🔖

Claude Codeにおけるllama.cppのQwen3.5 KVキャッシュ無効化問題のメモ

に公開

Qwen3.5 + claude code cli はまだ無理そ なメモ(2025/03/02 時点)
https://zenn.dev/syoyo/articles/a4f11cd929f5e7

の原因


調査日: 2026年03月24日

問題点

Claude Codeからllama.cppサーバー経由でQwen3.5モデルを使用すると、リクエストのたびにKVキャッシュが無効化され、プロンプト全体の再処理(約24Kトークン以上のシステムプロンプト)が強制されます。これにより、リクエストごとに2〜3分もの遅延が発生します。

ログメッセージ: "forcing full prompt re-processing due to lack of cache data (likely due to SWA or hybrid/recurrent memory"

参考文献: https://zenn.dev/syoyo/articles/a4f11cd929f5e7

根本原因

1. Claude Codeのアトリビューション・ヘッダー(クライアント側で即修正可能)

Claude Codeは、各リクエストに変化する CLAUDE_CODE_ATTRIBUTION_HEADER を注入します。llama.cppはトークンのプレフィックス(接頭辞)をバイト単位で照合するため、システムプロンプトがわずかでも変更されると、KVキャッシュ全体が無効化されます。

修正方法: ~/.claude/settings.json に以下を追加してください。

{
  "env": {
    "CLAUDE_CODE_ATTRIBUTION_HEADER": "0"
  }
}

この修正は、#20003 において複数のユーザーによって効果が確認されています。

2. ハイブリッド/再帰型モデルのアーキテクチャ(llama.cppの制限、一部対応済み)

Qwen3.5は、再帰型(SSM/DeltaNet)レイヤーを持つハイブリッドモデルです。純粋なTransformerモデルとは異なり、再帰型レイヤーはトークンごとに更新される単一の状態(State)を保持するため、従来のプレフィックス・キャッシュが利用できません。定期的な状態のスナップショット(チェックポイント)を作成することでのみ、部分的な再利用が可能になります。

主要なマージ済みPR:

  • #20087--checkpoint-every-nb N フラグを追加(Nバッチごとにチェックポイントを作成)
  • #20288 — プロンプト処理の終了間際に2つのチェックポイントを作成

重要: --swa-full はハイブリッド/再帰型モデルには効果がありません(SWAのみのモデル用です)。#20291 でこれに関する警告が追加されました。

