Prhub

#47920 [Tests][Spec Decode] Add gemma4 MTP acceptance rates test

原始 PR 作者 TheEpicDolphin 合并时间 2026-07-28 07:15 文件变更 4 提交数 1 评论 2 代码增减 +120 / -48

执行摘要

新增 Gemma4 MTP 验收率测试并修复 3 个 bug

Gemma4 MTP 缺乏验收率测试,同时存在三个运行时错误:

1) #43957 引入的 embedding 维度相等性检查阻碍了 Gemma4 MTP 的启动;
2) seq_lens 在 _prepare_decode_inputs_kernel 中未考虑 num_rejected,导致接受率次优;
3) 概率拒绝采样时 Gumbel 采样位置未随 draft 步数更新。本 PR 旨在填补测试空白并修复这些正确性问题。

建议所有使用 Gemma4 MTP 的开发者 review 此 PR,特别是采样位置修复部分。测试框架的泛化设计值得学习,可复用于未来新增的推测模型。

讨论亮点

作者在 speculator.py 的 review 评论中说明了一个关键修复点:seq_len 应该无论是否推进 draft 位置都考虑 num_rejected,否则会导致 Gemma4 MTP 路径下 seq_lens 错误,进而影响接受率。该问题在 PR 中已修复。

实现拆解

  1. 泛化验收率测试框架:将原有的 dflash_config fixture 和 test_dflash_acceptance_rates 合并为参数化的 test_acceptance_rates,新增 spec_configexpected_acceptance_lengthschat_template_kwargs 三个参数,支持 DFlash 和 Gemma4 MTP 两种规格,并保留 MRV1/MRV2 双后端测试。
  2. 修复 Gemma4 MTP embedding 共享:在 vllm/v1/spec_decode/gemma4.py 中覆盖 _maybe_share_embeddings 方法,绕过基类的 embedding 维度相等性检查,直接使用目标模型的 embed_tokens 替换 draft 模型的 placeholder embedding。
  3. 修复 draft 解码 seq_lens 更新:在 vllm/v1/worker/gpu/spec_decode/autoregressive/speculator.py_prepare_decode_inputs_kernel 中,将 seq_len = target_seq_len - num_rejected 计算移出 ADVANCE_DRAFT_POSITIONS 条件块,确保无论是否推进位置,seq_lens 都正确反映被拒绝的 token 数。
  4. 修复 Gumbel 采样位置:在 _generate_draft 中,当 advance_draft_positions=False(Gemma4 MTP)时,计算 sample_positions = positions + current_draft_step 传递给采样函数,使得概率拒绝采样时 Gumbel 噪声在正确的绝对位置上生成。
  5. 配套 CI 配置:在 .buildkite/test_areas/spec_decode.yaml 中新增 nightly 测试步骤 Spec Decode Acceptance Rates Nightly,在 H200 上运行 test_acceptance_rates
文件 模块 状态 重要度
tests/v1/e2e/spec_decode/test_spec_decode.py 规范解码测试 modified 7.03
vllm/v1/spec_decode/gemma4.py Gemma4 MTP modified 7.17
vllm/v1/worker/gpu/spec_decode/autoregressive/speculator.py 推测核心 modified 6.66
.buildkite/test_areas/spec_decode.yaml CI 配置 modified 3.58

关键符号

test_acceptance_rates _maybe_share_embeddings _generate_draft _prepare_decode_inputs_kernel

关键源码片段

vllm/v1/worker/gpu/spec_decode/autoregressive/speculator.py core-logic

修复两个核心逻辑错误:seq_lens 更新未考虑 num_rejected、Gumbel 采样位置未偏移。

# In _generate_draft method of Speculator class:
# 之前:draft_tokens = self.sample_draft(..., positions, ...)
# 之后:
sample_positions = positions
if not self.advance_draft_positions:
    # 当 draft 位置不推进(如 Gemma4 MTP 的 constant_draft_positions),
    # 采样位置需要累加 current_draft_step 以生成正确的 Gumbel 噪声。
    sample_positions = positions + self.current_draft_stepdraft_tokens = self.sample_draft(
    last_hidden_states,
    sample_positions,
    idx_mapping,
    self.temperature,
    self.seeds,
    self.current_draft_step,
    self.draft_logits,
)

评论区精华

seq_len 应无条件考虑 num_rejected 正确性

作者在 speculator.py 的 review 评论中指出 'seq_len should account for num_rejected regardless of whether we are advancing draft positions or not.'

结论:已修复:将 seq_lens 计算移出 ADVANCE_DRAFT_POSITIONS 条件块。 · 已解决

风险与影响

  • 回归风险:参数化测试覆盖了原有 DFlash 场景,基线值不变,但测试运行时间较长可能影响 CI 稳定性。
  • 性能风险:Gumbel 采样位置修复对吞吐的影响在 benchmark 中 < 2%,接受率持平或微升,无负面性能风险。
  • 兼容性风险:仅影响 Gemma4 MTP 推理路径,对其它模型或推测解码方法无影响。
  • 安全性风险:无。
  • 用户:Gemma4 MTP 用户将获得正确的接受率,概率采样不会因采样位置错误而退化。
  • 系统:新增 nightly 测试步骤,约 30 分钟,仅 CI 影响,不改变运行时。
  • 开发团队:为 spec decode 提供了可靠的回归保障,尤其是 Gemma4 路径。
核心路径变更 Gemma4 特定修复 采样逻辑修正 seq_lens 修复

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论