[Bug]: Structured-output scheduler can keep advancing a terminated xgrammar matcher

该报错发生在 vLLM V1 引擎使用 XGrammar 结构化输出后端,且启用 MTP 推测解码时。其根本原因是 Python 侧的终止标志刷新晚于 C++ 侧 matcher 的实际终止状态,导致已终止的 matcher 仍被传入后续 draft token。优先排查是否启用了推测解码,并检查

快速结论:该报错发生在 vLLM V1 引擎使用 XGrammar 结构化输出后端,且启用 MTP 推测解码时。其根本原因是 Python 侧的终止标志刷新晚于 C++ 侧 matcher 的实际终止状态,导致已终止的 matcher 仍被传入后续 draft token。优先排查是否启用了推测解码,并检查 XGrammar 后端版本是否包含终止检查修复。

适用环境:vLLM 0.26.0(V1 引擎、单节点)、Ubuntu 22.04、Python 3.12.9、PyTorch 2.10.0+cu128、CUDA 12.8、NVIDIA RTX 4090 双卡、NVIDIA 驱动 570.86.10。

最快修复方案:暂无确认的一步修复方案。但可优先尝试将 vLLM 升级到包含 PR #52805 修复的版本,该 PR 在 XgrammarGrammar.accept_tokens() 的 token 循环内增加了 matcher.is_terminated() 检查,在传递剩余 draft token 前跳出循环。

注意事项:Issue 评论指出在 0.26.0 上该问题表现为日志噪声而非请求失败,因为 structured_output/__init__.py 已有前置防护。但若调用路径绕过了该防护,则可能引发真实请求失败。若无法立即升级,需关注日志频率与请求失败率是否上升。

问题场景

该问题在 vLLM V1 引擎下,启用 MTP 推测解码和 XGrammar 结构化输出后端时触发。用户使用 Qwen3.6-35B-A3B 模型,配置了 --speculative-config '{"method":"mtp","num_speculative_tokens":3}',同时启用 --enable-auto-tool-choice --tool-call-parser qwen3_xml --reasoning-parser qwen3、前缀缓存和最大模型长度 262144。在普通 tool-calling 请求下即可复现,无需特殊 schema。

报错原文

ERROR [backend_xgrammar.py:162] Failed to advance FSM for request
      chatcmpl-b674593843c941f9-b8e17400 for tokens 271. Please file an issue.
[grammar_matcher.cc:612] Warning: The matcher has terminated after accepting
      the stop token, but is trying to accept new token with id 198.

核心报错名为:[Bug]: Structured-output scheduler can keep advancing a terminated xgrammar matcher

原因分析

可能原因如下:

1. Python 侧终止标志更新滞后XgrammarGrammar.accept_tokens() 方法在遍历完所有 tokens 后才刷新 self._is_terminated 标志。在推测解码场景下,方法接收一批 draft tokens;当 stop token 在位置 i 被接受后,位置 i+1 的 token 仍会被传给 C++ 侧已视为终止的 matcher,从而触发警告并返回 False。

2. 推测解码放大触发窗口:MTP 推测解码一次性传递多个 draft token,使上述竞态窗口显著增大,相比逐 token 解码更容易触发该问题。

3. 调度器侧与后端侧存在双重不同步:Issue 评论指出调度器侧的问题讨论见 #42853,而 XGrammar 后端在 accept_tokens 内也存在类似的终止状态不同步问题。

环境排查

  • 确认 vLLM 版本是否为 0.26.0 或包含 PR #37506/#52805 修复的版本。
  • 确认是否启用了 MTP 推测解码(--speculative-config),可尝试关闭后观察问题是否消失。
  • 确认使用的结构化输出后端是否为默认的 XGrammar(需检查日志中 backend_xgrammar.py 相关输出)。
  • 检查 Python 3.12、PyTorch 2.10.0+cu128、CUDA 12.8 与 vLLM 的兼容性,排除环境差异导致的行为偏移。
  • 确认日志中出现该错误的频次是否与推测解码 token 数量(如 3)相关。

解决步骤

  1. 可优先尝试升级 vLLM 至包含 PR #52805 修复的版本。该 PR 在 accept_tokens() 的循环内增加终止检查,确保已终止的 matcher 不会继续接收批内后续 token。
  2. 参考 Issue 中提到的 PR #37506,检查其是否包含针对 accept_tokens 的同类修复,并评估是否适用于当前版本。
  3. 若无法立即升级,可尝试关闭 MTP 推测解码(移除 --speculative-config 参数或设置为 {"method":null}),观察错误是否消失。
  4. 在日志中观察错误出现的规律,确认是否伴随 Unexpected: grammar rejected tokens 或请求被标记为 FINISHED_ERROR。若仅出现日志警告而无请求失败,可暂时容忍噪声并等待修复版本。
  5. 若调用路径绕过了 structured_output/__init__.py 中的防护逻辑(即 advance_grammar and not grammar.is_terminated() 守卫),则需要更紧迫地应用修复,否则可能遭遇真实请求失败。

验证方法

升级修复版本后,在相同的 MTP 推测解码和结构化输出配置下运行 tool-calling 请求,观察 backend_xgrammar.py:162 的 ERROR 日志是否消失。建议持续运行数小时(如 6 小时)以覆盖高频触发场景。同时监控 grammar_matcher.cc:612 的 Warning 是否不再出现,以及是否存在请求被标记为 FINISHED_ERROR。若关闭推测解码后问题消失,可确认该场景与推测解码的 token 批处理直接相关。

参考来源

vllm-project/vllm #42619

相关 PR:#37506#52805(修复方案来源)

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 19182

发表回复

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