ステータス: 決定的な解決には至っていません。 最も包括的な修正の試み(PR #20428)はマージされずにクローズされました。オープンなIssue #19794, #19977, #19908 では、依然としてこの問題が発生していることが報告されています。

3. マルチモーダル (--mmproj) パスにおけるバグ(修正済み)

ビジョンエンコーダーを読み込むとKVの切り詰め(truncation)に失敗する問題がありました。これは #19849 および #19877 で修正済みです。--mmproj を使用している場合にのみ関連します。

推奨される回避策(優先順位順)

  1. CLAUDE_CODE_ATTRIBUTION_HEADER=0 を設定する: ~/.claude/settings.json で設定します。アトリビューション・ヘッダーが主な原因である場合、これだけで解決する可能性があります。
  2. llama-serverの起動時に --checkpoint-every-nb 3 を使用する: ハイブリッドモデルのキャッシュ再利用のために、頻繁にチェックポイントを作成します。
  3. --ctx-checkpoints N を使用する: 保存可能なチェックポイントの数を増やします。
  4. --mmproj を使用しない: ビジョン機能が必要ない限り避けてください。
  5. --cache-ram 0 を使用しない: リクエストをまたぐプロンプトキャッシュが無言で無効化されます。
  6. 最新のllama.cppビルド(b8123以降)を使用する: マージ済みのすべての修正を取り込むためです。

関連するGitHub Issues

Issue タイトル ステータス
#20225 Qwen 3.5 毎ターンでフルプロンプト再処理が発生 完了 (Closed)
#20003 Claude Code使用時のQwen3.5-35B-a3bフル再処理 完了 (回避策あり)
#19858 Qwen3.5が常にフルプロンプトを再処理する 完了 (Closed)
#19794 Qwen3-Coder-Nextでフル再処理が強制される 未解決 (Open)
#19977 Qwen3.5-122Bがコンテキストキャッシュを喪失する 未解決 (Open)
#18497 qwen3-nextでキャッシュ再利用が機能しない 完了 (Closed)
#20510 KVキャッシュのプレフィックス管理の改善 完了 (Closed)

結論

2つの独立した原因が重なり合っています:

  1. Claude Codeがプロンプトの接頭辞を変化させている — クライアント側の環境変数で修正可能です。
  2. Qwen3.5のハイブリッド・アーキテクチャ — 本質的に純粋なTransformerのようなプレフィックス・キャッシュが不可能です。チェックポイントによって部分的に緩和されていますが、llama.cppにおける完全な修正はまだマージされていません。

まずは「修正1」を試してください。それでも不十分な場合は、ハイブリッドモデル特有のキャッシュ問題として、llama.cpp側のアップデートを待つ必要があります。

おまけ: vLLM and SGLang

Investigated whether the same hybrid model prefix caching issue exists in vLLM and SGLang.

vLLM — Same issue exists, NOT solved

vLLM has the infrastructure for hybrid model prefix caching (the SupportsMambaPrefixCaching protocol and Hybrid KV Cache Manager), and several other hybrid models have implemented it (Jamba, Bamba, Mamba, Mamba2, Falcon-H1, Nemotron-H, Zamba2, GraniteMoEHybrid). However, Qwen3.5 does NOT implement this protocol, so prefix caching yields near-zero hit rates.

  • #36493 (Open) — Prefix cache hit rate on Qwen3.5-35B-A3B is ~0%, compared to ~20% on older Qwen3-30B-A3B. Confirmed root cause: Qwen3.5 model class does not implement SupportsMambaPrefixCaching.
  • #25874 (Open) — Feature request to enable Automatic Prefix Caching for Qwen3-Next hybrid attention. High community demand, no official timeline.
  • The Qwen3.5 usage guide warns: "Prefix caching for Mamba cache 'align' mode is currently experimental."
  • With TP=2, the minimum cacheable prefix is 2048 tokens due to block size alignment, further reducing cache hits.
  • No workarounds available — passing --enable-prefix-caching is essentially non-functional for Qwen3.5's Mamba layers.

SGLang — Partial solution, actively evolving

SGLang has a more advanced approach via MambaRadixCache, a specialized radix tree that stores both KV cache indices and Mamba/SSM state per node. However, it is incomplete.

  • V2 extra_buffer scheduler strategy enables "branching point caching" for Mamba states. This is the closest to working prefix caching for hybrid models. Requires --mamba-scheduler-strategy extra_buffer --page-size 64.
  • V1 no_buffer (default) has no branching point caching — similar to llama.cpp behavior.
  • Known limitations:
    • FlashInfer GDN prefill kernel has no radix cache support (#18590), so the optimized prefill path cannot benefit from prefix caching.
    • Speculative decoding (SpecV2) conflicts with radix cache mechanics (PR #12892 on hold).
    • V2 strategy increases Mamba state memory, reducing max concurrency.
    • Page size constrained to align with FLA_CHUNK_SIZE (64).
    • Cache implementations (RadixCache, MambaRadixCache, SWARadixCache) are diverged copies with inconsistent behavior — unification refactor in progress (#20415, Stage 1).
  • #20069 (Open) — Tracking Qwen3.5 bugs, numerous open items.
  • #18590 (Open) — Tracking Qwen3.5 optimizations, radix cache conflicts noted.
  • #12826 (Closed/inactive) — HiCache for hybrid LLMs was abandoned.

Summary Table

Feature llama.cpp vLLM SGLang
Qwen3.5 prefix caching Partial (checkpoints) Not working (~0% hit rate) Partial (V2 extra_buffer)
Infrastructure exists Checkpoint system SupportsMambaPrefixCaching protocol MambaRadixCache
Qwen3.5 implements it Partially (checkpoint-every-nb) No Partially (V2 only)
Status Open issues, no complete fix Open issues, no timeline Active refactor in progress
Best workaround --checkpoint-every-nb 3 None --mamba-scheduler-strategy extra_buffer

Bottom Line

The hybrid model prefix caching problem is an industry-wide issue, not specific to llama.cpp. All three major inference frameworks (llama.cpp, vLLM, SGLang) struggle with it because Qwen3.5's recurrent/GDN layers fundamentally cannot do traditional KV prefix caching.

  • llama.cpp has partial mitigations via checkpoint system
  • vLLM has the infrastructure but Qwen3.5 hasn't implemented the required protocol — currently non-functional
  • SGLang is the most advanced with MambaRadixCache + V2 strategy, but still incomplete and actively being reworked

For Claude Code specifically, the first fix remains: set CLAUDE_CODE_ATTRIBUTION_HEADER=0 to eliminate the client-side prefix mutation. The hybrid architecture limitation is a deeper problem being worked on across all frameworks.


いかがでしたか. この内容について、さらに詳しく知りたい点や、設定ファイルの書き換えのお手伝いが必要な場合は Claude クンなり Codex クンなりに相談してくださいね

Discussion