簡易な免責事項: これは 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 %} {{-