[Bug]: ~7× MTP (K=3) decode-throughput regression on Qwen3.6-35B-A3B (GB10 / sm_121) in recent nightlies

用户在 DGX Spark (GB10, sm_121, aarch64) 上,使用 vLLM 0.23.x nightly 版本(如 commit a16dbd5b8 和 93d8f834d),对 `nvidia/Qwen3.6-35B-A3B-2.06GB-per-token` 模型进行单请求

[Bug]: ~7× MTP (K=3) decode-throughput regression on Qwen3.6-35B-A3B (GB10 / sm_121) in recent nightlies

[Bug]: ~7× MTP (K=3) decode-throughput regression on Qwen3.6-35B-A3B (GB10 / sm_121) in recent nightlies

快速结论:该 Bug 发生在 DGX Spark (GB10, sm_121) 上使用 vLLM 0.23.x nightly 版本运行 `nvidia/Qwen3.6-35B-A3B-2.06GB-per-token` 模型的 MTP (K=3) 解码场景。优先排查:确认是否使用了特定问题 checkpoint `nvidia/Qwen3.6-35B-A3B-2.06GB-per-token`,该 checkpoint 在 GitHub Issue 中无法获取和复现;同时检查生成是否被硬限制在 128 个 token。

问题场景

用户在 DGX Spark (GB10, sm_121, aarch64) 上,使用 vLLM 0.23.x nightly 版本(如 commit a16dbd5b8 和 93d8f834d),对 `nvidia/Qwen3.6-35B-A3B-2.06GB-per-token` 模型进行单请求 MTP (K=3) 解码时,观察到解码吞吐量出现约 7 倍的回退。同时,生成被硬限制在 128 个 output token,即使设置了 `ignore_eos` 和 `min_tokens` 也无效。

报错原文

# 核心性能回归表现:解码 ITL 从 ~10 ms 回退到 ~72 ms
# vLLM version comparison:
# 0.21.0+2325b6f0: 9.94 ms ITL, ~100 tok/s, output len ~997 ✅
# 0.22.1+7b9cb5b7: 9.95 ms ITL, ~100 tok/s, output len ~1002 ✅
# 0.23.1rc1.dev471 (e312c5cb2): 10.29 ms ITL, 97.2 tok/s, output len full ✅
# 0.23.1rc1.dev601 (a16dbd5b8): 71.9 ms ITL, 13.9 tok/s, output len 128 ❌
# 0.23.1rc1.dev672 (93d8f834d): 71.1 ms ITL, 14.1 tok/s, output len 128 ❌

原因分析

当前 Issue 讨论中,该问题在特定 checkpoint `nvidia/Qwen3.6-35B-A3B-2.06GB-per-token` 上被报告,但该 checkpoint 不可用,因此无法在其他环境(如 SM120/x86_64)上完全复现。已有证据指向以下可能原因:

  • 平台特定原因(最可能): 问题在 SM120/x86_64 上无法复现,因此很可能是 GB10 (sm_121) / aarch64 平台特有的问题,或者与 nightly-aarch64 镜像本身有关(例如 `CUTE_DSL_ARCH=sm_121a` 路径存在问题)。
  • 生成长度限制 Bug: 存在一个独立的生成配置正确性缺陷。`ModelConfig.get_diff_sampling_param()` 会过滤掉 `stop_token_ids`,导致其无法进入由 commit fca432e 引入的请求级别合并,从而可能引起过早停止。
  • 非性能回归: 有分析指出,报告的 ITL 增长(10.29 ms → 71.9 ms)实质上是由输出长度从约 1000 token 收缩到 128 token 导致的,而非绝对解码时间增加了七倍。使用公共 checkpoint 的受控测试未重现该性能回退。
  • 客户端测量偏差: 在 MTP 模式下,SSE chunk 会合并到达。如果客户端按 chunk 到达次数而非服务器报告的 token 数量来计算 ITL,可能会高估 ITL(大约为接受因子 K=3 倍)。

环境排查

  • 硬件: DGX Spark (GB10, sm_121 / cc 12.1),aarch64 架构
  • 软件版本: vLLM 0.23.1rc1.dev601 (a16dbd5b8) 及之后的 nightly 版本
  • 模型: `nvidia/Qwen3.6-35B-A3B-2.06GB-per-token`(不可用,问题疑似与此特定 variant 有关)
  • CUDA / PyTorch: CUDA 13.0.88, PyTorch 2.11.0+cu130
  • 环境变量: 检查 `VLLM_*` 和 `CUTE_DSL_ARCH` 等覆盖设置
  • 对比环境: 确认在 SM120/x86_64 上是否可复现(Issue 中该平台不可复现)
  • 客户端工具: 确认是否使用 aiperf;如果使用,注意其 ITL 计算方式可能与服务器端报告不一致

解决步骤

  1. (可优先尝试)切换模型 checkpoint: 使用公共可用的 checkpoint `nvidia/Qwen3.6-35B-A3B-NVFP4` 进行测试,确认问题是否仍然存在。如果问题消失,则可能是特定 checkpoint `nvidia/Qwen3.6-35B-A3B-2.06GB-per-token` 的问题。
  2. 降低 vLLM 版本: 回退到已知正常的版本,例如 vLLM 0.22.1 或 0.23.1rc1.dev471 (e312c5cb2),并确认问题是否消失。
  3. 使用服务器端 token 计数: 在客户端计算 ITL 时,使用服务器端返回的 `usage.completion_tokens` 而不是通过 SSE chunk 到达时间来估算。例如,ITL 计算公式为:(最后一个 chunk 时间戳 - 第一个 chunk 时间戳) / (completion_tokens - 1)
  4. 检查生成长度限制(如适用): 如果遇到 128 token 输出限制,可以关注 Issue 中提到的 `ModelConfig.get_diff_sampling_param()` 修补程序,或等待上游修复。作为临时工作区,可以尝试手动设置或覆盖 `stop_token_ids`。
  5. 禁用 MTP 进行基准测试: 禁用 MTP (K=0) 运行相同工作负载,记录 ITL 和吞吐量,与启用 MTP (K=3) 的结果进行比较,以隔离 MTP 路径上的问题。

验证方法

使用相同的请求参数(prompt、`max_tokens`、`ignore_eos`、`min_tokens`)运行受控测试:

  • 确认解码 ITL 是否恢复到 ~10 ms 范围。比较服务器端报告的 token 计数与客户端观察到的 token 数量。
  • 确认生成的 output token 数量是否符合预期(例如 1024 token),而不是被硬限制在 128 token。
  • 如果切换到公共 checkpoint,确保输出哈希值与正常版本一致。

参考来源

vllm-project/vllm #47297

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

celebrityanime
celebrityanime
文章: 14499

发表回复

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