Qwen3 GGUF:トークナイザーとチャットの修正 template
GGUF Qwen3 におけるトークナイザーとチャットテンプレートのエラーは、三つの症状として現れます。思考タグが閉じられないこと、生成が止まらないこと、または的外れな回答です。原因はほぼ常に、チャットテンプレートの適用ミスです。GGUF に埋め込まれたテンプレートを使用するには --jinja を追加し、ファイルの出所を確認してください。最終手段として、カスタムテンプレートを使用してください。
Qwen3のGGUFが「でたらめな回答をする」場合、モデルの品質が原因であることはほとんどありません。問題は、プロンプトがモデルに渡される前の整形にあります。このガイドでは、Qwen3のGGUFにおけるトークナイザーとチャットテンプレートのエラーだけを扱います。症状を見分け、ファイルの出所を確認し、テンプレートを修正または置き換える方法を説明します。
#認識すべき 3 つの症状
トークナイザまたはチャットテンプレートの問題を示す3つのシグナルがあります。これらはモデル自体の問題ではありません。具体的には、応答内で思考タグ(通常は「think」)が開かれたまま閉じられないこと、応答の論理的な終了位置で停止せず生成が無限に続くこと、あるいは質問がされたことを理解していないかのように的外れな回答を返すことです。いずれの場合も、原因はモデル自体ではなく、入力として受け取るテキストの構造が正しく形成されていないことにあります。
#根本原因:チャットテンプレート
お使いのマシンで、プライベートかつ無料のChatGPTを1時間で構築 — LM Studio、Ollama、Open WebUI、ご自身のドキュメント、クラウド不要。
- 永久に利用できるオンラインスペース
- PDF + ファイル
- 30日間返金対応
言語モデルがメッセージをそのまま直接受け取ることはありません。トークンに変換する前に、チャットテンプレートがメッセージを整形します(発話ターンのタグ、システムプロンプト、開始・終了マーカーなど)。このテンプレートがない場合や、選択が不適切な場合、推論エンジンが正しく解釈できない場合には、モデルに渡されるテキストが学習時の形式と異なるため、出力の品質が低下します。モデルの重みとトークナイザー自体が正しくても、この問題は起こります。
#--jinjaオプション:最初に確認すべき項目
Qwenの公式ドキュメントでは、llama.cppでQwen3のGGUFを起動する際に--jinjaを追加することを明示的に推奨しています。このオプションは、GGUFファイルに埋め込まれたチャットテンプレートを使うよう指定するものです。エンジンがデフォルトで選ぶ汎用テンプレートを使うよりも、この方法を優先するよう案内されています。
起動コマンドに--jinjaが含まれていない場合は、ほかの原因を考える前に、まずこのオプションを追加してみてください。このオプションが広く使われるようになる前に作られたスクリプトやインターフェースの多くは、今でもこれを省略しています。そのため、正常なQwen3のGGUFでも「回答がおかしくなる」という報告がかなりあります。
#既知で修正済みの構文解析バグ
llama.cppでは、Qwen3のチャットテンプレートに関する特定のエラーが発生しました。テンプレートエンジンが、ツール呼び出しのロジックで会話履歴を逆順にたどるために使われるJinjaのリストスライス構文(messages[::-1])を解析できなかったのです。報告されたのは、テンプレート内のまさにその行を指す解析エラーでした。
- 01使用されているllama.cppのバージョンを確認古くなったバージョンは、Qwen3テンプレートで使用されるスライス構文のパーサー修正を含んでいない可能性があります。
- 02新しいバージョンに更新するこのケースでは、llama.cppの最新バイナリを再コンパイルまたは再ダウンロードすることで解決できます。GGUF自体を編集する必要はありません。
- 03アップデートが不可能な場合問題となっているJinja構文を避けた、簡略化したカスタムテンプレートを--chat-template-fileで指定する。
#llama-serverとllama-cliは動作が異なります
llama.cppのリポジトリで報告されている挙動として、llama-serverで--jinjaを有効にすると、応答から推論ブロック(思考タグの間にある内容)が消えることがあります。一方、同じオプションと同じモデルでllama-cliを使うと、そのブロックは表示されたままです。連携先が出力内の推論内容の存在を前提としている場合(オブザーバビリティやデバッグのためなど)、これはトークナイザーの問題ではなく、2つのバイナリ間の処理の違いです。さらに調査する前に、どちらを使っているか確認する。
この違いは、単に対話セッションを使うのではなく、llama.cpp を組み込んだシステムを構築する場合に実務上の影響があります。llama-cli で出力形式を検証するテストパイプラインを使い、その後 llama-server を介して本番環境にデプロイすると、アプリケーション側のパラメータを一切変更していなくても、この点に関して気づかないうちに退行が生じる可能性があります。本番環境で使うバイナリを明示的に文書化し、ローカル開発で使うバイナリではなく、その本番用バイナリでテストすれば、この落とし穴を避けられます。
#思考モードを強制的に無効化する
Qwen3は、チャットテンプレートのレベルで思考モードと直接回答モードを切り替える仕組みを提供しています。ただし、Qwenの公式ドキュメントによると、思考モードを強制的に無効化するこの仕組み(hard switch)は、llama.cppでは標準で利用できる形では公開されていません。Qwen3.5の派生モデルに関する最近の複数の報告が示すように、コマンドラインオプションでenable_thinkingをfalseに設定しても、バージョンによっては無視されることがあります。
Qwenが文書で示している回避策は、--chat-template-fileでカスタムテンプレートを指定し、リクエスト時にパラメータとして渡すのではなく、テンプレート自体の中でenable_thinkingを明示的にfalseに固定することです。この方法は、お使いのllama.cppのバージョンがどこまで対応しているかに左右される実行時パラメータよりも信頼できます。
誤って一般化しないために明確にしておくべき点があります。報告#20182(「enable_thinking param cannot turn off thinking」)が扱っているのは、ビルド8215でのQwen3.5-9Bです。llama.cppのリポジトリでは今も「bug-unconfirmed」ラベルが付いており、未解決のまま「not planned」としてクローズされています。Qwen3.5ではなく、元のQwen3のGGUFでも同じ挙動が起きることを示す証拠はありません。通常のQwen3でこの症状が出た場合は、このチケットの内容が自動的に確認されたとみなさず、切り分けて別途報告すべき事例として扱ってください。
#第三者が提供するGGUFファイルの出所を確認する
Qwen3のGGUFで発生するトークナイザーの問題の一部は、llama.cppではなくGGUFファイル自体に原因があります。古いバージョンの変換ツールで変換した場合や、トークナイザーが正しくエクスポートされていないファイルでは、同様の症状(生成が終了しない、特殊トークンが正しく認識されない)が現れます。推論エンジン側のバグを調べる前に、使用しているGGUFファイルのサイズと公開日を、信頼できるリポジトリ(Qwen公式、または再量子化の内容が文書化されているリポジトリ)のファイルと比較することで、ファイル自体に原因があるという可能性を除外できます。
ファイルの問題か設定の問題かを素早く判断するための簡単な目安があります。同じGGUFが別のマシンや別のバージョンのllama.cppで正常に動作するなら、ファイル自体が原因である可能性は低いでしょう。一方、同じマシンで同じリポジトリから何度ダウンロードし直しても必ず同じ症状が再現される場合は、ファイルよりもローカル設定(バイナリのバージョン、起動オプション)が原因である可能性が高くなります。
#量子化のビット数が低すぎる:ツール呼び出しの形式が不正になる
最初の3つとは異なる最後の症状は、ツール呼び出しを伴うエージェントとしての Qwen3 の使用に特に関係します。テキストのフォーマットの問題ではなく、ツール呼び出し自体が切り詰められ、引数が空または構造が不適切(無効な JSON)になります。llama.cpp に特化したコミュニティのトラブルシューティングガイドでは、ツール呼び出しの構造は量子化レベルに敏感であると記載されています。4ビット未満の量子化(Q3、Q2、IQ)は、--jinja を使用してチャットテンプレートが正しく適用されている場合でも、不正なツール呼び出しを生成します。
この点は見逃されがちです。一見すると、よくあるトークナイザーの問題に見えるためです。応答が途中で切れると、まずチャットテンプレートが正しく閉じられていないのではないかと考えてしまいます。実際に見分ける手がかりは、症状が現れる状況です。テンプレートの問題は、ツール呼び出しを含まない単純なテキストを含め、すべての応答に影響します。一方、ツール呼び出しに関する量子化の問題は、通常、自由形式のテキスト応答には影響せず、ツール呼び出しプロトコルが要求する厳密なJSON構造でのみ現れます。
#トラブルシューティング早見表
| 症状 | 最も可能性の高い原因 | 最初に試す修正 |
|---|---|---|
| 「think」タグがいつまでも閉じられない | チャットテンプレートが適用されていません | 起動時に --jinja を追加する |
| 終了しない生成 | テンプレートが正しく解釈されていない、または存在しない | --jinjaがあるか確認し、なければllama.cppを更新する |
| 起動時に「Expected value expression」エラーが発生 | Jinjaのスライシングパーサーのバグ(PR #13573で修正) | llama.cppを最近のバージョンに更新する |
| llama-serverでは思考ブロックが表示されないが、llama-cliでは表示される | 文書で確認できる、2つのバイナリ間の処理の違い | llama-cliでテストして確認し、その後チケット#14894の進展を追う |
| enable_thinking=false は無視されます | llama.cppには、強制的に切り替えるためのスイッチが標準では公開されていません | --chat-template-file を使用してテンプレートに enable_thinking=false を設定する |
| 途中で切れるツール呼び出し、または無効なJSON | 量子化のビット数が低すぎる(Q3、Q2、IQ) | 少なくともQ4_K_Mに上げる。できればQ5_K_MまたはQ6_Kにする |
| 同じモデルの古いGGUFより、新しいGGUFのほうがバグが多い | 変換に問題があるファイル、またはダウンロード中に破損したファイル | 元の配布元(Qwen公式または定評のあるリポジトリ)から再ダウンロードする |
- GGUFおよびsafetensorsフォーマットの理解
- Qwen3-32Bの技術仕様書
- llama.cpp とは何か、Ollama から移行すべきか?
- 量子化の選択(Q4、Q5、Q8、FP16)
- 出典:llama.cppでの利用に関するQwenの公式ドキュメント
- 出典:Qwen3チャットテンプレートの解析バグ(llama.cpp)
- 出典:思考ブロックに関するserverとcliの動作の違い
- 出典:llama.cppのトラブルシューティングガイド(量子化およびツール呼び出し)
自分のQwen3 GGUFが「think」タグを一向に閉じないのはなぜですか?+
--jinja オプションは Qwen3 のテンプレート問題をすべて解決しますか?+
llama.cppでQwen3の思考モードを恒久的に無効にするにはどうすればよいですか?+
最近ダウンロードされたQwen3のGGUFファイルは、以前のものと異なる挙動を示します。なぜですか?+
--jinjaを使ってもQwen3のツール呼び出しが途中で切れるのはなぜですか?+
enable_thinking が無視されるバグは、Qwen3.5だけでなくQwen3にも影響しますか?+
ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。