Level 2:モデルとGPUを理解する
Model & GPU
「27BだからこのGPU」ではなく、必要メモリをどう見積もる?
Level 1で、Nortia株式会社はSelf-hostをPoCすると決めました。次に来るのが「では、どのモデルをどのGPUで動かすのか」です。
ここで多くのプロジェクトが最初の躓きを経験します。パラメータ数だけを見てGPUを選ぶと、単体テストでは動くのに、同時利用が増えた瞬間にOOMで落ちるからです。
このLevelの位置づけ
技術そのものの解説はTechnology側に分離しています。ここでは原理の説明ではなく、要件から数字を出して候補を絞る手順に徹します。用語が分からない場合は各セクションからリンクしている解説ページを参照してください。
1. 現在の企業状況
- Self-hostのPoCを行う方針が承認された
- 検証用のハードウェアはまだ確定していない(Level 4で調達)
- モデルは未選定。社内には「有名なモデルを入れればよいのでは」という声がある
- Level 0で作った想定質問100件と、非機能要件シートがある
2. 発生した課題
技術選定の会議で、次のような発言が出ます。
「30Bクラスなら60GBくらいでしょう。121GBのマシンがあるなら余裕では?」
この見立ては、モデルの重みしか数えていません。実際に確保されるメモリは以下の合計です。
GPUメモリに載るもの
┌────────────────────────────┐
│ モデルの重み │ ← パラメータ数 × 精度
├────────────────────────────┤
│ KV Cache │ ← 同時実行数 × コンテキスト長に比例
├────────────────────────────┤
│ アクティベーション・ランタイム │ ← 断片化を含む上乗せ
└────────────────────────────┘
重みは固定ですが、KV Cacheは利用状況に比例して増えます。同時実行数を8から32に増やせば4倍、コンテキスト長を4Kから16Kにすれば4倍です。「1人で試したら動いた」は、何の保証にもなりません。
さらに厄介なのが速度です。メモリに載ることと、要求速度で動くことは別問題です。後述しますが、容量に余裕があるのに帯域で詰むという事態が普通に起こります。
3. 要件(この判断に関係する部分)
| 要件 | 値 | 出典 |
|---|---|---|
| ピーク同時利用 | 20〜50人 | Level 0 非機能要件 |
| TTFT | 2秒以内 | Level 0 非機能要件 |
| 回答完了 | 約5秒以内 | Level 0 非機能要件 |
| 1利用者への出力速度 | 20〜30 tok/s | 人が読む速度を上回る水準 |
| コンテキスト長 | PoCは4K。RAG導入後は8〜16Kを見込む | Level 5の前提 |
| 回答品質 | 想定質問100件で評価 | Level 0 評価指標 |
RAGを入れると入力が伸びる
現時点ではRAGがないため、入力は数百トークンで済みます。しかしLevel 5で検索結果をプロンプトへ詰め始めると、入力は一気に数千トークン規模になります。
4K前提でギリギリのサイジングをすると、RAGを足した時点で破綻します。 この段階から8〜16Kを想定した余裕を見ておく必要があります。
4. 選択肢
決めるべき変数は3つあり、それぞれ独立ではありません。
| 軸 | 候補 | 効く先 |
|---|---|---|
| モデル | 8B級 / 30B級 Dense / 30B級 MoE / 70B級 | 品質・メモリ・速度 |
| 精度 | BF16 / FP8 / INT4 | メモリ・速度・品質 |
| ハード | 大容量Unified Memory機 / HBM搭載GPU / 複数台 | 容量・帯域・コスト |
組み合わせは数十通りありますが、計算すれば大半はその場で消えます。
5. 技術比較:サイジングの7手順
ここからが本題です。実務では次の順序で進めます。手順3までは机上で終わり、手順4〜6は電卓で終わります。 実機が必要になるのは手順7からです。
Step 1:要件を数字にする
曖昧な言葉を、計算に使える変数へ落とします。
| 変数 | 記号 | Nortiaの値 |
|---|---|---|
| ピーク同時実行数 | C | 50(安全側) |
| 平均入力長 | Lin | 4,000トークン(RAG後想定) |
| 平均出力長 | Lout | 500トークン |
| 1利用者への出力速度 | R | 25 tok/s |
| TTFT目標 | — | 2秒 |
Step 2:必要スループットを出す
すべての出発点になる1つの数字です。
必要な合計出力速度 = 同時実行数 × 1利用者あたりの出力速度
= 50 × 25 tok/s
= 1,250 tok/s
この1,250 tok/sを1台で出すのか、複数台に分けるのかが、最終的なGPU台数の議論(Level 9)につながります。
なぜ25 tok/sなのか
日本語で人が快適に読む速度は、おおよそ毎秒10〜20文字程度です。トークンと文字は1対1ではありませんが、20〜30 tok/s出ていれば「表示が追いつかない」という不満は出ません。逆にこれを大きく超えても、体感的な価値はあまり増えません。過剰な速度目標はGPU台数に直結するため、根拠を持って決めます。
Step 3:品質要件でモデル候補を絞る
メモリ計算の前に、品質で足切りします。 載っても使えないモデルを計算しても意味がないためです。
| 観点 | 確認すること |
|---|---|
| 日本語性能 | Level 0の想定質問100件で、社内文書なしでも破綻しないか |
| ライセンス | 商用利用・社内利用の条件を満たすか |
| コンテキスト長 | RAG後の8〜16Kを扱えるか |
| 構造 | Dense か MoE か(後述のとおり速度計算が変わる) |
| 形状 | config.jsonのlayers・kv_heads・head_dim(計算に必要) |
モデルの形状は必ずconfig.jsonから取る
サイジングに必要な num_hidden_layers・num_key_value_heads・hidden_size・num_attention_heads は、モデルカードの説明文ではなく config.json の実値を参照します。同じ「30B」でもレイヤ構成は異なり、KV Cacheの量は倍近く変わることがあります。
Step 4:メモリ収支を計算する
3つを足すだけです。
① 重み
重み = パラメータ数 × 1パラメータあたりのバイト数
BF16 = 2 bytes / FP8 = 1 byte / INT4 = 0.5 bytes
例:30B を FP8 → 30 × 1 = 30 GB
② KV Cache
生成済みトークン1つごとに、全レイヤ分のKeyとValueを保持し続けます。
KV Cache / token = 2 × layers × kv_heads × head_dim × dtype_bytes
↑
K と V の2本
例:layers 64・kv_heads 8・head_dim 128・FP16
= 2 × 64 × 8 × 128 × 2
= 262,144 bytes
≈ 262 KB / token
1トークン262KBは小さく見えますが、これはリクエストごとに、コンテキスト長の分だけ積み上がります。
1リクエスト(4Kコンテキスト) = 262KB × 4,096 ≈ 1.07 GB
16並列 = 約 17.2 GB
50並列 = 約 53.7 GB ← 重みより大きい
KV Cacheが重みを追い越す
50並列・4Kコンテキストの時点で、KV Cache(約54GB)は重み(30GB)を上回ります。RAG導入で16Kまで伸びれば、KV Cacheだけで200GBを超えます。
「重みが載るか」ではなく「KV Cacheが載るか」がサイジングの主戦場です。ここを見落とすのが、冒頭の「121GBあるなら余裕では?」という誤りの正体です。
KVヘッド数が計算に効いている点にも注目してください。Attentionヘッドすべてに個別のKVを持たせる方式(MHA)ではなく、KVを共有するGQAを採用したモデルでは、この値が大幅に小さくなります。詳細はKV Cacheの解説を参照してください。
③ 上乗せ
アクティベーション、CUDAコンテキスト、メモリ断片化などで、①+②に対しておおよそ10〜20%を見込みます。ここでは15%とします。
Step 5:帯域から速度の上限を見積もる
メモリに載っても、速度が出るとは限りません。デコード(1トークンずつ生成する処理)はmemory-boundです。
1トークン生成するたびに、(アクティブな)重みを全部読む
理論上のデコード速度 = メモリ帯域 ÷ 1トークンで読む重みのバイト数
ここで、Level 1で候補に挙がった「大容量Unified Memory機」の性格が効いてきます。
| ハード種別 | 容量 | 帯域 | 30B FP8での理論デコード速度 |
|---|---|---|---|
| 大容量Unified Memory機 | 121GB | 約273 GB/s | 273 ÷ 30 ≈ 9 tok/s |
| HBM搭載データセンターGPU | 80GB | 約3,350 GB/s | 3,350 ÷ 30 ≈ 112 tok/s |
容量は余るのに、速度で要件を満たせない
121GBの機体に30Bモデルを載せると、メモリは大きく余ります。しかし理論値ですら9 tok/sで、目標の25 tok/sに届きません。理論上限を下回る実測しか出ない以上、この組み合わせは測る前に脱落します。
「大きなモデルが載る=速い」ではありません。容量と帯域は別の指標です。
では、この機体では何もできないのでしょうか。式を逆から使えば、打ち手が見えます。
必要な重みサイズ = 帯域 ÷ 目標速度 = 273 ÷ 25 ≈ 10.9 GB 以下
読むバイト数を10.9GB以下にできれば、25 tok/sに届く可能性があります。方法は2つです。
| 打ち手 | 読むバイト数 | 理論速度 | 副作用 |
|---|---|---|---|
| 量子化(30B → INT4) | 15 GB | 約18 tok/s | 品質劣化の検証が必要 |
| 小さいモデル(8B FP8) | 8 GB | 約34 tok/s | 回答品質が落ちる可能性 |
| MoE(総30B・アクティブ3B) | 3 GB(+ルーティング分) | 理論値は大幅増 | 重み30GBは常駐。効果は条件次第 |
MoEは「重みは全部メモリに置くが、1トークンの生成で読むのは一部だけ」という構造です。帯域が制約になっている環境では極めて有効ですが、バッチ処理では複数リクエストが別々のエキスパートを呼ぶため、実効的に読まれる量は増えます。理論値をそのまま信じず、実測(Level 4)で確認する前提が必要です。
TTFTは別の計算になる
デコードがmemory-boundなのに対し、プリフィル(入力を読み込む処理)はcompute-boundです。
プリフィルの計算量 ≈ 2 × パラメータ数 × 入力トークン数
例:30B・4K入力 → 2 × 30e9 × 4,096 ≈ 2.5 × 10^14 FLOPsTTFTはこの計算量を実効FLOPSで割った値が下限になります。帯域を改善してもTTFTは縮まず、演算性能を上げないと縮まない——この非対称性が、GPU選定で見落とされがちな点です。詳細はGPUの解説を参照してください。
Step 6:三すくみを表にする
モデルサイズ・コンテキスト長・同時実行数は、同じメモリを取り合います。1つを伸ばせば他が減ります。
| 伸ばすもの | 増えるメモリ | 犠牲になるもの |
|---|---|---|
| モデルサイズ | 重み(固定分) | KV Cacheの余地=同時実行数 |
| コンテキスト長 | KV Cache(線形) | 同時実行数 |
| 同時実行数 | KV Cache(線形) | 使えるコンテキスト長 |
この関係を体感するために、実際に数字を動かしてみてください。
メモリサイジング計算機
1GB = 10^9 bytes
レイヤ数・KVヘッド数・ヘッド次元は、モデルのconfig.jsonのnum_hidden_layersnum_key_value_headshidden_size / num_attention_headsから取得してください。プリセットは形状の目安であり、特定製品の実測値ではありません。
この構成なら載ります
44.4 / 121 GB
使用率 37% ・ 余裕 76.6 GB
- 重み
- 30.0 GB
- KV Cache
- 8.6 GB
- 上乗せ
- 5.8 GB
- KV Cache(1トークン)
- 262 KB
- KV Cache(1リクエスト)
- 1.07 GB
- 収容できる同時実行数
- 70 並列
- デコード速度の理論上限帯域 ÷ 1トークンで読む重み(単一リクエスト)
- 9 tok/s
上乗せ15%はアクティベーション・ランタイム・断片化の概算です。デコード速度は帯域だけから導いた理論上限であり、実測は必ずこれを下回ります。最終的な判断は実測(Level 4)で行ってください。
この計算機で確認してほしいこと
- 30B級 Dense・FP8・4K・8並列 → 121GBに余裕で載る
- そのままコンテキストを16Kにする → KV Cacheが4倍になる
- さらに同時実行を50にする → 一気に破綻する
- 精度をINT4に落とす → 重みは減るが、KV Cacheは減らない
- KV CacheをFP8にする → ここで初めてKV側が半分になる
重みの量子化とKV Cacheの量子化は別物である、という点がこの計算機の要点です。
Step 7:候補を2〜3案に絞り、測定項目を決める
理論でできるのはここまでです。以降は実測でしか決まりません。測る前に、何を測れば合否が判定できるかを決めておきます。
6. 採用判断
NortiaのPoCでは、次の3案を検証対象とします。
| 案 | 構成 | 狙い | 想定される弱点 |
|---|---|---|---|
| A | 8B級 Dense・FP8 | 速度要件を確実に満たす下限側の基準 | 回答品質が不足する可能性 |
| B | 30B級 MoE(A3B)・FP8 | 品質と速度を両立できる本命 | バッチ時に理論通り出ない |
| C | 30B級 Dense・INT4 | 品質を保ちつつ読むバイト数を減らす | 量子化による品質劣化 |
70B級は、この段階で候補から外します。 検証機の帯域では理論値でも4 tok/s程度にとどまり、要件を満たす見込みがないためです。品質面で魅力があっても、要件を満たせない構成をPoCに含めると、検証工数が無駄になります。
計算で落とすことに価値がある
3案に絞った過程で、数十通りの組み合わせを1つも動かさずに除外しました。これがサイジングの効用です。
「とりあえず動かしてみる」から始めると、落ちる構成の検証に時間を使い、なぜ落ちたのかも分からないまま次を試すことになります。計算で落とせるものは計算で落とす——これが実務での進め方です。
7. Architecture
PoC時点のメモリ収支を、構成図ではなく予算表として持ちます。
検証機(121GB)のメモリ収支:案B(30B MoE・FP8・8K・16並列)
※ layers 48・kv_heads 4・head_dim 128・KVはFP16で試算
0GB 30GB 43GB 49GB 121GB
├───────────┼──────────────┼──────────┼───────────────┤
│ 重み 30 │ KV Cache 約13 │ 上乗せ 約6 │ 余裕 約72 │
└───────────┴──────────────┴──────────┴───────────────┘
↑
同時実行を増やせるのはこの余裕の分だけ
この構成では、メモリ上は同時実行を大きく増やす余地があります。先に限界へ達するのは容量ではなく帯域であり、そのことがStep 5の計算で分かっています。
この図で管理すべき点は1つです。**余裕の部分が、そのまま「あと何並列いけるか」**を表します。運用時にここが枯渇すると、リクエストがキューで待たされるか、OOMで落ちます。
8. 実装
サイジング表テンプレート
PoC前に、次の表を埋めます。埋まらない欄がある時点で、まだ測定に進む段階ではありません。
| 項目 | 値 | 取得元 |
|---|---|---|
| モデル名・バージョン | 記入 | モデルカード |
| 総パラメータ数 | 記入 | モデルカード |
| アクティブパラメータ数 | 記入 | MoEの場合。Denseは総数と同じ |
| num_hidden_layers | 記入 | config.json |
| num_key_value_heads | 記入 | config.json |
| head_dim(hidden/heads) | 記入 | config.json |
| 重みの精度 | 記入 | 配布形式・量子化手法 |
| KV Cacheの精度 | 記入 | 推論エンジンの設定 |
| 想定コンテキスト長 | 記入 | Level 5の見込みを含める |
| 想定同時実行数 | 記入 | Level 0の非機能要件 |
| 重みサイズ(GB) | 計算 | Step 4-① |
| KV Cache(GB) | 計算 | Step 4-② |
| 合計必要メモリ(GB) | 計算 | Step 4-③まで含む |
| GPUメモリ容量(GB) | 記入 | ベンダー公称値 |
| GPUメモリ帯域(GB/s) | 記入 | ベンダー公称値 |
| 理論デコード速度(tok/s) | 計算 | Step 5 |
| 判定 | 記入 | 載るか/速度要件を満たしうるか |
実施手順
- モデル候補のconfig.jsonから形状を取得する
- 上表を候補ごとに作成する
- 容量で落ちる構成を除外する
- 帯域で落ちる構成を除外する
- 残った2〜3案をLevel 3の推論サーバー選定へ渡す
9. Benchmark / Evaluation
Level 4で検証する仮説を、いま明文化しておきます。測ってから解釈を考えると、都合のよい説明が後付けされます。
| # | 仮説 | 検証方法 | 棄却されたら |
|---|---|---|---|
| 1 | 案Bは単一リクエストで25 tok/s以上を出せる | 同時実行1で計測 | 案Aへ後退 |
| 2 | 同時実行を8まで増やしても1利用者あたり20 tok/sを維持できる | 並列数を1→2→4→8と変えて計測 | 本番GPU台数を増やす |
| 3 | 実測メモリは計算値の±20%に収まる | 起動時とピーク時のメモリを記録 | 計算式の前提を見直す |
| 4 | コンテキスト16Kでも上記が成立する | 長文プロンプトで再計測 | RAGの投入量を制限 |
| 5 | INT4(案C)の品質劣化は許容範囲 | 想定質問100件でFP8版と比較 | 案Cを除外 |
10. 残った課題
- 理論値と実測値の乖離幅が不明(推論エンジンの実装効率に依存する)
- Continuous BatchingやPagedAttentionによって、KV Cacheの実効効率が変わる(Level 3)
- MoEのバッチ時の挙動は計算だけでは読めない
- 量子化による品質劣化を、日本語の社内文書で測ったデータがまだない
11. 次のLevelへ
Level 3:推論サーバーを選ぶでは、同じモデル・同じGPUでも、推論エンジンの実装によってスループットが数倍変わる理由を扱います。
Continuous BatchingとPagedAttentionが、このLevelで計算した「三すくみ」の制約をどこまで緩められるのか——それが次の論点です。