Instructions to use froggeric/Qwen-Fixed-Chat-Templates with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use froggeric/Qwen-Fixed-Chat-Templates with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir Qwen-Fixed-Chat-Templates froggeric/Qwen-Fixed-Chat-Templates
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
[Bug] Template-controlled thinking toggles break non-streaming vLLM response parsing
Summary
With v22.1, thinking can be disabled internally by the template without updating the state used by vLLM's Qwen3 reasoning parser.
This affects:
- Inline
<|think_off|> auto_disable_thinking_with_tools=truechat_template_kwargs.reasoning_effort="none"
For non-streaming requests, a normal final answer may be returned entirely as reasoning, with content=null. If include_reasoning=false, the answer can effectively disappear.
Tested revisions
- Qwen-Fixed-Chat-Templates:
2b50d8ef73e9ba606680856aaeb46ab94702e788 - Template version:
qwen3.8-froggeric-v22.1 - vLLM:
311b3513af33bc29b4acb2fde2e9313e5e9966a0 - Model:
Qwen/Qwen3.8-27B-FP8
Reproduction
Start vLLM with the custom template and Qwen3 reasoning parser:
vllm serve Qwen/Qwen3.8-27B-FP8 \
--chat-template /path/to/chat_template.jinja \
--reasoning-parser qwen3
Send a non-streaming request:
{
"model": "Qwen/Qwen3.8-27B-FP8",
"messages": [
{
"role": "user",
"content": "Answer in one short sentence. <|think_off|>"
}
],
"stream": false
}
The template resolves ns_state.thinking to false and prefills:
<think>
</think>
The generated completion therefore contains only the final answer, without a generated </think> marker.
Expected behavior
{
"message": {
"reasoning": null,
"content": "The final answer."
}
}
Actual behavior
The Qwen3 parser may treat the complete answer as reasoning:
{
"message": {
"reasoning": "The final answer.",
"content": null
}
}
With include_reasoning=false, the reasoning field is removed and the response may appear empty.
The reverse mismatch is also possible: when enable_thinking=false is passed explicitly but a historical inline tag re-enables thinking, vLLM starts in CONTENT state and reasoning can leak into content.
Root cause
The template changes its private state here:
- Inline controls:
chat_template.jinja:35-80 - Automatic tool toggle:
chat_template.jinja:32-34 reasoning_effort="none":chat_template.jinja:18-23
However, vLLM's Qwen3 parser only reads the original chat_template_kwargs.enable_thinking value:
The non-streaming serving path passes only output.text to the parser, so it cannot see the empty <think></think> block that was inserted into the prompt:
Top-level vLLM reasoning_effort="none" is safe because vLLM also derives enable_thinking=false. Placing "none" only inside chat_template_kwargs does not provide that synchronization.
Suggested resolution
Because a Jinja template cannot update the parser's request state after rendering, possible resolutions include:
- Document that inline thinking toggles and
auto_disable_thinking_with_toolsare incompatible with--reasoning-parser qwen3. - Require callers to pass an explicit
enable_thinkingvalue matching the final template state. - Avoid allowing historical inline tags to override the request-level
enable_thinkingsetting. - Add vLLM integration tests covering both streaming and non-streaming requests.
The tests should verify at least:
enable_thinking=false- Inline
<|think_off|> chat_template_kwargs.reasoning_effort="none"auto_disable_thinking_with_tools=trueenable_thinking=falsecombined with a historical<|think_on|>
The current 34 tests validate rendered string fragments, but they do not perform a render-to-vLLM-parser round trip.
Generated by GPT-5.6-Sol
Thank you, that is a super cool and useful report. I will look into it.
Any news on this?
Here is what I have found out: in vLLM, when --reasoning-parser qwen3 is enabled alongside server-side thinking extraction, prefilling <think>\n\n</think>\n\n from the template can occasionally clash with vLLM's internal token parser if enable_thinking states are mismatched between client requests and server config.
In v22.2, the template cleanly handles thinking toggles:
If you want thinking active, pass --reasoning-parser qwen3 on the server and use the default template settings.
If you want fast non-reasoning mode, you can pass "enable_thinking": false in chat_template_kwargs or include <|think_off|> in the prompt without triggering the fatal exceptions present in the official template.
For tool calling on vLLM, make sure you launch with --tool-call-parser qwen3_xml to match Qwen's native XML tool format.
Give v22.2 a go and let me know if everything works.