Mastodon
跳过正文
  1. Posts/

每日阅读

·1407 字·3 分钟·
reading - 这篇文章属于一个选集。
§ : 本文

阿里云开发者
#

mp.weixin.qq.com
原文链接
RTP-LLM 在相关性大模型中的推理优化最佳实践

场景
#

淘宝的业务场景是搜索相关性判别,即用户搜一个Query,系统判断Items是否相关,筛选出该Query下最相关的商品。这种场景的特征是:

  • 超大规模Point-wise计算:针对每一个Query请求,相关性模型需要对多个(Query, Item)对进行相关性判断,计算量随候选集大小线性增长。
  • 超长Context的Prompt处理:为了让大模型准确理解商品细节,我们需要将 Query 和包含丰富商品属性、描述信息的 Item 拼接成一个很长的 Prompt 输入给模型,长度带来的是O(N2)计算量增长。
  • 极度严苛的RT要求:搜索端到端的延迟要控制在1秒内,抛出Query理解、召回和客户端传输解析环节,留给相关性模型的空间也就在500ms左右。

架构优化方案
#

  1. 精细化Proxy拆批与动态负载均衡
    • 基于计算量的均匀拆分:不同于简单的固定Batch Size拆分方式,使用基于Query/Item Token预估长度动态组合,确保每个批次的预估计算量基本一致,避免因任务倾斜导致的某个Batch计算过慢。
    • 自定义动态调度策略:引入专用的Proxy服务,该服务会实时维护每个下游机器的活跃请求数和上一次请求的完成状态。当新的大请求到达时,Proxy会基于实时负载信息,采用加权轮询或最小连接数等策略,优先将拆分后的小Batch发送给当前最空闲的可服务机器,从而实现整体RT达到全局最优。
    • Proxy重构:把Proxy从python重构为Go,因为Python在高并发场景下有性能瓶颈和GIL及GC 机制,经常出现剧烈毛刺,严重影响服务的稳定性。
  2. 部署策略选择的是单卡张量并行,因为在这个场景下(Batch Size较小且模型是MoE架构),TP会带来较大的跨卡通信开销。
  3. 批次内前缀复用
    • 批次内KV-Cache复用:这个是根据特定场景的优化,同一个Query会与多个不同的Item进行组合。实现的核心思路是引入一种投机式的Block分配与注册机制。具体来说:
      1. 调度阶段的预注册:在Scheduler对批次内请求进行调度时,顺次为请求分配Block ID。对于第一个请求,在分配完Block后,尽管此时Block内尚未填充真正的KV值,立即将其公共前缀Token与Block的映射关系注册到Cache Manager中。
      2. 批次内复用:当调度该批次内的后续请求时,调度器会查询Cache Manager,发现公共前缀已存在映射关系,从而直接复用已分配的Block ID,无需重新分配。
      3. Lazy Filling:在真正执行推理的Attention计算阶段,引擎会先行计算当前Token的KV值并将其更新填充到对应的Block中;随后,再从这些刚刚完成更新的Block中读取KV数据进行最终的Attention计算。GPU 单Stream内Kernel严格的顺序执行保证,可以保证结果的正确性。
    • Cache可见性隔离:当一个批次正在推理时,其预注册的Block被标记当前批次的Epoch,该Block仅对同一批次内的其他请求可见,对全局其他批次的请求不可见。只有当该批次推理成功完成,这些Block的状态才会被更新为全局可见,完成“提交”。反之,如果请求调度失败,系统会触发回滚操作,自动清理未提交的Cache映射并释放Block资源。如果推理中途失败,该Cache映射会一直处于不被命中状态会被CacheManager释出。
  4. MoE kernel动态调优
tinuvile
作者
tinuvile
一个笨小孩
reading - 这篇文章属于一个选集。
§ : 本文