3行でいうと
- ローカルAIは、モデル本体のほかに、会話の長さに比例して増えるKVキャッシュ(記憶の置き場所)を使う。
- 遅くなる、重くなる、読み込みでエラーになる。この3つは同じところが原因。
- 読み込み時に、設定した会話の長さの分のメモリを先に確保するので、長くしすぎるとエラーになる。
- 対策は、会話の長さを控えめにする、キャッシュの量子化など。
先に結論
ローカルAIが使うメモリは、モデル本体だけではありません。会話が長くなるほど、KVキャッシュという別の置き場所が、じわじわ大きくなります。
遅くなる、重くなる、そして最初の読み込みでエラーになる。この3つの原因は、どれも同じところにあります。
KVキャッシュとは何か
AIは文章を「トークン」という単位で読みます。単語や文字の断片のようなものです。そして、続きを1トークンずつ作ります。
新しい1トークンを作るとき、AIは、それまでの全部のトークンを見直します。Red Hatの解説によると、このとき必要になる「キー」と「値」という2種類のデータは、履歴の全体について必要で、しかも途中で変わりません。そこで、毎回計算し直さずに、メモリに保存して使い回します。この保存先がKVキャッシュです。Hugging Faceの資料も、同じ計算を毎回やらないための仕組みだと説明しています。
たとえるなら、長い本を読みながら、読んだところのメモを机に並べていくようなものです。メモがあれば読み直さずに済みます。ただし、本が長くなるほど、机の上のメモは増えていきます。
どれくらい増えるのか
1トークンあたりのKVキャッシュの大きさは、次の式で決まります。Red Hatと、Sebastian Raschka氏の解説に載っている式です。
| 項目 | 意味 |
|---|---|
| 2 | キーと値の2種類 |
| 層の数 | モデルの段数 |
| KVヘッドの数 | 注意(アテンション)を計算する窓口の数 |
| ヘッドの次元 | 窓口1つあたりのデータの幅 |
| バイト数 | 数字1つの大きさ(16ビットなら2バイト) |
この5つを掛けたものが、1トークン分です。そこに文脈の長さ(コンテキスト長)を掛けると、全体の大きさになります。モデル本体の大きさは、会話が10トークンでも1万トークンでも変わりません。KVキャッシュだけが、トークンの数に比例して増えます。
具体例が2つあります。
| モデル | 1トークンあたり | 文脈の長さと、KVキャッシュの大きさ |
|---|---|---|
| Qwen3 8B(Raschka氏) | 144KiB | 32,768トークンで約4.5GB |
| gpt-oss-120b(Red Hat) | 約36KB | 2kで約75MB、8kで約300MB、32kで約1.2GB、128kで約4.8GB |
同じ長さでも、モデルの作りで大きく違います。Red Hatは、Llama 3.3 70Bのような密なモデルでは、1トークンあたり約320KBに達すると書いています。この記事の主役であるQwen3.8-27Bについて、KVキャッシュの実際の大きさを書いた資料は、今回は見つけられませんでした。なので、数字は載せません。
なぜ遅くなるのか
Raschka氏の解説では、キャッシュが大きくなると、1トークンを作るたびにメモリを読み書きする量が増え、アテンションの計算の負担も上がります。キャッシュは、前の部分の再計算を省いてくれますが、長い前置きを無料にしてくれるわけではない、という言い方です。
先ほどのたとえなら、メモが増えるほど、1行書くたびに机の上を見渡す手間が増える、ということです。
実際の数字を見てみます。Splashの公式ブログに、M5 Pro(メモリ48GB)での測定があります。
| モデル | 短い入力 | 8K | 16K | 32K |
|---|---|---|---|---|
| Qwen3.8-27B | 毎秒74 | 毎秒55 | 毎秒55 | 毎秒54 |
| Qwen3.6-35B-A3B | 毎秒210 | 毎秒156 | 毎秒149 | 毎秒143 |
単位は、1秒に作るトークンの数です。どちらのモデルも、入力が長くなると遅くなります。ただ、27Bでは、8Kから32Kまでの落ち方がほとんどありません。短い入力からの落ち幅は、27Bで約27%、35B-A3Bで約32%です(この割合は、表の数字から計算しました)。
:::
動画の実例:32GBのM6 Mac miniで
YouTubeの「ふじもった」さんの動画「M6 Mac mini 32GBで27Bが高速化|話題の新技術「Splash」を実際に試してみた件」でも、似た傾向が語られています。以下は、動画の自動字幕から読み取った内容です。細かい数字は、動画で確かめてください。
動画によれば、M6 Mac mini(メモリ32GB)のQwen3.8-27B(Splash)は、出だしが毎秒約25トークンでした。7万トークンほど溜まった状態でも、毎秒約15でした。落ちてはいますが、止まるほどではない、という印象です。
もうひとつ大事なのが、文脈長を大きくしすぎたときの話です。動画では、KVキャッシュの確保でエラーになり、18万トークンなら読み込めた、と述べられていました。
32GBで、読み込みエラーになる理由
ここは、モデルの読み込みという場面で考えます。
LM Studioの文脈長の解説によると、アプリはモデルを読み込む時点で、設定した文脈長の分のメモリを、先に確保します。会話が実際に長くなってから増やすのではなく、「最大でこれだけ使う」という分を、最初に押さえるわけです。初期設定が2,048〜4,096トークンと控えめなのは、128,000トークンを最初から確保すると、ほとんどの家庭用GPUが落ちてしまうからだ、とも書かれています。llama.cppのヘルプでは、文脈長の初期値の0は「モデルが持つ値を使う」という意味です。Qwen3.8-27Bのモデルカードには、標準で262,144トークンまで扱えるとあります。上限いっぱいに設定すれば、その分の確保を求めることになります。
LM Studioで読み込みに失敗した例では、「Failed to initialize the context: failed to allocate compute pp buffers」というエラーが紹介されています。対処は、文脈長を減らす、より小さい量子化を選ぶ、などです。量子化とは、数字の精度を少し落として、サイズを小さくする方法です。
さらに、Macには事情があります。Appleの開発者フォーラムでは、GPUが使えるのは、ユニファイドメモリ全体の約75%だと書かれています。別の解説は、75〜80%としています。メモリ32GBなら、使える量は、およそ24〜25GBです。ここに、モデル本体とKVキャッシュと、作業用の領域が入ります。macOSやほかのアプリの分も、残しておく必要があります。
対策
出典で確認できたものを、表にまとめます。
| 対策 | 内容 | 出典で確認できたこと |
|---|---|---|
| 文脈長を控えめにする | 読み込み時の設定を下げる | LM Studioの解説は、メモリ不足のとき文脈長を半分にする例を挙げています。llama.cppは-cで指定します |
| KVキャッシュの量子化 | キャッシュの数字の精度を下げる | llama.cppは--cache-type-k、--cache-type-vで、初期値のf16から、q8_0やq4_0などに変えられます。Hugging Faceのブログでは、int4で約2.5倍小さくなり、品質はfp16と同程度でした。int2では品質が落ちたとあります |
| スライディングウィンドウ | 直近の一定の長さだけを見る | Raschka氏の例では、窓が4,096、全体が32,768なら、保持するトークンが8分の1になります。MLXには、固定サイズで回す--max-kv-sizeがあり、小さいほどメモリは減りますが、品質は下がります |
| GQA | KVヘッドを減らし、共有する | Raschka氏の例では、KVヘッドを32から8にすると、キャッシュが4分の1になります。GQAの論文では、品質を保ちながら、速さを上げる方法とされています |
| MoE | 全体の一部だけを動かす | Qwen3.6-35B-A3Bは、全体で35B、同時に動くのは3Bです |
スライディングウィンドウとGQAは、Mistral 7Bの論文でも、推論を速く・軽くするために使われた技術として挙げられています。Hugging Faceの資料では、スライディングウィンドウは、Mistral、Gemma 2、Llama 4で対応とあります。
注意が2つあります。ひとつ目は、KVキャッシュの量子化に、速さの代償があることです。Hugging Faceのブログは、バッチサイズが大きいときに生成が遅くなる、と書いています。ふたつ目は、これらの設定が、Splashで使えるかどうかを、確かめられていないことです。llama.cppやMLXの設定が、そのまま通るとは限りません。
ここから先は、僕らの見立て
事実ではなく、見立てです。
Qwen3.8-27Bは、KVキャッシュの増え方が穏やかなモデルかもしれません。 モデルカードによると、64層のうち、通常のアテンション(Gated Attention)の層は16層だけです。残りの48層はGated DeltaNetという方式で、これは、過去のトークンを固定サイズの状態にまとめます(Raschka氏の解説)。つまり、会話が長くなっても増え続けるのは、おそらく16層の分だけです。Splashの測定で、8Kから32Kまで毎秒55から54に収まっているのは、この作りと合っています。ただ、実際のメモリの使われ方を測った資料は読めていないので、確定ではありません。
MoEは、KVキャッシュを減らす対策とは、分けて考えるのがよさそうです。 MoEが軽くするのは、1トークンを作るときの計算です。今回読んだ資料には、MoEがKVキャッシュを直接小さくするとは書かれていません。35B-A3Bでも、32Kで約32%落ちています。
32GBでの現実的な線は、文脈長を控えめにすることです。 Splashの公式ブログでは、27Bの重みが15GiB、補助モデルが1.2GiBです。仮に、GPUが使える量を24GB前後とすると、残りは8GB前後になります。KVキャッシュだけでなく、作業用の領域も、ここから出ます。動画で、18万トークンまでは読み込めた、という話とは、桁としてはおかしくありません。ただ、これは私たちの粗い計算です。
使い方としては、まず控えめな文脈長で読み込み、足りなくなったら少しずつ上げる。長い文章を扱うときだけ、設定を変える。この順番が、失敗が少ないと見ています。
出典
- Splash(Inco AI公式ブログ)
- How AI inference works, clearly explained(Red Hat、日本語版)
- KV cache long context bottleneck(Sebastian Raschka)
- When GQA and SWA(Sebastian Raschka)
- Gated DeltaNet(Sebastian Raschka、LLMs from scratch)
- KV cache strategies(Hugging Face Transformers ドキュメント)
- Unlocking Longer Generation with Key-Value Cache Quantization(Hugging Face ブログ)
- GQA: Training Generalized Multi-Query Transformer Models(arXiv)
- Mistral 7B(arXiv)
- Qwen/Qwen3.8-27B(Hugging Face)
- Qwen/Qwen3.6-35B-A3B(Hugging Face)
- llama.cpp completion README(GitHub)
- mlx-lm README(GitHub)
- LM Studio Context Length(Fast.io)
- LM Studio "Failed to Load Model" の直し方(runaihome)
- recommendedMaxWorkingSetSize(Apple Developer Forums)
- Increase VRAM on Apple Silicon for local LLMs(mehmetbaykar.com)
