[Performance]: MTP first repeat misses prefix cache on a hybrid Mamba/GDN model

在混合 Mamba/GDN 模型(如 Qwen3.8-27B-FP8,含 3 个 Mamba KV-cache group + 1 个 FullAttention group, mamba_cache_mode="align" )上启用 MTP/EAGLE 投机解码时,相同 prompt 的第一次重

快速结论:在混合 Mamba/GDN 模型(如 Qwen3.8-27B-FP8,含 3 个 Mamba KV-cache group + 1 个 FullAttention group,mamba_cache_mode="align")上启用 MTP/EAGLE 投机解码时,相同 prompt 的第一次重复会完全 miss prefix cache 并整段重新 prefill,直到第二次重复才开始复用。优先排查 Mamba retention 边界与调度器 EAGLE 调整后的可复用边界是否一致。

适用环境:vLLM(Issue 中复现基线为未修改的 0.26.1rc1.dev1130+g2ec6f0d71);混合 Mamba/GDN 模型 Qwen3.8-27B-FP8;MTP 投机解码 num_speculative_tokens=2,TP=2;--kv-cache-dtype fp8--enable-prefix-caching。Issue 未提供操作系统、Python、CUDA、显卡型号信息。

最快修复方案:暂无确认的一步修复方案。Issue 中已完成的修复补丁(将 canonical retention boundary 移入 HybridKVCacheCoordinator,从 Dense 参考组派生并作为可选 cache_blocks(replay_boundary=...) 参数下传)尚未合入主干,仅推送到公开分支 Suppressor72:fix/mamba-retention-eagle-boundary,因项目 open-PR 限制暂未提 PR。

注意事项:Issue 正文提到的 --prefix-cache-retention-interval <block_size> 只是配置层面的规避手段(workaround),不是根因修复。Mamba manager 的 use_eagle 标志本身不是通用信号:Mamba lookup 并不会丢弃 block,unitary-Mamba coordinator 不应发生偏移,mixed/fine-grained 或 DCP 布局可能使用不同的 common-hit 单元,不要直接照搬该标志做判断。

问题场景

用户在 vLLM 上服务一个混合 Mamba/GDN 模型(Qwen3.8-27B-FP8,3 个 Mamba KV-cache 组 + 1 个 FullAttention 组,mamba_cache_mode="align"),并通过 --speculative-config '{"method":"mtp","num_speculative_tokens":2}' 启用 MTP 投机解码。请求被严格串行化发送:每个请求完整跑完(流读到结束、请求 finished 并释放)后间隔约 1 秒再发下一个,因此不存在 in-flight 重叠。

测试使用同一段约 12k token 的 chat prompt 连发三次(关闭 thinking),逐请求记录 TTFT 与 vllm:prefix_cache_* 计数器增量。结果出现“miss / miss / hit”的模式:第一次重复整段重新 prefill,第二次重复才命中。作为对照,不启用 speculative_config 时,第一次重复立刻命中。Issue 还提到在发布 benchmark 时也遇到同样的 cache hit 下降。

报错原文

[Performance]: MTP first repeat misses prefix cache on a hybrid Mamba/GDN model

原因分析

Issue 通过埋点定位到 retention-policy 边界不一致。单个冷启动请求的日志已足以复现:

# request 1 (cold)
SCHED  num_tokens=11910 use_eagle=True block_size=1600 last_cache_position=9600
MASK   use_eagle=True(ignored) retention=0 start_blk=0 end_blk=5 boundaries=[11909]
MASK   use_eagle=True(ignored) retention=0 start_blk=5 end_blk=6 boundaries=[11909]

# request 2 (identical prompt)
SCHED  num_tokens=11910 use_eagle=True block_size=1600 last_cache_position=9600
MASK   use_eagle=True(ignored) retention=0 start_blk=5 end_blk=6 boundaries=[11909, 9600]

按 mask 自身的算术,边界 11,909 对齐到 11,200 → block 6,落在包含 9,600 状态的 [5, 6) chunk 之外,因此在同一个 request 中,调度器算出 9,600 backoff、而 mask 什么都没保留。Request 2 的 boundaries=[11909, 9600] 说明响应式连接点(shared_prefix_boundary)晚了一个 request 才到达,这才让 request 3 能命中。也就是说:Mamba manager 计算 retention mask 时使用的边界,与调度器 EAGLE 调整后的可复用边界不一致,导致第一次重复时该保留的 block 处于“已物化但被 mask 掉”的状态。

环境排查

  • 确认 vLLM 版本;Issue 复现基线为 0.26.1rc1.dev1130+g2ec6f0d71,且埋点为仅日志改动。
  • 确认模型是否为混合 Mamba/GDN 架构(Issue 中为 Qwen3.8-27B-FP8,3 + 1 组)。
  • 确认是否启用了 MTP/EAGLE 投机解码(speculative_config),以及 num_speculative_tokens 取值。
  • 确认 --enable-prefix-caching--kv-cache-dtype fp8 是否开启。
  • 确认 block 单元:Issue 中提到 clean-main spec-on 启动自动解析为 1,600-token attention/Mamba block unit,而 nospec 对照自动解析为 1,568,两个启动的绝对 TTFT 不能当作同 block geometry 的 A/B 对比。
  • 注意 sleep mode 不是影响因素:production boot(sleep 模式)与无 sleep 的 spec-ON 启动呈现相同的 miss/miss/hit 形状。

解决步骤

  1. 先用串行请求复现并采集 vllm:prefix_cache_queries_totalvllm:prefix_cache_hits_total 增量,确认是否出现第一次重复 hit tokens = 0 的模式。
  2. MambaManager.reachable_block_mask 计算 mask 处,以及调度器计算 EAGLE 调整后 last_cache_position 处,加 debug-gated 日志,逐请求打印两者算出的边界。若单个冷启动请求中 mask 侧算出 11,200、而调度器侧为 9,600,即为单请求级别的直接复现,无需跑到第二、三次重复。
  3. 可优先尝试:使用 Issue 中提到的配置规避 --prefix-cache-retention-interval <block_size>,观察第一次重复是否开始命中。注意这是 workaround,Issue 未将其列为根因修复。
  4. 如需采用已完成的修复,参考公开分支 Suppressor72:fix/mamba-retention-eagle-boundary:该改动把 canonical retention boundary 移入 HybridKVCacheCoordinator,从 Dense reference group 派生(沿用 finder 的 eagle-margin 算术),并作为可选 cache_blocks(replay_boundary=...) 参数下传,其余位置保持未偏移的默认行为。
  5. 该补丁的回归测试覆盖:adjusted boundary 上的首次重复命中、nB-1/nB/nB+1 边界长度、使用参考组单元的 32/16 混合 block geometry;另有一条 guard 确保带 eagle 标志的 unitary Mamba 配置不会被偏移。
  6. 若使用该项目以外的自定义构建,不要仅凭 Mamba manager 的 use_eagle 标志做偏移判断,需确认本机的 common-hit 单元是否与调度器一致。

验证方法

在复现硬件上(Qwen3.8-27B-FP8 hybrid GDN,MTP K=2,TP=2)应用修复后,首次重复 TTFT 由 2.83 s 降至 0.61 s,其后每一次重复(包括间隔 10 s 空闲后的一次)也都保持在 0.61 s。对应地,vllm:prefix_cache_hits_total 应在第一次重复时就开始增长,而不是等到第二次重复。

参考来源

vllm-project/vllm #53504

相关修复分支:Suppressor72/vllm fix/mamba-retention-eagle-boundary

Issue 评论中提到的相关 PR:vllm-project/vllm #53388

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 22950

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注