ローカルQwenの長文コンテキストが早く止まる原因をKV Cache・バックエンド・GPU別に切り分ける
メモリ不足、バックエンドの制約、速度低下、冒頭情報の忘却を分けて確認し、モデル・KV Cache・バックエンド・GPU配置を一度に一つだけ変更して、ローカルQwenの実用的なコンテキスト長を測ります。
目次

ローカルQwenを128Kコンテキストに設定したのに、72K前後でエラーになる、動作が遅すぎる、あるいは最後まで生成できても冒頭の指示を忘れることがあります。原因は一つの「正解パラメータ」ではなく、モデル重みの量子化、KV Cache、推論バックエンド、GPUへの配置が組み合わさって決まることが多いです。
この記事では、128Kを表示させることではなく、あなたの環境で安定し、十分に速く、遠い位置の情報も使える長さを求めます。最初に症状を分類し、その後は一回のテストで一つの変数だけを変えるので、KV Cacheを替えるべきか、バックエンドを替えるべきか、GPU配分を直すべきか、目標長を下げるべきかを判断できます。
結論:設定したコンテキスト長は上限であり、実用性の保証ではない
128Kという設定は、その長さの入力を扱うための領域を準備するようバックエンドに要求するだけです。実際に動くには、次のメモリ収支が成立する必要があります。
model weights + KV cache + runtime workspace + safety margin ≤ memory the backend can actually use
モデル重みは読み込み時に大きな固定領域を使います。KV Cacheは過去のtokenに対するattention状態を保持するため、保存するtoken数に応じて増えます。さらに、workspaceや一時バッファはバックエンド、batch、kernelによって変わります。割り当てに成功しても、メモリが尽きる前にprefill時間や遠距離の再現性が実用範囲を外れる場合があります。
したがって、確認すべきことは三つです。入力が収まるか、許容時間内に処理できるか、冒頭の情報を正しく使えるかです。UIに表示された最大コンテキスト値だけでは、どれも判断できません。
先に症状を分類すると、直すべき場所を間違えにくい
「128Kまで届かない」という言い方には、複数の失敗が含まれます。自分の現象に近い行から確認してください。
| 症状 | 疑う方向 | 最初に確認すること |
|---|---|---|
| モデル読み込み時や長文領域の確保時にすぐOOM | 重みとKV CacheがVRAMを取り合う、または一枚のGPUで割り当てに失敗 | GPUごとのpeak VRAMと空き容量を記録する |
| 毎回ほぼ同じtoken数でbackend error | KV形式、バックエンド実装、連続領域の境界 | モデルとハードウェアを固定し、cacheかbackendだけを変える |
| promptは受け付けるがprefillや生成が極端に遅い | 帯域、GPU間転送、kernel、目標長の過大設定 | prompt処理と生成速度を別々に測る |
| 生成は完了するが冒頭の条件や事実を忘れる | 容量ではなくeffective contextの品質 | 入力全体に散らした事実を再現できるか調べる |
| 同じテストが通ったり落ちたりする | 余裕不足、並行負荷、不安定なruntime | 他の負荷を止め、同一テストを3回繰り返す |
メモリには収まるが遅い場合、KV Cacheを小さくするだけが最善とは限りません。収まっても冒頭を使えない場合、VRAMを増やすだけでは品質が改善しない可能性があります。
72Kから128Kに伸びた一例から読み取れること
2026年9月23日の構成報告で、Nigel Hungerford-SymesはRTX 5060 Ti 16GBとRTX 3070 8GB上のQwen3.8-27B(Unsloth UD-Q5_K_M)について説明しています。報告された128K構成はbeellama.cpp + kvarn5 KV + MTP n=2で、短いコンテキストでは約36 tok/s、126Kでは約18 tok/sでした。以前のmainline llama.cppとq8_0 KVの構成は約72Kで止まったとされています。
この例が示すのは、特定の一台で推論stackを変えると到達可能な長さが変わり得ることです。ただし、backend、KV-cache方式、その他のruntime設定が同時に変わっています。そのため、「kvarn5だけで72Kから128Kになった」とは証明できず、速度を別のGPUやモデルへ一般化することもできません。
使い方は、原因確定ではなく診断の手掛かりです。同じ長さで繰り返し止まるなら、モデルファイルだけでなくKV Cacheとバックエンドも比較対象に入れます。
変更前に72K構成のbaselineを完全に残す
現在の構成を再現できる形で記録してください。baselineがなければ、新しい構成が成功しても、何が効いたのか分かりません。
| 項目 | 記録する内容 |
|---|---|
| モデル | 完全なmodel名、正確なファイル、weight quantization、ファイルサイズ |
| バックエンド | 名称、versionまたはcommit、起動方法 |
| コンテキスト | requested window、実際のinput tokens、予約したoutput tokens |
| KV Cache | data typeまたは方式、GPU/host配置、圧縮設定 |
| ハードウェア | 各GPUの型番とVRAM、system RAM、PCIe topology |
| 配置 | GPU split、offload範囲、デバイスをまたぐ処理 |
| runtime | batch、並列数、sampling、最大出力長 |
| 結果 | 成否、完全なerror、peak VRAM/RAM、prefill速度、生成速度 |
16GBと8GBのGPUを単純な24GBの共有poolとして扱わないでください。重み、cache、workspaceをどこに置くかはバックエンドが決めます。一方のGPUだけが先に満杯になることも、GPU間転送が長文処理のボトルネックになることもあります。
四つの変数を一度に一つずつ比較する
1. 重み量子化は主に固定メモリを変える
重み量子化は、モデルを読み込む時点の占有量を主に変えます。小さい重みはKV Cacheの余地を増やせますが、長いコンテキストを保証するものではなく、品質や速度も変わり得ます。
重みがcacheを圧迫しているかを調べるなら、バックエンド、KV形式、テストpromptを固定し、weight quantizationだけを替えます。解放されたVRAMと、失敗する長さが動いたかを記録してください。
2. KV Cache形式はtokenごとに増える領域を変える
KV Cacheは、次のtokenを生成するために再利用する過去の状態を保持します。同じモデルと表現方式なら、占有量は保存token数にほぼ連動するため、長文コンテキストに対する直接的な調整点です。
二つのcache方式を比べる際は、peak memory、安定して通る最長入力、再現精度を一緒に見ます。「128Kが入った」だけでは不十分です。遠い事実の再現率が落ちたり、バックエンドが不安定になったりするなら、実運用での勝利とは言えません。
3. バックエンドは各形式をどう実装するかを決める
バックエンドごとにcache layout、allocation、multi-GPU placement、kernelが異なる場合があります。同じモデルファイルとコンテキスト値でも、メモリの増え方や速度は同じとは限りません。
新しいbackendが別のKV形式を必須にする場合、結論は「このstack全体が通った」とします。単一形式だけを原因にしないでください。可能なら、双方が対応する共通設定で追加のA/Bテストを行います。
4. ハードウェア配置は、どの資源が最初に限界になるかを決める
multi-GPUで総VRAMだけを見るのは危険です。一枚のカードで十分な領域を取れない、cacheが片側に集中する、workspaceの余裕がない、GPU間転送で速度が落ちる、といった理由で失敗します。
各GPUを別々に監視してください。一枚がほぼ満杯で、もう一枚に明らかな余裕があるなら、モデル品質を下げる前にsplitやplacementを見直します。
長さのladderで再現可能な受け入れテストを行う
短いpromptからいきなり128Kへ飛ばないでください。固定した長さのladderを使うと、失敗が突然起きるのか、徐々に遅くなり再現性が落ちるのか分かります。
開始点として8K → 32K → 64K → 72K → 96K → 126Kを使えます。126Kは128Kに近く、明示的な出力枠も残せます。長い出力が必要なら、その分だけ入力目標を下げます。
同じcontrolled prompt setを準備する
- 文字数やファイルサイズではなく、対象モデルが実際に使うtokenizerでtokenを数えます。
- 入力の10%、20%から90%付近まで、重複しない「canary facts」を置きます。例は
ORBIT-17 = copperです。 - 冒頭、中間、末尾に一つずつcoding constraintを置き、最後に条件の再掲と小さなcode変更を求めます。
- すべての長さで内容順、sampling、出力budgetを同じにします。
- 他の負荷を止め、重要な長さは3回ずつ実行します。
Canary factsは検索・再現能力を測るもので、coding能力の全体評価ではありません。最終確認では、普段の仕事に近いcode、logs、repository documentationも加えてください。
毎回同じ指標を残す
| 指標 | 分かること |
|---|---|
| 実際のinput tokens | 目標長が本当にbackendへ渡ったか |
| allocation結果と完全なerror | 容量または互換性がどこで破綻したか |
| GPUごとのpeak VRAMとpeak RAM | どのdeviceが先にボトルネックになったか |
| prompt処理時間または速度 | 長文prefillが許容範囲か |
| 生成速度 | 長いprompt後も対話が実用的か |
| 正しく答えたcanary数 | 遠い位置の情報を使えているか |
| 満たしたcoding constraints | 実際の作業に長文windowが役立つか |
テスト前にpass条件を決めます。例として、目標長で3回連続完了、memory/backend errorなし、10個中9個以上のcanaryが正解、prefillと生成が自分の作業時間上限内、という基準が使えます。9/10は例にすぎません。結果を見てから基準を緩めないことが重要です。
結果ごとに次の一手を選ぶ
同じ長さで安定してOOMになる
最初に、どのdeviceが満杯かを確認します。長さとともにcacheが残りの余裕を消費するなら、より省メモリなKV方式を比較します。重み読み込み直後からほぼ余裕がないなら、小さいweight quantizationを比較します。一回につき一項目だけ変え、失敗点が予想方向に動いたかを見ます。
新backendは128K、旧backendは72Kまで
新しいstackを候補として、3回再現し、遠距離再現テストを行います。backendとcacheが同時に変わった可能性があるため、確認できるのは候補stackが機能することです。単一のroot causeが確定したとは言えません。
128Kは完走するが遅すぎる
これは容量失敗ではなく運用上の境界です。通常は小さいwindowを使い、必要な作業だけ超長文を有効にします。小さいモデル、別backend、より良いplacementも比較してください。「動く」と「毎日使う価値がある」は別の判断です。
128Kは動くが冒頭を繰り返し忘れる
effective-context qualityの問題として扱います。同じpromptを64K、72K、96Kでも実行し、再現率の曲線を作ります。短い入力の方が明確に安定するなら、allocation可能な点ではなく品質がpassする点を本番上限にします。巨大repositoryではretrieval、chunking、事前要約で無関係な情報を減らす方法も有効です。
目標は最大表示値ではなく、検証済みの作業window
72Kで日常のrepositoryやlogsを十分扱えるなら、128Kを表示するためだけに量子化、KV Cache、backend、GPU splitを同時変更しないでください。安定したbaselineを残し、各変更に容量、速度、再現性のいずれかの測定可能な改善を求めます。
100Kを超える入力が本当に必要なら、最初にlength ladderとpass条件を作り、その後にcacheとbackendの組み合わせを比較します。役に立つ最終結論は「このモデル、backend、cache、hardwareは126Kで3回連続し、必要な速度と再現性を満たした」です。「設定は128K対応」だけではありません。