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万トークンまでは読み込めた、という話とは、桁としてはおかしくありません。ただ、これは私たちの粗い計算です。

使い方としては、まず控えめな文脈長で読み込み、足りなくなったら少しずつ上げる。長い文章を扱うときだけ、設定を変える。この順番が、失敗が少ないと見ています。

出典