智猩猩AI整理
编辑:BugMaker
大模型推理服务里,Prefix Cache明明已经算过一次,下一次请求却不一定能用上。
问题不一定出在缓存本身,而可能出在请求被送到了哪个模型服务节点。
对于客服Agent、多租户助手这类应用,同一业务往往会反复携带一段稳定的系统提示词、业务知识或历史上下文。如果后续请求再次落到保存这段Prefix KV Cache的服务器上,就能直接复用。但传统负载均衡会把请求分散到不同节点,缓存也跟着被“打散”。
反过来,如果为了缓存命中,强行把同类请求固定到一台服务器,又会把热门业务的流量全部压到同一个队列上。
缓存局部性和负载均衡,恰好在往两个方向拉。
来自Meta的Huang Cheng近日以单作者形式发布了论文CacheRoute,一种面向大规模LLM推理服务的Prefix Cache请求路由技术,让高频请求尽量回到已有缓存的服务节点,同时避免热点流量把少数服务器压爆。
![]()
在Llama-3.3-70B fp8、60张H100的主实验中,CacheRoute在p99≤3.5秒的SLO约束下达到176±11 QPS,是五个对比策略中最强Preble-style基线的2.3倍。
与此同时,实际服务KV Cache命中率从Flat-LB的64.1%提高到93.2%。
01
服务节点越多,Prefix Cache反而
可能越难命中
传统负载均衡关注的是一件事:
哪台服务器现在比较空,就把请求发到哪里。
但对于Prefix Cache,这种策略并不友好。
假设某个业务的请求被均匀分散到R个节点,那么随着节点数量增加,同一个业务再次回到某一节点的间隔也会越来越长。
一旦这段时间超过KV Cache的实际驻留时间,之前缓存好的Prefix就已经被淘汰,服务器只能重新执行Prefill。
所以一个有些反直觉的现象出现了:
集群扩大、总缓存容量增加,不代表单个Prefix更容易被复用。
固定亲和性也不行。
如果直接用一致性哈希,让某个业务持续访问固定的模型服务节点,缓存确实稳定了,但请求量最高的业务也会直接把流量压力带到对应节点。
这就是CacheRoute真正要解决的矛盾:
既要让高频Prefix尽可能回到已经有缓存的服务节点,又不能让流量热点跟着缓存热点一起固定下来。
02
不等请求来了再决定,而是
提前规划一张路由表
CacheRoute没有在每一次请求到来时临时计算“缓存和负载谁更重要”。
它把这个决策提前到了一个周期性离线路由规划器里。
整个流程可以拆成三步。
第一步是高频Key准入。
CacheRoute先根据历史流量估计每个业务Key的请求速率,把请求最频繁、最值得建立稳定缓存亲和性的Key优先放进“warm set”。
第二步是决定一个Key需要几个目的节点。
如果某个Key自身的请求速率已经超过单个节点能够承受的目标负载,就允许它使用多个目的节点,把热点拆开。
第三步才是关键的LPT负载放置。
规划器按照预计请求量,从高到低把这些Key分配给当前预计负载最小的节点,尽量让最终形成的缓存亲和关系本身就是均衡的。
规划完成后得到一张稳定路由表:
某个Key → 固定的一组目的服务器。
进入规划表的请求就在自己的固定服务器集合中选择当前负载最低者。没有进入warm set的长尾请求,则继续使用普通的power-of-two choices负载均衡。
![]()
这张表并不在请求路径上实时重算。
论文中128824个业务Key、30个目的节点的规划构建只用了345ms,在线阶段基本只剩一次查表和小范围负载比较。
还有一个容易误解的地方:
虽然CacheRoute支持把超热门Key复制到多个节点,但主实验70B场景中所有Key实际上都只分配了一个目的节点。
因此176 QPS这个核心结果,主要来自高频Key准入、稳定单副本亲和性以及更合理的LPT放置,并不是靠把热门Key分配到多个节点换来的。
03
命中率从64%到93%,但真正关键的
是队列没有被压歪
主实验使用Llama-3.3-70B fp8,在30个TP2目的节点、共60张H100 GPU上测试。
在p99≤3.5秒的SLO下:Flat-LB只有42±20 QPS,Preble-style达到76±11 QPS,CacheRoute达到176±11 QPS,相比最强基线达到2.3倍。
在固定100 QPS负载时,CacheRoute的p99 TTFT只有1.8秒,另外五个策略则处于3.8—8.5秒。
![]()
为什么差距会这么大?
消融实验把答案拆得很清楚。
为了进一步拆解提升来自哪里,作者又在 Llama-3.1-8B-Instruct bf16、30张单卡H100 上设计了一组受控的 synthetic-whale实验,也就是人为注入请求量特别高的“超级热门Key”。
只增加Affinity后,KV命中率从56%升到88%,但服务器间负载不均衡程度也从1.00×恶化到3.46×,最终容量仍然停在240 QPS。
也就是说:
缓存命中了,但热点服务器被堵住了,整体吞吐根本没有提高。
加入热点复制后,不均衡降低到2.60×,容量还是240 QPS。
直到再加入LPT放置,把不均衡压到1.24×,测试容量才从240 QPS提高到至少500 QPS。这里的500 QPS已经碰到论文设置的测试扫描上限,意味着真实容量可能还要更高,因此作者将其标记为右删失结果。
![]()
这组实验实际上说明了CacheRoute最核心的一点:
Prefix-Affinity只负责把重复计算省下来,Placement才负责让省下来的计算真正转化成集群容量。
04
Cache命中率更高,也可能
让系统跑得更差
这篇论文还有一个比较少见的地方:
作者专门把CacheRoute失败的场景也测了出来。
在一组32B工作负载中,Affinity让KV命中率从1.1%提高到11.8%,看上去确实变好了。
但这点缓存收益不足以抵消剩余的负载倾斜。在3.5秒和5秒SLO下,最终容量分别只有Flat-LB的0.50倍和0.67倍。
另一组32B负载中,命中率从0.8%提高到8.5%,在5秒SLO下最终也只是和Flat-LB打平。
![]()
所以论文没有给出一个简单规则:
“重复Prefix很多,就打开CacheRoute。”
相反,作者建议正式启用之前先做一次Shadow Replay。
让候选路由方案在不真正向用户返回结果的情况下跑一遍,同时测量KV命中率、各节点负载以及p99延迟。
只有p99或者实际容量真的改善,才启用新的Affinity计划。
因为缓存命中率本身,并不是最终目标。
对于大规模LLM Serving,真正要优化的是:
省下来的Prefill计算,最终有没有转化成更高的服务容量和更低的尾延迟。
CacheRoute比较有价值的地方,也正在这里。
它没有单独追求更高的Cache Hit,也没有退回纯粹的负载均衡,而是尝试提前规划两者之间的关系。
更重要的是,这篇论文把它什么时候有效、什么时候失效也一起给了出来。
Prefix-Affinity不是越强越好,只有当可回收的KV计算收益足以覆盖剩余负载倾斜时,这笔账才真正划算。
关注+星标,获取AI前沿进展与开源一线动态
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.