执行摘要
- 一句话:为Qwen3.5 MTP新增spec-decode CI测试覆盖
- 推荐动作:建议合并。该 PR 针对测试矩阵的空白进行了精准补充,并且设计决策(阈值选择、兼容性跳过、视觉塔限制)都基于实测数据,具有一定参考价值。
功能与动机
PR body明确了动机:'Adds hybrid-model coverage to two spec-decode tests that today only cover dense and MLA targets'。混合模型架构与密集/MLA有显著不同,缺乏覆盖导致已有bug(#38556)无法被早期检测。Qwen3.5是官方自带MTP权重的模型,适合用于填补这一空白。
实现拆解
- 在 test_spec_decode.py 的 test_mtp_correctness 参数化列表中添加 ("mtp", "Qwen/Qwen3.5-0.8B-Base", 1) 案例,设置 GSM8k 阈值 0.20;增加 Model Runner V2 不兼容跳过;通过 limit_mm_per_prompt 限制视觉塔初始化 OOM。
- 在 test_async_spec_decode.py 的 SPEC_DECODE_CONFIGS 中添加 self-draft 的 MTP 案例(mtp-qwen3_5-hybrid),同样限制视觉塔预热。
- 在 spec_decode.yaml 中添加可选 B200 阶段 'Spec Decode MTP hybrid (B200)',依赖 qwen3_5.py 和 qwen3_5_mtp.py 模型文件,通过 -k qwen3_5-hybrid 筛选测试。
关键文件:
tests/v1/e2e/spec_decode/test_spec_decode.py(模块 推测解码;类别 test;类型 test-coverage;符号 test_mtp_correctness): 核心测试文件:添加了 Qwen3.5 混合模型的 MTP 正确性测试案例,包括 GSM8k 阈值设置和兼容性跳过逻辑。
tests/v1/e2e/spec_decode/test_async_spec_decode.py(模块 推测解码;类别 test;类型 test-coverage;符号 test_no_sync_with_spec_decode): 异步无同步测试:添加了 Qwen3.5 MTP 案例,测试在混合模型下不会出现隐式 GPU-CPU 同步。
.buildkite/test_areas/spec_decode.yaml(模块 CI配置;类别 config;类型 configuration): CI 配置:新增专门的 B200 通道用于运行 Qwen3.5 MTP 测试,明确定义源文件依赖。
关键符号:test_mtp_correctness, test_no_sync_with_spec_decode
关键源码片段
tests/v1/e2e/spec_decode/test_spec_decode.py
核心测试文件:添加了 Qwen3.5 混合模型的 MTP 正确性测试案例,包括 GSM8k 阈值设置和兼容性跳过逻辑。
# 在 test_mtp_correctness 的参数化列表中新增 Qwen3.5 案例
@pytest.mark.parametrize(
["model_setup", "mm_enabled", "expected_accuracy_threshold"],
[
(("mtp", "XiaomiMiMo/MiMo-7B-Base", 1), False, 0.5),
(("mtp", "ZixiQi/DeepSeek-V3-4layers-MTP-FP8", 1), False, 0.0),
# 新增混合模型案例:Qwen3.5-0.8B-Base (Mamba GDN + Attention)
(
("mtp", "Qwen/Qwen3.5-0.8B-Base", 1),
False,
0.20, # 参考 GSM8k 精度 ~0.348,留约 14pt 余量
),
],
ids=["mimo", "deepseek", "qwen3_5-hybrid"],
)
def test_mtp_correctness(...):
...
# 跳过 Model Runner V2 不兼容情况
if "Qwen3.5" in model_name and os.environ.get("VLLM_USE_V2_MODEL_RUNNER"):
pytest.skip("Model Runner V2 does not yet support hybrid models")
# 限制视觉多模态输入以防止 ViT 预热 OOM
extra_kwargs: dict[str, Any] = {}
if "Qwen3.5" in model_name:
extra_kwargs["limit_mm_per_prompt"] = {"image": 0, "video": 0}
# 构建参考 LLM 和 spec LLM 时传递 extra_kwargs
ref_llm = LLM(model=model_name, ..., **extra_kwargs)
...
spec_llm = LLM(model=model_name, speculative_config={...}, ..., **extra_kwargs)
评论区精华
评审者 benchislett 要求 GSM8k 阈值不能为零,必须基于实测设定合理值。作者参考测量后将阈值从 0.0 调整为 0.20。gemini-code-assist[bot] 建议在新 CI 通道的 source_file_dependencies 中加入具体模型实现文件,作者已采纳并提交补丁。
- GSM8k正确性阈值应基于实测设定 (correctness): 阈值从0.0调整为0.20(使用Base模型后),留出约14pt margin,与MiMo案例一致的做法。
- 新CI通道应包含模型源文件依赖 (design): 作者在后续提交中添加了这两个文件依赖。
风险与影响
- 风险:主要风险来自新测试可能因未来 Qwen3.5 模型变更或 B200 驱动变化而失败,但测试为可选通道,不影响主 CI。另外,limit_mm_per_prompt 的 hack 假设视觉塔不需要,若后续测试需要多模态则失效。Model Runner V2 的跳过需跟踪上游修复。
- 影响:此 PR 全部是测试和 CI 配置变更,不涉及生产代码。对用户无直接影响。对 CI 系统,新增了一个可选的 B200 通道,在拥有该硬件的环境中可自动检测回归。对团队,提高了混合模型 spec-decode 的测试覆盖率,降低了未来修改导致错误的风险。
- 风险标记:硬件依赖B200, ViT内存限制hack, Model Runner V2兼容性跳过
关联脉络
- PR #38556 stale num_accepted_tokens_cpu corrupting hybrid hidden state under async spec decode: PR body 说明此PR新增的正确性测试本可捕获该bug。
- PR #39546 B200 CI lane support for MTP hybrid: PR body 说明 B200 通道依赖此 PR,合入前需等待。
参与讨论