055 · Agentic Batch Inference
CONCUR:用拥塞控制避免 Agent KV cache 中段抖动
CONCUR 控制什么:它把活跃 agent 数当作 TCP congestion window,根据 KV cache 使用率和命中率执行 AIMD 式 admission control。长生命周期 agent 的总 working set 因此受到约束,避免 LRU eviction、重算和 offload 在执行中段拖垮吞吐。
本文目录 · 18 节
- 1. Agent workload 为什么不同于普通聊天
- 2. Baseline 为什么都不够
- 3. 系统位置与四步循环
- 4. Cache-aware AIMD
- 5. 完整例子:三个 agent、只能稳定容纳两个
- 6. 实验设置
- 7. Cache 证据与消融
- 8. 贡献、适用范围与相关工作
- 9. 前置知识:KV cache、prefix tree 与块驱逐
- 10. 中段抖动的三阶段因果链
- 11. 为什么控制单位必须是 agent
- 12. AIMD 控制律逐变量解释
- 13. 控制器端到端伪代码
- 14. 逐表解释端到端结果
- 15. 命中率表证明了什么、没有证明什么
- 16. 固定窗口与阈值敏感性
- 17. 局限、在线服务与组合方法
- 18. 复现清单与结论边界
1. Agent workload 为什么不同于普通聊天
ReAct agent 在“LLM 推理→工具调用→把观察追加到上下文”之间循环几十甚至上百步。每个 agent 的 context 与 KV footprint 单调增长,但它在等工具时暂时不发请求。SGLang 等 serving engine 按 request 做 batching 和 LRU:暂停 agent 的 KV 因为“不新近”而被活跃 agent 挤掉;工具返回后,系统必须重做越来越长的 prefill 或从 CPU 搬回。
这不是最后内存耗尽才发生。大批 agent 的执行呈 warmup、middle、cooldown 三段:warmup context 短且共享前缀多,hit rate 约 90%;middle 占总时间 90% 以上,cache usage 长期 80%–100%,但 hit rate 崩溃,系统反复 eviction/recomputation;少量 agent 完成后进入 cooldown。DeepSeek-V3 trace 中额外重算占端到端延迟 49.1%,已经超过原始 prefill 的 6.1% 和 decode 的 27.1%。作者称它 middle-phase thrashing。
Figure 1 还把“上下文增长”与“缓存增长”并排画出:DeepSeek-V3 和 Qwen3-32B 的输入在十个 agent step 中持续增长,KV 占用也随之单调上升。对 DeepSeek-V3,一个四千零九十六 token 请求的缓存约六点六七吉字节;并发从一提高到八时,CPU 与 GPU 间搬运缓存和重新做 prefill 都会增长。区别在于重算消耗模型算力,搬运争用主机链路,两种补救都只是为此前驱逐付账。真正应控制的是让仍会恢复的 agent working set 不进入持续互相驱逐区,而不是等驱逐发生后选择较便宜的补偿方式。
论文的“middle”不是按固定轮数切分,而是由运行状态定义:缓存使用持续处于约八成到满载,同时命中率由早期高位坠落并长期不恢复。暖机阶段增加 agent 可提高 batch 利用;冷却阶段已完成 agent 释放整条长前缀,压力自然下降;只有中段同时具备长上下文、异步工具等待和大量未完成 agent。因而采样几轮短轨迹、只测首次生成,根本观测不到该病理,也会错误地把最大瞬时并发当成最高端到端吞吐。
2. Baseline 为什么都不够
SGLang LRU 只看 request recency,不认识一个 agent 跨多轮的状态连续性。固定 request-level cap 限制的是瞬时请求数;agent 等工具时不在 flight,恢复后仍造成 working-set 冲击。HiCache/CPU offload 能维持很高 hit rate,但高并发下 PCIe offload/reload 互相争带宽,命中不等于低延迟。固定 agent cap 也脆弱:安全值会随 context 增长改变,过小浪费早期 GPU,过大在中期抖动。
因此控制点必须从 eviction 之后移到 admission 之前,控制单位必须是长生命周期 agent,而不是单次 generation request。
3. 系统位置与四步循环
CONCUR 是 agent framework 与现有 LLM serving engine 之间的轻量 controller,不改模型和 SGLang 的 token generation/KV manager。
- Agent 要生成时先向 controller 请求 admission;未获准的 agent 在框架层暂停,保留逻辑状态但不把新请求压进 engine。
- 已 admit agent 进入正常 continuous batching,KV 随 context 增长。
- Agent 调工具时暂时不生成,但仍属于受保护的 active working set;controller 不因它当前无 request 就随意补进大量新 agent。
- controller 周期读取 KV usage U_t 与 hit rate H_t,更新允许活跃的 agent window W_t,pause/resume/admit。
4. Cache-aware AIMD
映射关系很直接:W_t 是 congestion window;cache eviction 类似 packet loss;重新 prefill 类似 retransmission;有限 KV capacity 类似共享链路。控制律为:
W_(t+1) =
W_t + α, if U_t < U_low
W_t * β, if U_t > U_high and H_t < H_thresh
W_t, otherwise
论文固定:α=2, β=0.5,
U_low=0.2, U_high=0.5, H_thresh=0.2
低利用率时只线性加 2,避免一次涌入许多长 context agent。高利用率本身不立刻减窗;只有命中也低,说明进入真实 thrashing,才乘 0.5 快速退出。中间区间保持,U_low 与 U_high 之间的 buffer 吸收 agent admission 引起的离散内存跳变。重算随序列长度近似有凸代价,乘性下降能在 O(log N) 次调整内离开高成本区。
逐变量说,W_t 是第 t 次控制更新允许活跃的 agent 上限,不是当前 request batch;U_t 是服务引擎报告的 GPU KV cache 使用比例;H_t 是同一观测窗口内的缓存命中率;α 是低压力下每次增加的 agent 数;β 是确认抖动后保留的窗口比例。U_low 以下表示显存利用不足,U_high 以上只是压力候选,必须再满足 H_t<H_thresh 才判定 thrashing。若使用率高但命中也高,缓存中存的是正在复用的有价值状态,减窗反而浪费吞吐。
乘性下降针对的是重算的凸惩罚。前缀长度为 L 时,重新 prefill 的 attention 计算随 L 具有二次成分;窗口过大造成的多次相互驱逐会把长前缀重复计算。假设窗口六十四且触发拥塞,β 为零点五时依次降到三十二、十六,只需两次更新便缩为四分之一;若也用每次减二的线性退让,则要二十四次才到十六,期间仍持续付重算成本。相反,恢复用 α 等于二的加性探测,避免一次恢复几十个长 agent 又立刻越界。
5. 完整例子:三个 agent、只能稳定容纳两个
A1、A2 已被 admit,A3 pending。A1 和 A2 生成一轮后同时调用工具。普通 LRU 看它们暂时不活跃,会让 A3 的新 KV 占满 pool,逐出 A1/A2 的长前缀;两者恢复时又逐出 A3 并重算,形成相互污染。
CONCUR 仍把 A1/A2 计入 agent window,不在工具暂停时立即 admit A3。若 U 低于 0.2,window 才从 2 增到 4;若中段 U 超过 0.5 且 H 低于 0.2,window 从 4 乘 0.5 回到 2,暂停超出的 agent。A2 完整结束、释放 KV 后,A3 才进入。这里“暂停”发生在 agent 发下一次 LLM request 之前,所以不需要把一个正在 decode 的 request 粗暴抢占。
把例子扩成两个控制周期:起始 W=4,四个 agent 活跃,监控得到 U=0.65、H=0.15,两个条件同时成立,下一窗口为 floor(4×0.5)=2。控制器不会终止两个超额 agent,也不会清空其工具环境,只阻止它们发下一轮生成;已经在引擎内 decode 的请求跑完。下一周期若两个保留 agent 的长前缀稳定命中,得到 U=0.45、H=0.82,它既不低于零点二,也没有同时满足高压低命中,窗口保持二。等一个 agent 完整结束、释放缓存后,若利用率降到零点一八,窗口加二回到四,再按 pending 队列恢复。
这个状态机说明“保护暂停 agent 的缓存”并不是给每个 agent 做永久显存保留。CONCUR 仍使用引擎原有 LRU;它通过减少新 agent 进入,降低仍有价值前缀被逐出的概率。被暂停 agent 的 KV 若已经被逐出,恢复仍需重算或搬运,控制器不会创造缓存容量。它优化的是未来工作集压力和重复驱逐频率,兼容性正来自不修改 token generation 与 KV manager。
6. 实验设置
对比原生 SGLang、固定 request control、SGLang+HiCache。硬件是 H100 80GB,节点内 900 GB/s NVLink,节点间 8×400 Gbps RoCE;PyTorch 2.7.1、Python 3.12、CUDA 12.6。模型覆盖 Qwen3-32B 与 DeepSeek-V3,通过 batch size、TP 和 GPU 数改变有效并发。指标用完成整个 offline agent batch 的总秒数,工作量相同,所以延迟越低即吞吐越高。
| 配置 | SGLang | Request control | HiCache | CONCUR |
|---|---|---|---|---|
| Qwen3-32B, 256/TP8/8GPU | 1480s | 2049s | 976s | 362s,4.09× |
| Qwen3-32B, 256/TP2/2GPU | 2527s | 1383s | 1112s | 846s,2.99× |
| DeepSeek-V3, 40/TP16/16GPU | 3877s | 2903s | 2320s | 2043s,1.90× |
Qwen3-32B 的最大提升 4.09×,DeepSeek-V3 最大 1.90×。request control 在某些设置甚至比原生更慢,证明限制瞬时请求数没有稳定控制 agent working set;HiCache 在 DeepSeek 小 batch 下也可能因传输开销显著变慢。
公平性边界是四套系统使用完全相同的模型权重、prompt 与 rollout workload,比较的是完成同一离线 agent batch 的总时间。Qwen3-32B 始终是 batch 二百五十六,通过张量并行八、四、二及对应八、四、二张 GPU 改变每卡有效并发;DeepSeek-V3 固定张量并行十六和十六张 GPU,把 batch 从十六增到三十二、四十。机内九百吉字节每秒 NVLink 与跨节点八条四百吉比特每秒 RoCE 是结果成立的互联背景;HiCache 对主机链路敏感,不能把论文秒数直接外推到不同 PCIe、NUMA 或网络拓扑。
7. Cache 证据与消融
DeepSeek-V3、TP=8、8 GPU 的 hit-rate 表中,batch 40 时 SGLang 只剩 35.41%,request control 32.21%,CONCUR 73.36%;HiCache 达 96.08%,但端到端仍慢于 CONCUR,直接说明“最高 hit rate”不是目标,关键是避免重算又不引入过量 PCIe。
固定 agent cap 30/32/64/128 的实验显示,小 cap 会在 warmup/cooldown 闲置资源,大 cap 在 middle 过载。自适应方案在相应 Qwen 配置达到 846 ms,较最佳固定值提升约 1.5–2.9×。阈值敏感性中,固定 U_low=0.2 时 U_high 从 0.5 调到 0.6,仅让 TP8/4/2 延迟增加 24/18/99 ms;升到 0.8 则慢 4–5×,因为减窗太迟。U_high=0.4 又因过早收缩导致 46%–64% 更高延迟。U_low 更敏感,决定系统何时重新探测容量。
8. 贡献、适用范围与相关工作
方法贡献:论文识别出 agent serving 的三阶段 working-set 病理,并把控制状态提升到 agent 生命周期。AIMD 本身已有成熟用途;这里增加 U 与 H 两个反馈信号,用来区分“cache 使用率高但仍健康”和“使用率高且正在 thrash”。
局限:主要面向 offline batch,在线服务还要同时约束单用户 latency、公平和优先级。暂停 agent 会延迟工具链,不能用于有硬 deadline 的交互任务而不加额外 policy。U/H 是滞后聚合信号,突发长 prompt 仍可能越界;不同 engine 是否暴露同样准确的 hit rate 也不确定。固定 α、β 跨论文实验有效,不保证所有 cache block size、量化或 offload 拓扑都最优。
合集关系:CONCUR 与 KV-cache compression 论文目标不同:后者减少每 token 占用,CONCUR 控制同时存活多少个 agent;两者可组合。与 SchedMate 都是控制层,但 SchedMate解释训练代码与日志,CONCUR只用 serving runtime 信号。与 PromptTuner 的 admission/热池相比,CONCUR 不扩 GPU,而是避免已有 GPU 的 cache 进入崩溃区。
9. 前置知识:KV cache、prefix tree 与块驱逐
Transformer 自回归解码时,每层为历史 token 保存 key/value,下一 token 不必重算整个前缀。现代引擎把显存切成固定大小 block,用 radix tree 或 prefix tree 让共享 prompt 的请求引用同一前缀。新请求先匹配树路径,命中部分直接复用,未命中部分做 prefill 并分配新 block。显存不足时,LRU 选择最近最少使用的节点驱逐。
普通聊天请求短、到达后连续生成,最近使用近似未来还会使用。Agent 却在每轮生成后调用浏览器、代码或环境,等待期间 KV 节点长时间没有访问;LRU 把“暂时等待工具”误认为“以后不再需要”。恢复时历史可能已有数万 token,重做 prefill 远比早期昂贵。多个 agent 异步暂停与恢复,会交替把彼此前缀逐出。
CPU offload 把被逐 KV 搬到主存,恢复时通过 PCIe 传回,避免算力重算但不免费。高并发下大量异步传输争用链路,还要同步 GPU block 分配。HiCache 命中率可以很高,端到端仍可能慢;论文因此同时使用 cache usage、hit rate 和 batch latency,不把命中率当最终目标。
10. 中段抖动的三阶段因果链
Warmup 时所有 agent 只有浅层轨迹,系统 prompt、任务模板高度共享,单 agent footprint 小。增加并发能填满计算 batch,cache 命中接近九成,吞吐随并发上升。若只跑短 benchmark,会错误得出“并发越高越好”。
进入 middle 后,每个 agent 追加独特思考、工具输出和观察,prefix sharing 下降,footprint 单调增长。工具等待让 recency 与未来价值脱钩;usage 长期接近八成到满载,LRU 不断逐出仍会恢复的前缀。恢复触发重算,新算出的 KV 又逐出别人,形成正反馈。论文 trace 中此阶段占总执行时间九成以上,额外重算占端到端四十九点一百分比。
Cooldown 时一部分 agent 完整结束,释放长前缀,working set 降到显存可容纳范围,命中率恢复。这个阶段说明问题不是永久容量不足,而是活跃 agent 集合在生命周期中段同时达到峰值。静态按最坏情况限制会浪费 warmup/cooldown,静态按早期容量限制又会在 middle 崩溃。
11. 为什么控制单位必须是 agent
Request-level cap 只统计当前送进模型的生成请求。Agent 等工具时没有 in-flight request,cap 立即出现空位并接纳新 agent;旧 agent 恢复时,系统已经积累更多长生命周期状态。即使任一时刻生成 request 数不大,跨轮保留的 KV working set 仍可远超显存。
Agent-level controller 从首次 admit 到完整结束持续为 agent 保留窗口名额。工具调用只是 agent 内部状态变化,不释放逻辑名额;只有完成、失败或被控制器显式暂停到非活跃集合才改变。控制器因而能估计“未来还会恢复的上下文”总量,而不是只看瞬时 batch。
暂停也在 agent 边界执行:未获准 agent 不发下一次 LLM generation,工具和历史状态保留在执行框架;正在模型中 decode 的请求不被中途抢占。这样无需修改 SGLang 内核,只在 agent framework 与 engine 之间拦截请求。论文称其轻量控制层,兼容现有 LRU 管理。
12. AIMD 控制律逐变量解释
W_(t+1) = W_t + alpha
当 U_t < U_low
W_(t+1) = W_t * beta
当 U_t > U_high 且 H_t < H_thresh
否则 W_(t+1) = W_t
W 是允许同时活跃的 agent 数;U 是 GPU KV block 使用比例;H 是近期 cache hit rate。低 usage 表明还有容量,窗口加 alpha 做线性探测。高 usage 并不必然有问题:若命中仍健康,现有状态有价值且未反复驱逐,所以保持。只有 usage 高且 hit 低,才确认进入 congestion,窗口乘 beta 快速下降。
论文固定 alpha 为二、beta 为零点五,低高利用阈值为零点二与零点五,命中阈值零点二。加性增长避免一次接纳大量长 context 造成离散跳变;乘性缩减让窗口在对数次数内离开抖动区。U_low 到 U_high 的间隔是滞回缓冲,减少阈值附近来回暂停恢复。
缓存重算代价随前缀长度增长,attention prefill 对长度有超线性成分,所以拥塞后的惩罚比网络丢一个包更重。AIMD 在这里不是证明全局最优,而是稳定、低状态、可反馈的启发式。它不需要预知每个 agent 最终长度或工具时间,这比静态容量模型更适合异步轨迹。
13. 控制器端到端伪代码
active, pending = set(), queue()
W = initial_window
agent 请求生成:
若 agent 已在 active:直接转发给 engine
否则放入 pending
周期控制:
U, H = engine.cache_metrics()
若 U < U_low:W = W + alpha
否则若 U > U_high 且 H < H_thresh:W = floor(W * beta)
若 active 数 > W:
将超额 agent 标为暂停,不再发下一轮 generation
若 active 数 < W:
从 pending 恢复或接纳,直到 W
agent 完整结束:
从 active 删除,释放 KV,接纳 pending
指标应按固定控制周期平滑。单个 request 的瞬时 miss 不能代表 middle thrashing;过长窗口又响应太慢。论文用引擎运行时 cache signal,而不是从每个 agent 精确预测 footprint。实现还需决定暂停选择,例如队列次序或可安全停在工具边界;论文核心是窗口大小,复杂公平策略可叠加。
14. 逐表解释端到端结果
Qwen 三十二亿批量二百五十六、张量并行八、八张卡时,原生 SGLang 一千四百八十秒,请求控制二千零四十九秒,HiCache 九百七十六秒,CONCUR 三百六十二秒,相对原生四点零九倍。Request cap 更慢说明限制瞬时请求破坏 batch,却没有保护跨轮状态。
同批量把张量并行降到四卡或两卡,有效每卡并发升高。CONCUR 分别七百五十七与八百四十六秒,相对原生二点九二与二点九九倍。HiCache 在两卡为一千一百一十二秒,虽然避免部分重算,传输仍不及主动减少 working set。
DeepSeek-V3 十六卡下,batch 十六时 CONCUR 五百二十一秒、相对八百七十三秒一点六八倍;batch 三十二时一千零一十八秒、只一点二倍;batch 四十时原生三千八百七十七秒,CONCUR 二千零四十三秒、一点九倍。增益随并发不是单调,因为模型、工具等待和 cache 压力共同决定窗口。
完整六行还能看出 baseline 没有统一赢家。Qwen 张量并行四时,SGLang、请求控制、HiCache、CONCUR 分别二千二百一十三、一千零八十九、一千六百七十八、七百五十七秒;请求控制相对原生有二点零三倍,却仍比 CONCUR 慢。DeepSeek batch 十六时,HiCache 二千五百五十九秒,只有原生的零点三四倍;batch 三十二时二千二百七十七秒,只有零点五四倍。高命中如果依赖频繁主机搬运,在较小批次也可能比直接重算更糟。
DeepSeek batch 三十二是 CONCUR 相对原生增益最低的一行:原生一千二百二十六秒,请求控制一千三百六十七秒,HiCache 二千二百七十七秒,CONCUR 一千零一十八秒。它提醒读者,中等压力下原生 LRU 尚未完全崩溃,自适应准入的空间有限;到了 batch 四十,原生延迟跃升到三千八百七十七秒,而 CONCUR 只升到二千零四十三秒,才显出避免拥塞坍塌的价值。论文证明的是跨所有配置最低延迟,而不是每个点都有四倍收益。
15. 命中率表证明了什么、没有证明什么
DeepSeek-V3 的 batch 十六时,原生命中八十点三八,HiCache 九十七点四八,请求控制六十九,CONCUR 九十六点三八;batch 四十时原生跌到三十五点四一,请求控制三十二点二一,CONCUR仍有七十三点三六。它直接支持 agent-level admission 减少 middle eviction。
HiCache 在 batch 四十仍有九十六点零八,比 CONCUR 高,但端到端二千三百二十秒慢于二千零四十三秒。命中可能来自 CPU 层,传输和同步成本没有出现在 hit ratio。一个系统也可通过极度限制并发获得高命中,却让 GPU 计算空闲。因此必须联合看 hit、usage、总延迟与有效窗口。
论文时间曲线还显示 baseline 在 usage 接近八成时 hit 急跌,CONCUR维持更高 hit;这比整段平均更能定位 middle。复现应按时间对齐 agent 完成数,否则 cooldown 的高命中会把 middle 低值平均掉。
三行命中率应逐行对照:batch 十六时原生、HiCache、请求控制、CONCUR 为百分之八十点三八、九十七点四八、六十九、九十六点三八;batch 三十二为七十七点七二、九十七点一三、六十八点三九、九十三点六五;batch 四十为三十五点四一、九十六点零八、三十二点二一、七十三点三六。CONCUR 随压力也下降,并非消灭所有 miss,但从 batch 三十二到四十只降二十点二九个百分点,原生则降四十二点三一,请求控制降三十六点一八。
Figure 5 以 Qwen batch 二百五十六、张量并行二、两张卡画时间序列。Baseline 在缓存使用逼近约八成后命中快速下降;CONCUR 通过窗口调节维持较高命中,且不要求把使用率始终压到低位。复现时应同时采样窗口 W、使用率 U、GPU 层命中、CPU 层命中、重算 token 数和完成 agent 数。只有命中率而没有命中层级,会把需要 PCIe 回载的 HiCache 命中与可直接在 GPU 复用的命中混在一起。
16. 固定窗口与阈值敏感性
固定三十、三十二、六十四、一百二十八个 agent 的比较说明不存在通用 cap。小窗口避免重算但 warmup 计算不足,大窗口早期快、中段过载。自适应方案对应配置达到八百四十六毫秒,较最佳固定设置约一点五到二点九倍,并相对无控制二点九九倍。
固定 U_low 零点二时,U_high 零点五到零点六较稳,TP 八、四、二只增加二十四、十八、九十九毫秒;升到零点八慢四到五倍,因为系统容忍过高 pressure;降到零点四又提前收缩,延迟高百分之四十六到六十四。阈值不是越保守越好。
U_low 决定何时重新加窗,更敏感。设零点一时 usage 很难降到它以下,窗口缩后不再恢复;设得过高则频繁接纳。部署应先固定安全 U_high,再按 workload 调 U_low,并记录窗口轨迹而非只调最终延迟。
附录表给出全部阈值秒数。固定 U_low=0.2 时,U_high=0.4/0.5/0.6/0.8 在 TP8 下为五百二十九、三百六十二、三百八十六、一千八百九十八毫秒;TP4 为一千零八十九、七百五十七、七百七十五、二千三百;TP2 为一千三百九十、八百四十六、九百四十五、二千四百九十八。零点五到零点六是宽容区,零点四过早减窗,零点八则等抖动严重后才动作。
固定 U_high=0.5 时,U_low=0.1/0.2/0.3/0.5 的 TP8 延迟为二千八百九十四、三百六十二、七百七十九、二千七百六十三毫秒;TP4 为二千五百六十一、七百五十七、一千五百六十六、二千二百四十五;TP2 为九百七十二、八百四十六、一千零八、一千四百五十一。过低时窗口缩小后难以重新探测,过高时不断加窗。默认二者都不是从单一 TP 配置过拟合,而是在三种并行度上同时取得最低值。
17. 局限、在线服务与组合方法
论文主要是 offline agent batch,目标是完成整批最快。在线交互还要限制单 agent 等待、租户公平和优先级;乘性缩窗可能让低优先 agent 长时间暂停。需要在窗口内加入 deadline、age 或份额,而不能直接使用离线队列。
聚合 U/H 是滞后信号。一次超长工具输出恢复会瞬间分配大量 KV,在下一控制周期前越过容量;可加入单请求长度准入或预测增量。不同引擎对 hit 的定义也不同,CPU 命中、GPU 命中和 prefix 部分命中必须分开校准。
CONCUR 不压缩单 token KV,也不改变 attention。它可与量化、KV compression、prefix-aware placement、HiCache 组合;压缩后容量扩大,阈值和窗口要重调。若 offload 链路很快,最优策略可能允许更大窗口。论文参数跨两模型固定有效,是鲁棒证据,不是所有硬件最优保证。
18. 复现清单与结论边界
复现需固定模型权重、agent prompt、工具环境、随机种子和轨迹终止,确保四系统做相同工作。记录每个 agent 的轮次、context 长度、工具等待、KV block、prefill、decode、offload、重算和完成时刻;硬件使用 H100 八十吉字节、机内高速互联和给定 RoCE 栈。
正确性先检查 controller 不把一次 agent 的后续轮当新 agent;工具等待不释放名额;完整结束才释放;暂停不丢环境状态。然后复现三阶段 usage/hit 曲线、延迟分解、表一总秒数、表二命中率、固定窗口与阈值表。参数敏感性应一次只改一个阈值。
CONCUR 观察到,Agent 批推理会在显存耗尽之前遇到瓶颈:异步长生命周期状态使 LRU 在中段反复逐出仍有价值的 KV。准入控制提升到 agent 生命周期后,usage 与 hit 两个反馈信号共同调节窗口,无需修改 serving engine 便可减少吞吐崩溃。系统适度限制并发以换取更少重算,优化的是有效吞吐,不是瞬时 batch 的最大值。
控制器实现还要记录每个 agent 的唯一标识和生命周期状态:待接纳、活跃、工具等待、暂停、已完成。工具等待仍占活跃窗口名额,暂停只在 generation 与 tool 的边界生效,已进入 decode 的请求不能中途撤回;完整完成才从 active 集合删除并释放名额。窗口乘零点五后若活跃数超过新上限,需要有确定的暂停选择规则;论文核心没有规定公平算法,因此复现可用稳定队列,但必须固定并报告,否则不同选择会改变缓存局部性和尾部等待。
端到端报告应包含六行 Table 1、三行 Table 2、固定三十/三十二/六十四/一百二十八窗口对照和八组阈值表,并提供三阶段时间线。预热结束前、批次完成后的时间不应被截掉,因为自适应方案的价值正是跨 warmup、middle、cooldown 调整。还应分解工具百分之十七点七、decode 百分之二十七点一、原始 prefill 百分之六点一和额外重算百分之四十九点一,验证速度提升来自重算减少,而不是工具环境或答案长度变化。
工作负载复现不能把普通多轮聊天伪装成 agent batch。论文面向三类长期并发流程:大量 agent 生成合成轨迹供模型训练或搜索;教师 agent 产生轨迹后用于学生模型监督微调;评测系统同时模拟并裁判数千种场景。共同条件是每个实体在多轮“生成、工具、观察”中持续追加历史,工具等待时间又彼此不同。若所有请求一次生成即结束,或每轮都主动清空上下文,agent 级名额与 request 级名额近似等价,不能验证 CONCUR 识别的抽象差异。
每个 rollout 还必须固定终止条件和工具返回。若某系统因暂停次序不同导致答案提前终止、工具超时或少执行步骤,较短总延迟可能只是少做工作。应逐 agent 比较轮数、输入 token 总量、输出 token 总量、工具调用数与最终状态,并在四个系统间确认一致;随机采样则固定种子或重复多轮报告方差。离线吞吐可用完成固定 batch 的总时间计算,不能用某一时刻的 decode token/s 替代,因为中段重算 token 也会被引擎计作忙碌,却没有推进任何 agent。
监控侧要把缓存事件拆成首次 prefill、有效 prefix hit、GPU 驱逐、CPU offload、CPU reload 与重算。一次恢复可能先在 prefix tree 命中公共系统提示,再重算独有工具历史;只用二元 hit 会掩盖部分命中长度。比较 HiCache 时尤其应报告 GPU 命中和主存命中,以及传输字节和链路等待。论文 Table 2 的高命中而较慢现象说明缓存层级决定命中的代价,复现不能把所有命中视为零成本。
AIMD 的观测窗口也必须与控制动作对齐。每次记录更新前的 W、U、H、触发分支和更新后的 W,再标记本周期新增、暂停、恢复、完成的 agent。若利用率指标包含模型权重或非 KV 显存,它就不能直接与零点二、零点五阈值比较;必须使用引擎 KV block pool 的占用比例。命中率分母应是可查询缓存的前缀 token 或 block,且跨 SGLang 与 HiCache 保持同一定义。否则双信号控制律代码相同,实际控制对象却不同。
边界失败要单独压测。若一个 agent 一次返回极长工具观察,它下一轮 prefill 可在控制器再次采样前造成瞬时压力;聚合反馈无法提前知道该增量。若工具服务长时间挂起,等待 agent 仍占窗口名额,批次可能低利用;若释放名额又会重新引入 LRU 连续性问题。论文选择保护长生命周期状态以优化离线总吞吐,没有给工具超时、优先级或租户配额政策。生产系统应在其上叠加最大暂停时间、每 agent KV 预算和公平队列,并把这些扩展与论文默认策略分开评测。
最终验收不只看 CONCUR 是否最快,还要复现因果链:高并发 baseline 的缓存使用接近饱和、命中在中段下降、重算占比上升、总延迟恶化;启用 agent 窗口后,活跃 working set 被限制,中段命中恢复,重算下降,完成相同轨迹更快。若延迟下降但重算没有变,收益可能来自不同 batching;若命中提高但延迟上升,则可能重现 HiCache 的搬运问题;若窗口长期停在很小值,可能只是静态限流。三条中间证据使四点零九倍与一点九零倍不再是无法解释的端到端数字。
从六组延迟还可检查扩展性。Qwen 固定二百五十六个 agent,把张量并行和 GPU 数从八降到四、二后,单副本算力下降而每卡状态压力上升;CONCUR 延迟从三百六十二增到七百五十七、八百四十六秒,仍保持二点九倍以上相对原生提升。DeepSeek 固定十六卡,batch 从十六增到四十时延迟从五百二十一到二千零四十三秒,说明控制器不能消除工作量增长,但能避免原生从八百七十三骤升到三千八百七十七秒的更严重坍塌。结果应解释为稳定退化,而不是无限线性扩展。
部署前最后要做窗口轨迹审计:在 warmup 中 W 应随低使用率逐步增加,在 middle 出现高使用低命中时乘性下降,在 cooldown 资源释放后再次探测。若 warmup 从不增,通常是 U 指标口径包含非缓存显存;若 middle 只保持不减,可能 H 统计包含 CPU 命中而虚高;若 cooldown 不恢复,U_low 太低或完成 agent 没有正确释放。AIMD 的可解释性就在每个动作都有明确触发条件,利用这份轨迹可比只看最终秒数更快定位实现偏差。
还应检查控制开销本身不进入关键路径:agent 只在发起下一轮生成前查询准入,运行时信号从现有引擎读取,暂停与恢复只改变框架队列状态。若每个 token 都同步查询控制器,或为每个等待 agent 复制完整上下文,轻量中间件会变成新瓶颈。压力测试需同时给出控制请求吞吐、决策延迟和队列长度,并确认模型引擎在相同窗口下的 batch 组成未因额外锁竞争而改变。