ローカル LLM を動かすサーバーを選ぶとき、ついモデルのダウンロードサイズだけを見てしまいます。「5.2GB のモデルだから、8GB あれば余裕」という考え方です。
半分は正しいのですが、これだと大事な項目を1つ落とします。コンテキスト長と同時リクエスト数に比例して増えるキャッシュです。条件によっては、モデル本体より大きくなります。
この記事では、必要なメモリを3つに分けて計算し、数字で確かめます。
必要なメモリは3つの足し算
必要なメモリは、重み・KV キャッシュ・予備の合計です。中身を順に見ます。
- 重み: モデルそのものです。ダウンロードするファイルとほぼ同じ大きさになります
- KV キャッシュ: コンテキスト内のテキストについて、モデルが計算済みのキーと値を持っておく場所です
- 予備: OS やほかのサービスのぶんです。以下の計算では 1 GiB とします
重みはファイルサイズを見れば分かるので、問題はキャッシュです。
キャッシュは式で求められる
モデルの設定ファイル(config.json)の値を使うと、キャッシュの大きさは次の式で見積もれます。
2 × 層の数 × KV ヘッドの数 × ヘッドの次元 × 1値のバイト数 × コンテキスト長 × 同時リクエスト数
既定の f16 では、1値が2バイトです。なお、この式は設定値から計算したもので、Ollama が公表している数値ではありません。すべての層が同じ形であることも前提にしています。
Qwen3 8B(層 36、KV ヘッド 8、ヘッドの次元 128)で計算してみます。1トークンあたりは次のとおりです。
2 × 36 × 8 × 128 × 2 = 147,456 バイト
これにコンテキスト長を掛けます。
| コンテキスト長 | KV キャッシュ |
|---|---|
| 4,096 トークン | 576 MiB |
| 32,768 トークン | 4,608 MiB |
32,768 トークンでは約 4.5 GiB です。重み(5.2 GB、約 4.84 GiB)とほぼ同じ大きさになります。
モデルが小さくても、メモリが少なくて済むとは限らない
ここからが面白いところです。主なモデルについて、コンテキスト長を変えて合計を出しました。同時リクエストは1件、f16、予備 1 GiB です。
| モデル | ファイル (GB) | 4,096 トークンの合計 (GiB) | 32,768 トークンの合計 (GiB) |
|---|---|---|---|
| Qwen3 0.6B | 0.52 | 約 1.92 | 約 4.98 |
| Qwen3 1.7B | 1.4 | 約 2.74 | 約 5.80 |
| Qwen3 4B | 2.5 | 約 3.89 | 約 7.83 |
| Qwen3 8B | 5.2 | 約 6.41 | 約 10.34 |
| Qwen3 14B | 9.3 | 約 10.29 | 約 14.66 |
| Mistral 7B (v0.3) | 4.4 | 約 5.60 | 約 9.10 |
Qwen3 4B と Qwen3 8B を見比べてください。
- Qwen3 8B を 4,096 トークンで使う: 約 6.41 GiB
- Qwen3 4B を 32,768 トークンで使う: 約 7.83 GiB
ファイルが半分以下の 4B のほうが、たくさんのメモリを使います。 Qwen3 4B は層の数が 8B と同じなので、トークンあたりのキャッシュも同じです。モデルの大きさだけでは、必要なメモリは決まりません。
「小さいモデルにしたのに足りない」と感じたら、コンテキスト長を疑う価値があります。
同時リクエストは、そのまま掛け算になる
Ollama の FAQ には、必要な RAM は OLLAMA_NUM_PARALLEL と OLLAMA_CONTEXT_LENGTH の積に比例して増えると書かれています。例として挙がっているのは、2K のコンテキストで4件を並列に処理すると 8K のコンテキストになる、というものです。
1人で使っている間は気づきません。問題は、チームで使い始めたときです。Qwen3 8B、4,096 トークンで比べます。
| 同時リクエスト | KV キャッシュ | 合計 |
|---|---|---|
| 1件 | 576 MiB | 約 6.41 GiB |
| 4件 | 2,304 MiB | 約 8.09 GiB |
1件なら 8 GiB に余裕で収まっていたものが、4件にすると 8 GiB を超えます。OLLAMA_NUM_PARALLEL の既定値は1と記載されているので、増やすと決めるときに計算し直すのが安全です。
キャッシュの量子化という手もある
FAQ によると、KV キャッシュを q8_0 で量子化すると f16 の約半分、q4_0 では約4分の1のメモリで済みます。先ほどの4件の例を q8_0 にすると、キャッシュは約 1,152 MiB になり、合計は約 6.97 GiB です。8 GiB に戻ってきます。
選択肢は、次の4つに整理できます。
- コンテキスト長を短くする
- 同時リクエスト数を減らす
- キャッシュを量子化する
- メモリの多い環境に移す、または小さいモデルにする
ただし、ぎりぎり収まるところまでコンテキスト長を削るのはおすすめしません。使ううちに足りなくなるからです。
見積もりの限界
計算で出るのは出発点で、実測ではありません。特に次の点に注意してください。
- ランタイムの作業メモリは入っていません。 計算用のバッファのぶんは予備でまかなう考え方です
- 層の形が一様でないモデルには当てはまりません。 Mixture of Experts やスライディングウィンドウのモデルは、この式では見積もれません
- GB と GiB は違います。 1 GB は 1,000,000,000 バイト、1 GiB は 1,073,741,824 バイトです。「8GB」と書かれたメモリが 10 進の数え方なら、約 7.45 GiB しかありません。先ほどの 7.83 GiB は、数え方によって収まったり収まらなかったりします
- 速度は分かりません。 メモリに載っても、十分な速さで動くかは別の話です
最後は、使うつもりのコンテキスト長で実際にモデルを読み込み、サーバーのメモリ使用量を見てください。ollama ps を使うと、モデルが CPU にオフロードされているかも確かめられます。
詳しく知りたいとき
モデルごとの値の出どころと考え方をまとめた記事と、同じ式を自分の数値で試せるツールです。ツールはブラウザの中で動きます。
この記事は生成AIで作成し、公開前に人が最終確認しています。