![[Bug]: `--reasoning-parser gemma4` silently disables structured output (xgrammar) when `enable_thinking=false`](https://www.chat-gpts.plus/wp-content/uploads/2026/06/39130-0cfbe746.jpg)
[Bug]: `–reasoning-parser gemma4` silently disables structured output (xgrammar) when `enable_thinking=false`
快速结论:当使用 --reasoning-parser gemma4 并设置 enable_thinking=false 时,结构化输出后端(xgrammar/llguidance)会被完全绕过,语法约束不再生效。优先排查是否使用了 Gemma 4 E4B 等小模型(其 chat template 不会自动插入空 Reasoning 块),或改用 reasoning_effort: "none" 参数。
问题场景
用户在使用 vLLM 启动 Gemma 4 系列模型(如 google/gemma-4-E4B-it、google/gemma-4-26B-A4B-it、google/gemma-4-31B-it)时,同时指定了:
--reasoning-parser gemma4--enable-auto-tool-choice--default-chat-template-kwargs '{"enable_thinking": false}'--structured-outputs-config '{"backend":"xgrammar"}'
结果发现 JSON Schema、BNF 等结构化输出约束被完全忽略,模型返回不受限制的自由文本。在 vLLM v0.19.0 及更早期版本中均可复现。
报错原文
# 无明显错误日志,但结构化输出不再生效。
# 可以通过性能差异间接发现:相同模型下,启用 parser 后 TPS 显著高于未启用 parser 的情况。
# 例如 E4B FP8 单卡数据,max_parallel=16:
# with parser: TPS = 65.4, TTFT = 0.302s
# without parser: TPS = 14.6, TTFT = 0.532s
# 说明 xgrammar 的 bitmask 计算和 FSM 推进被静默跳过了。
原因分析
根因在 vllm/v1/structured_output/__init__.py 中 should_fill_bitmask() 和 should_advance() 与 reasoning parser 的交互逻辑。
- 触发条件:当
enable_thinking=false时,输入 prompt 中不包含<|channel>(start token 100)或<channel|>(end token 101)任意一个 Thinking 标记。 - 判定失效:
Gemma4ReasoningParser.is_reasoning_end()在未找到任何标记时返回False,即认为“推理尚未结束”。 - 决策链:结构化输出引擎检查
reasoning_ended = False→ 跳过 bitmask 填充和 FSM 推进 → 整个请求不再受语法约束。 - 影响范围:xgrammar 和 llguidance 两个后端均受影响。
- 模型差异:Gemma 4 的 26B/31B 等大模型的 chat template 会在
enable_thinking=false时自动插入空 Thinking 块,因此问题不明显。但 E4B(以及 E2B)等小模型不会插入空块,因此问题暴露。
环境排查
- vLLM 版本:v0.19.0(CI 环境为
vllm/vllm-openai:v0.19.0-x86_64-cu130-ubuntu2404) - GPU:NVIDIA RTX PRO 6000 Blackwell Server Edition(SM 12.0)
- OS:Linux 5.15.0-171-generic
- CUDA:13.0
- Python:3.12
- 模型:
google/gemma-4-E4B-it(FP8 量化),其它 Gemma 4 变体同理 - 结构化输出后端:xgrammar(也可选 llguidance)
- 注意:使用
--speculative-config时可能引入独立 bug(参见 #34650)
解决步骤
- 方案一(推荐,当前已知可用):不通过
chat_template_kwargs禁用 Thinking,而是改用reasoning_effortAPI 参数。
extra_body.update({"reasoning_effort": "none"})
此方案会触发正确的 Reasoning 状态判断,结构化输出得以生效。 - 方案二(适用于 E4B / E2B 小模型):在 Chat Template 层面修改,确保 prompt 中包含空 Thinking 标记。例如可以在调用时通过
chat_template_kwargs注入"enable_thinking": false的同时,手动在模板中添加<|channel>thought\n<channel|>前缀。但该方案需要自定义 Template 或模型配置,不是 vLLM 原生行为。 - 方案三(vLLM 0.22.0+ 验证):如果启用 Thinking(
enable_thinking: True),结构化输出在推理结束后仍无法正确约束最终输出。有用户反馈将--structured-outputs-config分别设为xgrammar或guidance均无法解决。社区认为该问题在 #45588 修复中可能已被解决(需进一步验证)。 - 备注:对于启用 Speculative Decoding 时出现的结构化输出失效,可能关联 #34650,建议分开提报。
验证方法
- 使用
curl或客户端发送结构化输出请求(如response_format: { type: "json_object" }),检查返回的内容是否严格遵循 JSON 格式(例如 content 字段是否为合法 JSON)。 - 对比设置
--reasoning-parser前后的 TPS(吞吐量)和 TTFT(首 Token 延迟)。如果启用 parser 后 TPS 异常升高(如从 14.6 飙升到 65.4),说明结构化输出被绕过。 - 检查 vLLM 日志中是否出现 “xgrammar” 相关的 backend 应用记录。
- 使用
reasoning_effort="none"后,再次执行相同的结构化输出请求,确认 JSON Schema 被正确校验。

![[Question]: Failed to build knowledge graph](https://www.chat-gpts.plus/wp-content/uploads/2026/06/6886-32ff5dfd-768x403.jpg)

