AI Navigate

qwen3.5モデルのプロンプト再処理を修正する方法(instructモードのみ)

Reddit r/LocalLLaMA / 2026/3/14

💬 オピニオンTools & Practical Usage

要点

  • 記事は思考を無効化した場合の Qwen 3.5 instruct モードにおけるプロンプト再処理の問題を、Jinja テンプレートによって挿入される空の <think> ブロックが原因であると説明します。
  • 問題は次のターンでテンプレートが前回のアシスタントのメッセージから </think> タグを取り除くため、llama.cpp がプロンプトが変更されたとみなし再処理を行うことにあります。
  • 修正は、テンプレートを実際に内容を含んでいる場合にのみ think ブロックを削除するよう更新することです。空の think ブロックはプロンプトを変更しないよう保持されます。
  • 使い方についての案内があり: 修正した chat_template.jinja を保存し、--chat-template-file chat_template.jinja で渡します。サンプルテンプレートが含まれています。長い文脈でのベンチマークは報告されていません。

簡易な免責事項: これは instruct モード(思考を無効にする設定)にのみ適用されます。 思考を使用している場合、テンプレートはデフォルトと同様に動作します。

私は llama.cpp で Qwen 3.5 を思考を無効にして実行しており、前回の処理の続きではなく、毎ターン最後のメッセージを再処理していることに気づきました。

原因はデフォルトの Jinja チャット・テンプレートにあります。思考を無効にすると、生成前に空の think ブロックを挿入します: <think> </think> 。問題は次のターンで、テンプレートがチャット履歴を見て前回のアシスタントのメッセージから </think> タグを取り除くことです。llama.cpp の観点では、プロンプトがちょうど変更されたとみなされ、再処理されます。

なぜ履歴の全ての think タグを残しておかないのかと思うかもしれません。思考が有効なとき、それらのタグは大量のテキストを蓄積し、文脈ウィンドウを侵食します。その削除は合理的なトレードオフです。思考が無効なとき、挿入されたブロックは数個の空のトークンに過ぎないので、蓄積するものは少なく、削除する理由はありません。

修正は、テンプレートが think ブロックに実際に内容があるかを今はチェックするようになった点です。内容がある場合は従来どおり履歴から削除します。空の場合はそのまま保持します。

長い文脈でこれらの空のタグを保持すると出力品質に影響が出るかどうかについて、ベンチマークはまだ報告されていません。コーディング用途で 35B を用いた私の個人的な使用では、特に問題は感じませんでしたが、保証はできません。

使い方:

下のテンプレートを chat_template.jinja として保存し、--chat-template-file chat_template.jinja で渡します。

{%- set image_count = namespace(value=0) %} {%- set video_count = namespace(value=0) %} {%- macro render_content(content, do_vision_count, is_system_content=false) %} {%- if content is string %} {{- content }} {%- elif content is iterable and content is not mapping %} {%- for item in content %} {%- if 'image' in item or 'image_url' in item or item.type == 'image' %} {%- if is_system_content %} {{- raise_exception('System message cannot contain images.') }} {%- endif %} {%- if do_vision_count %} {%- set image_count.value = image_count.value + 1 %} {%- endif %} {%- if add_vision_id %} {{- 'Picture ' ~ image_count.value ~ ': ' }} {%- endif %} {{- '<|vision_start|><|image_pad|><|vision_end|>' }} {%- elif 'video' in item or item.type == 'video' %} {%- if is_system_content %} {{- raise_exception('System message cannot contain videos.') }} {%- endif %} {%- if do_vision_count %} {%- set video_count.value = video_count.value + 1 %} {%- endif %} {%- if add_vision_id %} {{- 'Video ' ~ video_count.value ~ ': ' }} {%- endif %} {{- '<|vision_start|><|video_pad|><|vision_end|>' }} {%- elif 'text' in item %} {{-