![[Bug]: Minimax m3 reasoning parser sending in content field in streaming](https://www.chat-gpts.plus/wp-content/uploads/2026/06/45687-72007dad.jpg)
[Bug]: Minimax m3 reasoning parser sending in content field in streaming
快速结论:该报错发生在 vLLM 部署 MiniMax M3 模型并使用 --reasoning-parser minimax_m3 启用流式输出时。优先检查 streaming 模式下,<mm:think> 标签和推理内容是否被错误地放入 content 字段而非 reasoning 字段,原因是流式推理解析器依赖 token ID 匹配,而真实 tokenizer 中标签可能被编码为多个子 token。
问题场景
用户使用 vLLM(标签 minimax-m3)部署 MiniMax M3 模型,并同时启用 --tool-call-parser minimax_m3 和 --reasoning-parser minimax_m3。在非流式模式下,推理解析器正常工作;但在 streaming 模式下,<mm:think> 标签和推理内容被当作普通文本放入 content 字段,reasoning 字段始终为空。
报错原文
data: {"choices":[{"delta":{"content":""}}]}
data: {"choices":[{"delta":{"content":"Reasoning"}}]}
data: {"choices":[{"delta":{"content":" content"}}]}
data: {"choices":[{"delta":{"content":""}}]}
data: {"choices":[{"delta":{"content":"content"}}]}
Expected output:
data: {"choices":[{"delta":{"reasoning":"Reasoning"}}]}
data: {"choices":[{"delta":{"content":"content"}}]}
原因分析
核心原因在于 vllm/reasoning/minimax_m3_reasoning_parser.py 中的 extract_reasoning_streaming() 方法依赖 token ID 来识别 <mm:think> 和 </mm:think> 标记。然而,实际部署中该标签可能被 tokenizer 编码为多个子 token,导致 self.start_token_id 或 self.end_token_id 无法在 delta_token_ids 中匹配,从而使所有内容落入文本分支,标签和推理内容全部泄漏到 content 字段。
非流式路径 extract_reasoning() 直接操作原始字符串(使用 partition 等字符串方法),不受 tokenize 方式影响,因此工作正常。单元测试 tests/reasoning/test_minimax_m3_reasoning_parser.py 使用 mock tokenizer,其中标签被当作单一原子 token,导致测试未能捕获此问题。
环境排查
- 模型:MiniMaxAI/MiniMax-M3-MXFP8
- vLLM 版本/分支:
minimax-m3或 0.1.dev17492+g454b47db8(基于vllm/vllm-openai:minimax-m3镜像) - 启动参数:需确认是否同时设置了
--reasoning-parser minimax_m3 - API 调用:使用
stream: true调用/v1/chat/completions - tokenizer 行为:检查
<mm:think>经 tokenizer 编码后的 token ID 数量和值:tok.encode("<mm:think>", add_special_tokens=False)
解决步骤
-
临时方案 1:修改 chat template(不推荐)
修改chat_template.jinja中的标记定义:
{%- set think_begin_token = '<think>' -%}
{%- set think_end_token = '</think>' -%}
警告:此方法会改变模型的标记习惯,可能影响工具调用等其他功能。 -
临时方案 2:设置默认 chat template kwargs(可优先尝试)
在 vLLM 启动参数中添加:
--default-chat-template-kwargs '{"thinking_mode":"enabled"}'
验证效果后,streaming 模式下推理内容会出现在delta.reasoning,最终回答出现在delta.content,且<mm:think>不再泄漏。
注意:此方法强制对每个请求启用推理模式,会增加延迟和 token 消耗,且请求级的chat_template_kwargs可能覆盖服务器端默认值。 -
长期修复:等待官方 PR 合入
参考 PR #45713(后自动关闭,请追踪 PR #45718 进展)。该修复将让流式推理解析器也能基于文本标记(而非仅依赖 token ID)检测<mm:think>,从而与extract_reasoning()保持一致。如果读者有能力,可前往 PR 进行 review 或验证。
验证方法
执行一次带 stream: true 的聊天请求,检查 streaming 响应中:reasoning 字段是否包含推理内容,content 字段中是否不再出现 <mm:think> 或 </mm:think> 标签。对于非流式请求,确保 reasoning 字段仍然正确分离。



