快速结论:在 llama.cpp 的 LFM3 模型(LFM3-1.7B / LFM3-VL-2B)上启用 response_format(json_schema 或 json_object)时,服务端会因 grammar prefill 失败而返回 500。优先排查 response_format 与 LFM3 原生 chat template 的 prefill 组合,尤其是 enable_thinking 相关分支与 </think> 令牌重复处理。
适用环境:工具为 llama.cpp llama-server;模型为 LiquidAI/LFM3-1.7B GGUF(Q8_0),以及 LFM3-VL-2B(Q5_K_M + mmproj-Q8_0);后端为 CUDA 12;测试构建包括 b11946(release binary,master 8ca4060b)与 ghcr.io/ggml-org/llama.cpp:server-cuda12(构建时间 2026-10-28T13:35Z);启动参数涉及 --jinja --reasoning-budget 0 --flash-attn on -ngl -1 --ctx-size 32768。
最快修复方案:Issue 讨论中维护者定位到 llama.cpp 强制追加 </think>、而 chat template 已自行加入该令牌,并提交了修复 PR(ggml-org/llama.cpp#31374)。可在该 PR 合并并发布后升级到包含修复的构建;Issue 内未给出可直接执行的一步命令或确认后的正式版本号。
注意事项:Issue 中提到的临时绕过方式各有副作用:--chat-template chatml 虽能让 grammar 工作,但会丢失 LFM3 的思考抑制,回复中可能泄漏原始 Thinking... 内容;修改模板 else 分支只输出 <think> 会导致思考块未闭合,并触发 Failed to initialize samplers;--reasoning-format none 会使采样器初始化失败并让思考标记泄漏到纯文本输出。修复 PR 在 Issue 关闭时的验证状态请以 PR 讨论为准。
问题场景
用户通过 llama-server 的 OpenAI 兼容接口 /v1/chat/completions 调用 LFM3 架构模型(LiquidAI/LFM3-1.7B GGUF Q8_0,以及 LFM3-VL-2B Q5_K_M + mmproj-Q8_0),请求体中带有 response_format({"type":"json_schema", ...} 或 {"type":"json_object"})时,服务端返回 HTTP 500。去掉 response_format 的相同请求返回 200,且模型能自行输出合法 JSON。同一模型上的工具调用(grammar 约束的函数调用)正常,说明问题集中在 response_format 的 grammar 路径。
报错原文
got exception: Unexpected empty grammar stack after accepting piece: 6 (30)
HTTP 500
{"error":{"code":500,"message":"got exception: Unexpected empty grammar stack after accepting piece: 6 (30)","type":"server_error"}}
原因分析
根据 Issue 讨论,异常抛出点在 src/llama-grammar.cpp 的 llama_grammar_accept_str():当 grammar 的解析栈全部耗尽时被视为致命错误。该函数用于 prefill/强制前缀,而非普通采样,因此更可能是 chat template 的 prefill 内容包含 JSON grammar 无法接受的令牌,而不是采样随机性问题。
维护者最终定位为:llama.cpp 会强制追加 </think>,而 LFM3 的 chat template 已经自行加入了 <think></think>,导致 prefill 中该令牌重复出现,JSON grammar 无法接受,解析栈全部失效并抛出上述异常。用户侧观察到的触发条件为 chat_template_kwargs: {"enable_thinking": false} 与 response_format 同时出现;省略该参数或设为 true 时请求成功。Issue 中还提到纯文本响应下偶发多余 U+2026(…)令牌,可能与模板中的控制/思考令牌被 prefill 有关。另有相关 Issue #29006 报告同类 chat-template 控制令牌导致 JSON Schema grammar 失败的问题。
环境排查
- 确认使用的模型及量化:LFM3-1.7B Q8_0,或 LFM3-VL-2B Q5_K_M + mmproj-Q8_0。
- 确认 llama.cpp 构建版本/镜像标签;Issue 中 b11946 与 2026-10-28T13:35Z 的 server-cuda12 镜像均复现,说明不是单一构建回归。
- 确认启动参数是否包含
--jinja、--chat-template以及--reasoning-budget、--reasoning-format等与思考内容相关的选项。 - 确认请求是否显式传入
chat_template_kwargs: {"enable_thinking": false},或所用客户端是否默认关闭思考。 - 确认
response_format的类型(json_schema或json_object),两者在 Issue 中表现一致。 - 确认后端与 CUDA 版本(Issue 使用 CUDA 12),但未见证据表明问题与 CUDA 版本直接相关。
解决步骤
- 先做最小复现:使用 Issue 中的 curl 请求,分别测试带
response_format: {"type":"json_object"}与不带response_format的请求,确认 500 是否只出现在带 grammar 的请求上。 - 检查客户端是否传入了
chat_template_kwargs: {"enable_thinking": false};Issue 中省略该参数或设为 true 时请求成功,可作为临时规避手段(可优先尝试)。 - 若需要临时让
response_format可用,可用--chat-template chatml启动服务;Issue 中 4/4 成功。但注意该方式会导致 LFM3 思考抑制失效、原始Thinking...内容泄漏,不适合生产。 - 关注并升级到包含修复 PR ggml-org/llama.cpp#31374 的构建;该 PR 针对 llama.cpp 强制追加
</think>、与模板已加入的令牌重复的问题。 - 不要采用“把模板 else 分支改为只输出
<think>”或--reasoning-format none作为修复,Issue 中两者分别导致Failed to initialize samplers和采样器初始化失败/思考标记泄漏。
验证方法
使用同一模型、同一构建、同一 prompt 和同一 response_format 请求:在启用 enable_thinking: false 的情况下,修复前应为 HTTP 500 并返回 Unexpected empty grammar stack after accepting piece: 6 (30);应用修复后应返回 HTTP 200 和合法 JSON。同时可对照 enable_thinking: true 或省略该参数的成功请求,确认行为一致。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。

![[Bug]: Qwen3.6-35B-A3B (hybrid GDN + MoE): a prompt's logprobs move by up to 0.2 when another sequence shares its engine step (v0.30.0, sm_1](https://www.chat-gpts.plus/wp-content/uploads/2026/10/59764-7f760e85-768x403.jpg)
