- カタログの「32 GB」ではなく 31.8 GiB を見積りの分母に置く理由
- VRAM が「重み + KV キャッシュ + 余裕」の 3 つに割られる仕組みと、公式の計算式
- パラメータ数 × 量子化ビット数の表で「載る・載らない」を借りる前に判定する方法
- 70B を 4 bit にしても 1 枚には載らないという上限と、その回避策の代金
- VRAM が足りていても動かないもう 1 つの条件(CUDA 12.8 / PyTorch 2.7 以上)
「32 GB」は見積りの分母に使えない
RTX 5090 のカタログ値は VRAM 32 GB GDDR7 / メモリインターフェース 512-bit / CUDA Capability 12.0 です(NVIDIA の GeForce RTX 5090 製品ページ)。VRAM(= GPU に直結した専用メモリ。モデルはここに載せて計算する)が 32 GB あるなら 32 GB 分のモデルが載る、と読みたくなります。ここが最初の落とし穴です。
vast.ai の公開 API で 1 枚構成の RTX 5090 の offer を 64 件取ると、gpu_ram は全件 32607 MB でした(2026-08-24 時点の実測)。この 32607 は MiB 単位なので、実効値は 31.84 GiB です。カタログの 32 GB(= 32 GiB)から、ドライバの予約分を引いた値だと読めます。
32607 MiB ÷ 1024 = 31.84 GiB(実測値からの計算例)
本章の表はすべて 31.8 GiB を分母にします。「32」で計算すると、ちょうど「動くと思ったのに落ちる」幅の楽観が入ります。
値段も先に置きます。1 枚構成の on-demand は 最安 0.3215 USD/時・中央値 0.4037 USD/時(2026-08-24 時点、貸出可能な offer 64 件の実測)。1 USD = 150 円として 48〜61 円/時。24 GB の RTX 4090(実測 gpu_ram 24564 MB)は最安 0.135・中央値 0.336 USD/時なので、約 1.2 倍の値段で VRAM が 1.33 倍という立ち位置です。ただし 4090・5090 とも offer 数が 64 件を超えるため、安い順に 64 件を取った範囲の中央値です。実際の相場より安い側に寄っていると考えてください。
なお本書ではメモリ帯域(GB/s)の数値を一切使いません。NVIDIA の製品ページにその行が無いからです。vast.ai の API には gpu_mem_bw というフィールドがありますが、これはホストの申告値であって NVIDIA の公式スペックではありません。
VRAM は「重み・KV キャッシュ・余裕」の 3 つに割られる
必要 VRAM ≒ 重み + KV キャッシュ + 余裕(フレームワーク常駐・CUDA コンテキスト)
このうち計算で確定できるのは重み(= 学習で決まったモデル本体の数値。パラメータとも呼ぶ)です。vast.ai 公式も「ざっくりした見積もりはモデルパラメータ数 × 2 バイト(BF16 精度の場合)」と書いています。
重み [GB] = パラメータ数 [10 億] × 1 パラメータあたりのビット数 ÷ 8
重み [GiB] = 重み [GB] ÷ 1.073741824
2 行目が要るのは、GB(1000 の 3 乗バイト)と GiB(1024 の 3 乗バイト)が約 7 % ずれるからです。分母の 31.8 は GiB 側の数字なので、比べる相手も GiB に揃えます。
ここで効くのが量子化(= 1 つの数値を表すビット数を落として重みを小さくする圧縮)です。基準の BF16(16 bit)に対し 8 bit なら半分、4 bit なら 1/4。この「1 パラメータあたりのビット数」を bpw(bits per weight)と呼びます。
表にすると次のとおり。単位は GiB なので、そのまま 31.8 と比べられます。
| パラメータ数 | 16 bpw | 8 bpw | 6 bpw | 4 bpw |
|---|---|---|---|---|
| 7B | 13.0 | 6.5 | 4.9 | 3.3 |
| 8B | 14.9 | 7.5 | 5.6 | 3.7 |
| 14B | 26.1 | 13.0 | 9.8 | 6.5 |
| 24B | 44.7 | 22.4 | 16.8 | 11.2 |
| 32B | 59.6 | 29.8 | 22.4 | 14.9 |
| 70B | 130.4 | 65.2 | 48.9 | 32.6 |
| 120B | 223.5 | 111.8 | 83.8 | 55.9 |
3 つ目の「余裕」の実数は、参照した公式ドキュメントのどこにも書かれていません。ですから上の表からは差し引いていません。実運用ではここからさらに引かれると考えてください。vLLM の場合は gpu_memory_utilization で指定した割合を起動時に先取りし、KV キャッシュ不足で処理が押し出された(preemption)ときの公式の対処もこの値を上げることです。
コンテキスト長の代金は KV キャッシュで決まる
KV キャッシュ(= トークンごとに保持する計算済みの中間データ。長い入力・長い会話ほど増える)は、コンテキスト長に比例します。vast.ai 公式が式を明示しています。
KV キャッシュ / トークン = 2 × num_hidden_layers × num_key_value_heads × head_dim × 1 要素のバイト数
右辺の名前は、Hugging Face のモデルリポジトリに置かれた config.json(= モデルの構造を書いた設定ファイル)の項目名そのままです。公式の計算例を 2 つ並べると、規模が近くても KV キャッシュは 10 倍違うことが分かります。
| モデル(公式の例) | 公式が示している計算式 | KV / トークン |
|---|---|---|
| GLM-4.7-Flash(MHA) | 2 x 47 x 20 x 256 x 2 bytes | 約 962 KB |
| Qwen3-30B-A3B(GQA) | 2 x 48 x 4 x 128 x 2 bytes | 約 96 KB |
差の正体は num_key_value_heads です。GLM-4.7-Flash は、MoE(= Mixture of Experts。全パラメータのうち一部だけを 1 トークンごとに動かす構造。公式はこのモデルを「3B アクティブパラメータ」と表現しています)で一般的な GQA(Grouped Query Attention)ではなく MHA(Multi-Head Attention)を使い、KV ヘッドが 4 ではなく 20 あります。公式はこのモデルについて「200k コンテキストでは KV だけで約 188 GB、重みの約 60 GB と合わせて 250 GB 超が必要」と書いています。パラメータ数が同じなら必要 VRAM も同じ、ではありません。
逆算もできます。KV に割ける VRAM を G GiB、1 トークンの KV を B バイトとすると、
収まるトークン数 = G × 1024^3 ÷ B
| KV / トークン(fp16) | 4 GiB で | 8 GiB で | 16 GiB で |
|---|---|---|---|
| 96 KiB(公式例の Qwen3-30B-A3B 相当) | 43,690 tok | 87,381 tok | 174,763 tok |
| 128 KiB(中規模の GQA) | 32,768 tok | 65,536 tok | 131,072 tok |
| 256 KiB(KV ヘッド多め) | 16,384 tok | 32,768 tok | 65,536 tok |
| 940 KiB(公式例の GLM-4.7-Flash 相当) | 4,461 tok | 8,923 tok | 17,847 tok |
公式の計算例自体、962,560 バイトを「約 962 KB」(10 進)、98,304 バイトを「約 96 KB」(実際は 96 KiB)と単位が揃っていません。まずバイトで計算し、換算は最後に 1 回だけやれば取り違えません。
KV キャッシュは量子化して縮められます。Ollama は OLLAMA_KV_CACHE_TYPE で型を選べて、既定の f16 に対し q8_0 が約 1/2(公式は「モデル品質に体感できる影響はまず無い」)、q4_0 が約 1/4(コンテキストが大きいほど精度低下が出やすい)です。llama.cpp なら -ctk q8_0 -ctv q8_0。上の表の数字がそのまま 2 倍・4 倍になります。Ollama 側の指定が効くのは Flash Attention が有効なときだけですが、公式によれば対応するバックエンド・デバイスでは自動的に使われます(明示するなら OLLAMA_FLASH_ATTENTION=1)。
既定値も効きます。Ollama は VRAM 容量でコンテキスト長の既定を切り替えていて、24 GiB 未満は 4k、24〜48 GiB は 32k、48 GiB 以上は 256k。31.8 GiB の 5090 は真ん中の帯なので既定 32k です。公式は Web 検索・エージェント・コーディング用途には「少なくとも 64000 トークン」を推しているので、明示的に上げる場面があります。
OLLAMA_CONTEXT_LENGTH=64000 ollama serve
ollama ps
ollama ps の PROCESSOR 列が 100% GPU なら全部 GPU に載っています。CONTEXT 列が実際のコンテキスト長です。
借りる前に「載る・載らない」を判定する
KV の残りまで含めて並べると次のようになります。右端は 24 GiB 機(RTX 4090 相当)との比較です。
| 構成 | 重み | KV に残る | 24 GiB 機では |
|---|---|---|---|
| 8B / 16 bpw | 14.9 GiB | 約 16.9 GiB | 入る(残り約 9.1 GiB) |
| 14B / 16 bpw | 26.1 GiB | 約 5.7 GiB | 入らない |
| 14B / 8 bpw | 13.0 GiB | 約 18.8 GiB | 入る(残り約 11.0 GiB) |
| 24B / 4 bpw | 11.2 GiB | 約 20.6 GiB | 入る(残り約 12.8 GiB) |
| 32B / 4 bpw | 14.9 GiB | 約 16.9 GiB | 入る(残り約 9.1 GiB) |
| 32B / 6 bpw | 22.4 GiB | 約 9.4 GiB | 残り約 1.6 GiB で実質不可 |
| 32B / 8 bpw | 29.8 GiB | 約 2.0 GiB | 入らない |
| 70B / 4 bpw | 32.6 GiB | 入らない | 入らない |
| 70B / 3 bpw | 24.5 GiB | 約 7.3 GiB | 入らない |
4090 に対する差は約 7.9 GiB。これは「一段大きいモデルが動く」ではなく、「量子化を一段良くする」「コンテキストを伸ばす」「bf16 のまま載せる」のどれかに変換できる予算です。差が最も出るのは 32B / 6 bpw(24 GiB 機では残り 1.6 GiB で KV が取れない)と 14B / 16 bpw(24 GiB 機では入らない)です。
逆に期待を折っておくべきなのが 70B です。4 bpw でも重みだけで 32.6 GiB あり、31.8 GiB には入りません。3 bpw なら 24.5 GiB で入り KV に約 7.3 GiB 残ります。2 枚なら合計約 63.7 GiB で 4 bpw も入りますが(2 枚構成は中央値 0.856 USD/時、GPU 1 枚あたり 0.428 USD/時。2026-08-24 時点)、RTX 5090 は NVLink 非対応(公式スペックの SLI-Ready が No)。GPU 間は PCIe 経由だけになり、vast.ai の技術 FAQ も「マルチ GPU 構成では PCIe 帯域が制限になりうる」と警告しています。
もう 1 つ注意。GGUF(= llama.cpp が読み込むモデルファイルの形式)の Q4_K_M のような量子化タイプはちょうど 4 bpw ではありません。実際の bpw はファイルサイズから逆算するのが確実です。
実 bpw = 重みファイルのサイズ [GB] ÷ パラメータ数 [10 億] × 8
VRAM が足りていても動かない条件
ここまでは容量の話でした。5090 には容量と無関係に動作を止める条件がもう 1 つあります。vast.ai 公式の RTX 5 シリーズのページは Blackwell GPU は旧世代ほどの後方互換性を持たないと述べ、「テンプレートと Docker イメージが CUDA 12.8 および PyTorch 2.7 以上を使うように構成されていることが重要である」と明記しています。ここでいう Docker イメージとは、インスタンスに最初から入っているソフトウェア一式を固めたもので、借りるときに選ぶテンプレートが決めます。
ここで大事なのは「CUDA のバージョンは誰が決めるのか」です。vast.ai の技術 FAQ の答えは 「CUDA バージョンは Docker イメージに依存する」。ホスト側で固定されているのではなく、借り手が選ぶテンプレート側の問題です。確認は借りたインスタンスの中で 2 コマンド。
nvidia-smi # ホスト側のドライバのバージョンと VRAM の使用量が出る
nvcc --version # イメージ側の CUDA のバージョンが出る
PyTorch 2.7 以上かどうかは、vast.ai 公式が載せている確認スニペットで見ます。python と打って対話モードに入り、そのまま貼り付けてください。
import torch
print(f"PyTorch version: {torch.__version__}")
print(f"CUDA available: {torch.cuda.is_available()}")
print(f"GPU device: {torch.cuda.get_device_name(0)}")
1 行目が 2.7 以上、2 行目が True、3 行目に GPU の名前が出れば要件を満たしています。
ただし上限はホストのドライバが決めます。NVIDIA の対応表では CUDA 12.8 GA に Linux で 570.26 以上、CUDA 13.x に 580 以上が必要です。実測(2026-08-24 時点)ではドライバは 570.133.07〜580.159.03 に分布し、cuda_max_good(そのホストで使える CUDA の上限)は 12.8 から 13.3 のいずれかで、12.8 未満は 64 件中 1 件もありませんでした。12.8 の要件は事実上満たされている一方、CUDA 13.x 前提のイメージにはドライバ 580 以上のホストが要るということです。
もう 1 つ、名前に騙されないための事実。「Blackwell 対応」と書かれていても 5090 で動くとは限りません。compute capability(= GPU の世代を表す番号。ソフトウェアはこの番号で対応可否を判定する)は、B200 / GB200 が 10.0、B300 / GB300 が 10.3、DGX Spark の GB10 が 12.1、GeForce RTX 50 シリーズと RTX PRO Blackwell が 12.0 です。sm_100 向けにしかビルドされていないものは、同じ「Blackwell」でも 5090(sm_120)では動きません。
この番号はそのまま設定値にもなります。llama.cpp を自前ビルドするなら小数点を取った "120" を渡します(公式の例が 8.6 と 8.9 を "86;89" と書く形式なので、そこからの導出)。
cmake -B build -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES="120"
逆に断定できないことも書いておきます。vLLM の量子化方式のハードウェア対応表には Blackwell の列がありません(列は Volta / Turing / Ampere / Ada / Hopper と AMD GPU / Intel GPU / CPU 系のみ)。「5090 で AWQ が使えるか」はその表からは読み取れないので、使う版で確認します。また CUDA 13.3 Update 1 のリリースノートには compute capability 12.0 / 12.1 を名指しした cuBLAS の既知の不具合が 2 件あり、うち 1 件は条件付きで誤った結果を返します。「新しいほど安心」ではありません。
溢れたときに何が起きるか
まず既定の挙動。llama.cpp は VRAM を使い切ると落ちます。Linux では GGML_CUDA_ENABLE_UNIFIED_MEMORY=1 を付けると「VRAM が枯渇したときにクラッシュせずシステム RAM へスワップできる」ようになります。裏を返せば、付けなければ落ちるということです。次に説明する --fit が既定で効いていても落ちうるのは、--fit が調整するのは明示していない引数だけだからです(公式の「未設定の引数を調整する」という記述からの導出)。-c 32768 のように自分で大きな値を書けば、その値は据え置かれたまま VRAM を超えます。
次に、いちばん気付きにくい挙動。llama.cpp の -ngl(= VRAM に置くレイヤーの最大数。レイヤーとはモデル内部の計算の段で、モデルはこの段の積み重ねでできています)は既定 auto、--fit は既定 on。--fit は「明示していない引数をデバイスメモリに収まるよう調整する」機能で、デバイスごとに 1024 MiB のマージンを残し、コンテキストは最小 4096 まで下げます。「動いたけれど会話が短いところで切れる」の正体はほぼこれです。古い記事の -ngl 99 を写して自動調整を潰すより、何も指定せず起動ログを読むほうが速く着地します。
自分で削る手段は公式に並んでいます。上の 2 つはコンテキストの持ち方を変えるだけ、下の 3 つは計算やデータを CPU 側へ移す手段なので、上から順に試します。
-c 8192のようにコンテキストを短くする(KV キャッシュが線形に減る)-ctk q8_0 -ctv q8_0で KV キャッシュを量子化する(既定はf16)-nkvoで KV キャッシュを GPU に置かない- MoE モデルなら
-cmoe(全部)または-ncmoe N(先頭 N レイヤー)で MoE の重みを CPU へ出す -nglの数字を下げて一部のレイヤーを CPU に置く(そのぶん遅くなる。なお-ngl 0でも GPU は完全には止まらず、止めるには--device none)
llama-server --model <GGUF ファイルの絶対パス> -c 8192 -ctk q8_0 -ctv q8_0 --port 20000
<GGUF ファイルの絶対パス> には .gguf のフルパスを入れます(vast.ai 公式手順での置き場所は /workspace/llama.cpp/models)。--port 20000 は任意の数字ではなく、Open WebUI テンプレートが localhost:20000 を見に行くよう事前設定されているからです。
つまずきポイント
パラメータ数の B(10 億個)と容量の GB は別の単位です。32B を BF16 で載せると重みだけで 59.6 GiB、8 bpw でも 29.8 GiB で KV キャッシュに 2.0 GiB しか残りません。31.8 GiB で 32B を実用にするなら 6 bpw か 4 bpw です。
70B の 4 bpw は 32.6 GiB で、31.8 GiB に 0.8 GiB 足りません。3 bpw なら 24.5 GiB で入ります。2 枚で 63.7 GiB にするなら、中央値 0.856 USD/時(2026-08-24 時点)に加えて GPU 間の通信が PCIe 経由だけになることを織り込んでください。
llama.cpp は --fit が既定 on で、収まらないときに明示していない引数を勝手に下げます(マージン 1024 MiB、コンテキストは最小 4096)。Ollama も VRAM 容量で既定コンテキストが決まります。長い文書を貼ったのに途中を忘れる症状が出たら、まず ollama ps の CONTEXT 列と起動ログを見ます。
Blackwell は 1 つの番号ではありません。sm_100 向けビルドは 5090(sm_120)では動きません。またテンプレートの Docker イメージを自分で差し替えると、vast.ai 公式が警告するとおり 5 シリーズ互換性を失う可能性があります(既定の [Automatic] タグのテンプレートはサポート済みイメージを pull します)。
理解度チェック
Q1. VRAM の見積りで分母に置くべき数字は何ですか?
31.84 GiB です。offer が返す gpu_ram は 32607 MB(MiB)で、1 枚構成の RTX 5090 の 64 件すべてが同じ値でした(2026-08-24 時点の実測)。カタログの「32 GB」から予約分を引いた実効値がこれです。
Q2. 32B のモデルを 8 bpw と 6 bpw で載せたとき、KV キャッシュに残るのはそれぞれ何 GiB ですか。どちらを選びますか?
8 bpw は重み 29.8 GiB で残り約 2.0 GiB、6 bpw は重み 22.4 GiB で残り約 9.4 GiB。6 bpw を選びます。2.0 GiB では実用的なコンテキスト長が取れません。24 GiB 機では 6 bpw の残りが約 1.6 GiB しかなく、ここが 5090 の差が最も出る構成です。
Q3. 規模が近い 2 つのモデルで KV キャッシュが 10 倍違うことがあるのはなぜですか?
式の中の num_key_value_heads が違うからです。公式の計算例では MHA の GLM-4.7-Flash が KV ヘッド 20 で約 962 KB/トークン、GQA の Qwen3-30B-A3B が KV ヘッド 4 で約 96 KB/トークンでした。
Q4. ドライバが 570.x のホストで、CUDA 13.x のイメージは動きますか?
動きません。NVIDIA の対応表では CUDA 13.x にドライバ 580 以上が必要です(12.8 GA は 570.26 以上)。実測では 5090 ホストのドライバは 570.133.07〜580.159.03 と混在しているので、ホストを選ぶ段階で絞る必要があります。
Q5. llama.cpp で「起動はしたが会話が短いところで切れる」とき、最初に疑うのは何ですか?
--fit(既定 on)による自動調整です。明示していない引数を VRAM に収まるよう下げる機能で、コンテキストは最小 4096 まで縮みます。-c を明示すれば調整対象から外れます。
まとめ
- 見積りの分母は 31.8 GiB(実測
gpu_ram32607 MiB、2026-08-24 時点で 64 件すべて同一) - VRAM は 重み + KV キャッシュ + 余裕。重みは「パラメータ数 × bpw ÷ 8」で確定し、余裕の実数は公式ドキュメントに記載が無いので本章の表からは引いていない
- コンテキスト長の代金は KV キャッシュ。式は
2 × num_hidden_layers × num_key_value_heads × head_dim × 要素バイト数で、MHA と GQA で 10 倍違う - 1 枚で素直に動くのは 32B / 4 bpw と 14B / 8 bpw 前後。70B の 4 bpw(32.6 GiB)は載らない
- 容量が足りても CUDA 12.8 / PyTorch 2.7 以上でなければ動かない。CUDA を決めるのは Docker イメージ、上限を決めるのはホストのドライバ
- 溢れたときに
--fit(既定 on)が縮めるのは明示していない引数だけ。それでも収まらなければクラッシュする。「動いた」は「意図どおり動いた」ではない
次章では実際にアカウントを作ってクレジットを入れます。残高が尽きたときにインスタンスがどうなるかまで、先に押さえておきます。
参考リンク
- vast.ai — RTX 5 series(CUDA 12.8 / PyTorch 2.7 以上の必須要件、Docker イメージを変えるなという警告)
- vast.ai — Technical FAQ(CUDA バージョンは Docker イメージに依存する/PCIe 帯域の制約)
- vast.ai — GLM-4.7-Flash の例(KV キャッシュの計算式と MHA / GQA の差)
- vast.ai — PyTorch テンプレート(バージョン確認スニペット)
- vast.ai — Quantized GGUF models(モデル置き場と llama-server の起動例)
- vast.ai API — Search offers(本章の実測データを取得したエンドポイント)
- NVIDIA — CUDA GPU Compute Capability(RTX 5090 = 12.0、B200 = 10.0 の一覧)
- NVIDIA — CUDA Toolkit Release Notes(ドライバ対応表と compute capability 12.0 の既知の不具合)
- llama.cpp — tools/server/README.md(
-ngl/--fit/-ctkの既定値) - llama.cpp — docs/build.md(
CMAKE_CUDA_ARCHITECTURESと unified memory の環境変数) - Ollama Docs(Hardware support / FAQ / Context length の各ページ)
- vLLM Docs(量子化の対応ハードウェア表と
gpu_memory_utilization)