← 全部 AgentX 优化

AgentX 行业影响 · 推理引擎

SGLang

我们与来自 RadixArk、Meta、NVIDIA 和 AMD 的 SGLang maintainer 合作,在 AgentX 计划推动下完成了一批面向智能体负载的优化,这些改动同样显著提升了生产环境的推理服务表现。

并发 384 下的输出吞吐量提升
+26.75%
同一改动带来的平均 TTFT 下降
−36.25%
staging 修复后正确命中的 needle 数(此前为 2/128)
128/128

Sliding-window 分配

SGLang 的 sliding-window 工作处理的冲突与 vLLM 的保留策略相同,只是从分配器一侧入手。window 页与 prefix 页取自同一个池,而 window 是更贪婪的消费者:它不断翻新,prefix 却长期不动,于是在压力下这种临时分配会挤掉本应长期保留的部分。

三种设计从不同角度解决该问题。其一,在页面离开 window 时就主动释放,而不是等淘汰压力来找它们,让失效的 window 状态不再争抢它已经用不上的页面。其二,把 compute lock 限制在单个 window 内,从而限定一个在途请求最多能钉住多少池空间。其三,清除已失去价值的陈旧 full-KV 条目。

与之并列的 ROCm ring-cache 修复属于正确性而非容量问题:ring buffer 的设计本身就会复用槽位,而复用一个旧内容仍被引用的槽位,得到的是错误输出而不是变慢的输出。这些问题在单个 8k prompt 上完全看不出来——window 永远不会绕过 prefix,池也不会有竞争;但在多轮 hybrid 会话中,它们决定了昂贵的 full-attention 历史在下一轮是否还在。

HiCache offload

HiCache 是 SGLang 内置的一流 offload 机制。它面对的 hybrid 问题与 vLLM connector 相同,但解法是一种不对称设计:offload full-attention cache,而在回载时重建较短的 sliding-window 尾部。只有昂贵的那一半值得跨总线搬运,便宜的一半重建比取回更快。在 AMD 上,分阶段写回让这种搬运不会阻塞引擎。

剩下的缺口是 recurrent 状态——它无法像 window 尾部那样由相邻 token 重建。FlashInfer 的 GDN checkpoint 让它得以参与 prefix 复用,在 92.4% cache 命中率下把吞吐量从 47,771 提升到 53,004 tok/s/GPU。

示意图展示三类状态从 GPU HBM 到 CPU DRAM 的处理方式:full-attention KV 按字节 offload,sliding-window 尾部不搬运、在加载时重建,recurrent 状态则做 checkpoint。
HiCache 的不对称设计。full-attention KV 体积大且无法重建,因此跨总线搬运;window 尾部重建成本低,所以留在原地;recurrent 状态虽小却无法重建,因此以 checkpoint 形式保存。查看原始分辨率图片

长度多变的流量对内核流水线意味着什么

与生产流量一样,AgentX 会话的上下文长度连续变化。如果运行时天真地按长度做特化,几乎每来一个请求就要编译一个新内核。SGLang maintainer 的解决办法是把上下文长度作为 runtime scalar 传入,从而收敛为一次编译:AgentX 并发 384 下输出吞吐量提升 26.75%,平均 TTFT 降低 36.25%——收益来自消除编译,而不是把计算做得更快。

同理,移除每步一次的 device-to-host 序列长度同步,也消除了一个 decode 气泡;这个气泡的唯一成因,就是 host 想知道一个设备端早已掌握的长度。

Cache 感知的数据并行路由

当请求不带任何可复用历史(例如某个 subagent 刚启动)时,发给哪个 worker 都行,唯一值得考虑的就是负载均衡;但当它带着上兆字节的已缓存 prefix 时,把它发给一个并不持有该 prefix 的空闲 worker 就是昂贵选择,router 必须知道状态究竟在哪里。

SGLang 加入了 DP cache affinity,让会话粘在持有其 cache 的 rank 上。同一批工作还实现了 DP 感知的 prefill 与 decode 路由,使 disaggregated 部署的两侧做出一致决策,并把 cache 均衡作为路由信号,避免亲和性退化成单个热点 worker。router 只能依据它被告知的信息行动,因此 hybrid cache 事件也变得 radix cache 感知与 sliding-window 感知。

Speculative decoding

Speculative decoding 需要特别关注,因为 MTP 会引入第二份、体量更小的每请求状态,而它必须与主 cache 一样在各种情况下存活。SGLang 修复了 disaggregated 部署中的 draft window 传输,使该状态完整跨越 prefill 到 decode 的边界;为高并发在线 decode 增加了 overlap 调度;移除了一处无实际作用的 EAGLE 重归一化;并避免了 EAGLE prefill 期间的 host 同步。

仍为 open 的 resource-lease 调度工作与数据并行 graph metadata 修复延续同一方向:当请求可能被撤回并恢复、而不是一路跑完时,让 overlap 依然安全。

异构 disaggregation 下的 prefix 感知 staging

异构的 prefill 与 decode 拓扑需要 prefix 感知的 staging,而这正是 prefix caching 与 disaggregation 相互冲突之处。当两侧分片方式不同时,KV 无法作为一条连续流拷贝过去,必须按传输网格切分,并在 decode 侧期望的偏移处重新拼装。prefix 命中会让这件事更难而不是更容易,因为 prefill worker 此时只发送未命中的剩余部分,decode 侧却仍然期望得到一份完整、位置正确的 cache。staging buffer 中的 radix cache 支持会按该网格切分已缓存的发送内容,并散布到正确的 decode 偏移上。

它修复的是一个正确性问题。一项 127,500 token 的共享 prefix 测试,从 128 根 needle 只答对 2 根变为 128 根全对,说明此前 cache 一直悄悄落在错误位置——而吞吐量基准测试只会把它记成一次又快又自信的错误回答。相应的 AgentX 对比还把单用户输出吞吐量中位数提高了 9.61%,而每 GPU 总吞吐量几乎不变。

同一条线上仍有 open 的工作:UMBP 中的多池 DeepSeek-V4 支持、经由 MoRI 承载的统一 KV HiSparse 状态,以及在 decode 未产生可见内容就终止时保留 prefill 侧持有的 token。HiSparse 相关工作应被理解为长上下文的容量与正确性使能,而不是高并发下的吞吐量收益——它目前还不是。

staging buffer 索引的前后对比:改动前未命中的剩余部分覆盖到 prefix 所在的错误行;改动后它被放到 decode 侧已持有 prefix 之后的正确偏移上。
改动前 staging 索引从 0 开始计数,忽略 decode 侧已经持有的内容,于是剩余部分覆盖了 prefix;采用 radix 感知 staging 后,已缓存的发送按传输网格切分,并散布到正确的 decode 偏移上。查看原始分辨率图片

其他项目