なぜ「GPUの追加」だけでは推論は高速化しないのか
「LLMのレスポンスが遅いから、とりあえずGPUインスタンスを追加しよう」という判断は、多くのプロジェクトで最初の選択肢として挙がりやすい傾向にあります。しかし、実務的な観点から見ると、その投資は期待したリターンの半分も生まない可能性が高いと言えます。
推論基盤の構築において、最も陥りやすい罠がこの「リソース信仰」です。確かに、モデルの学習(Training)フェーズにおいては、計算リソースの量がそのまま成果に直結することが多くあります。しかし、推論(Inference)、特に現在主流のTransformerベースのLLMにおいては、話はそう単純ではありません。
エコシステムの中核を担うHugging FaceのTransformersライブラリも、最新バージョンでは内部設計をモジュール型アーキテクチャへと大きく刷新しています。PyTorchを中心とした最適化が進められる一方で、TensorFlowやFlaxのサポートは終了となりました。また、vLLMやSGLangといった外部の高性能推論エンジンとの連携強化、さらには量子化モデル(8bit/4bit)の第一級サポートなど、ソフトウェアレベルでの効率化とアーキテクチャの抜本的な見直しが進んでいます。これはすなわち、ハードウェアの力技だけでは解決できない課題が山積していることを示唆しています。
リソース投入と速度向上の非線形な関係
推論速度とハードウェアリソースの関係は、決して線形ではありません。GPUを2倍に拡張しても、処理速度がそのまま2倍になることは稀です。むしろ、ノード間の通信オーバーヘッドや同期コストの増大によって、かえって全体のレイテンシが悪化するケースすら報告されています。
ユーザー数の急増に伴い、推論用GPUクラスターを単純に3倍に拡張したプロジェクトの事例を考えてみましょう。リソースを増やしたにもかかわらず、ユーザーからの「レスポンスが遅い」という声が一向に減らないという課題は珍しくありません。このようなケースで綿密な調査を行うと、ボトルネックはGPUの演算能力(FLOPS)そのものではなく、メモリ転送速度の限界やリクエストスケジューリングの非効率性に潜んでいることが大半です。
ここで深く理解すべきは、LLM推論における「Compute Bound(計算制約)」と「Memory Bound(メモリ制約)」という2つの相反する状態の違いです。
ボトルネックの正体:メモリ帯域幅か、計算能力か
LLMの推論プロセスは、大きく2つのフェーズに分かれています。
- Prefillフェーズ: 入力プロンプト全体を並列処理し、KVキャッシュ(Key-Value Cache)を生成する段階。
- Decodeフェーズ: 1トークンずつ順番に生成していく段階。
Prefillフェーズは巨大な行列演算の塊であり、GPUの演算能力(Compute)をフルに活用できるため、ここは典型的な「Compute Bound」になりやすい傾向があります。つまり、ハードウェアをアップグレードすれば、その分だけ処理が速くなる余地があります。
例えば、クラウドベースの機械学習において中規模プロジェクトでコストパフォーマンスに優れるA100から、現在主力のH100やH200、あるいは最新アーキテクチャであるB200(Blackwell)へと移行すれば、演算能力の向上を直接的な速度改善に繋げやすくなります。ただし、A100は成熟した選択肢である反面、徐々にレガシーな位置づけとなりつつあるため、今後の基盤設計では世代交代を意識した選定が求められます。
問題は、ユーザーが待ち時間を最も長く感じるDecodeフェーズです。ここでは、たった1つのトークンを生成するために、巨大なモデルの全パラメータと、これまでに生成した全トークンのKVキャッシュをGPUメモリから読み出す必要があります。演算量に対してメモリ転送量が圧倒的に多いため、ここは典型的な「Memory Bound」となります。
この状況下では、いくら最新のGPUを導入してコア数を増やしても、メモリ帯域幅(Memory Bandwidth)が飽和していれば速度は頭打ちになります。高速道路の車線を増やさずに、エンジンの馬力だけを上げているような状態と言えます。
さらに、最近のトレンドであるMixture of Experts(MoE)モデルを採用している場合、状況はより複雑さを増します。全パラメータを使わないスパースな構造は計算効率が良い反面、特定のエキスパートネットワークへのアクセス集中が新たなメモリボトルネックを生む原因となるからです。
こうしたハードウェアの物理的制約とモデルの特性を深く理解した上で、ソフトウェア側の設定と数理的なアプローチによって推論性能を限界まで引き出すアプローチが不可欠です。「なんとなくのリソース追加」から脱却し、計算されたキャパシティ設計へとエンジニアリングの解像度を上げる必要があります。
推論速度を科学する:TTFTとTPOTによるレイテンシ分解
「推論が遅い」という漠然とした課題をエンジニアリングで解決するには、まずその「遅さ」を計測可能な指標に分解する必要があります。LLMのパフォーマンスエンジニアリングにおいて、実務上必ず定義すべきなのがTTFTとTPOTという2つの指標です。
ユーザー体感に直結するTTFT(Time To First Token)
TTFT(Time To First Token)は、ユーザーがリクエストを送信してから、最初の1文字(トークン)が画面に表示されるまでの時間を指します。これはWebパフォーマンスにおけるTTFB(Time To First Byte)に相当し、ユーザーの「サクサク感」や「システムへの信頼感」を決定づける極めて重要な指標です。
TTFTは以下の要素で構成されます。
$$ TTFT = T_{queue} + T_{prefill} $$
- $T_{queue}$: リクエストが推論サーバーに到達してから処理が開始されるまでの待ち時間。
- $T_{prefill}$: 入力プロンプトを処理する時間。
チャットボットや対話型エージェントの場合、TTFTは0.5秒未満が理想であり、長くとも2秒以内に抑えなければユーザーはストレスを感じて離脱し始めます。ここを短縮するには、キュー待ち時間を減らすための並列処理能力と、Prefill速度(Compute性能)が重要になります。
スループットを支配するTPOT(Time Per Output Token)
一方、TPOT(Time Per Output Token)は、2トークン目以降の生成速度、つまり「文字が生成されるスピード」を指します。これはユーザーにとっての「読みやすさ」に直結します。
人間が黙読するスピードはおおよそ毎分500〜800文字程度と言われます。英語のトークン換算で言えば、1秒あたり10〜15トークン(TPS: Tokens Per Second)程度です。TPOTがこの速度を下回ると、ユーザーは生成される文字を目で追うのが遅く感じ、ストレスの要因となります。
逆に、これ以上速すぎてもユーザーは読み取れないため、過剰な高速化はコストパフォーマンスが悪化するだけです。TPOTの最適化は「速ければ速いほど良い」ではなく、「人間の認知速度をわずかに上回る」ラインを狙うのが定石です。
2つの指標のトレードオフ関係
ここでシステム設計者を悩ませるのが、バッチサイズ(Batch Size)を介したTTFTとTPOTのトレードオフ関係です。
サーバーのスループット(単位時間あたりの総処理量)を高めるためにバッチサイズを大きくすると、一度に多くのリクエストを処理できるため、システム全体の効率は上がります。しかし、個々のリクエスト視点で見るとどうなるでしょうか。
- TPOTの悪化: バッチサイズが増えると、1ステップ(1トークン生成)あたりの計算量が増えるため、各トークンの生成間隔(TPOT)は長くなります。
- TTFTの悪化: バッチ処理のサイクルが長くなると、新しく到着したリクエストが次のバッチに組み込まれるまでの待ち時間($T_{queue}$)が増加します。
多くの現場では、スループットを上げようとしてバッチサイズを大きく設定しすぎ、結果としてTTFTとTPOTの両方を犠牲にしているケースが見受けられます。逆に、レイテンシを気にしてバッチサイズを1にすれば、GPUメモリ帯域の利用効率が極端に下がり、高価なGPUを遊ばせることになります。
この「黄金比」を見つけることこそが、推論基盤の設計において極めて重要です。
エキスパートキャパシティ最適化の数理モデル
より具体的な最適化手法、特にMixtralやGrokのようなMixture of Experts (MoE) モデルを扱う際のキャパシティ設計について、数理モデルを用いて論理的に紐解いていきます。
MoEは、入力トークンごとに最適な「エキスパート(専門のニューラルネットワーク層)」を選択して処理を行うアーキテクチャです。これにより、モデル全体のパラメータ数が多くても、推論時に使用するパラメータ(Active Parameters)を抑え、高速化を実現しています。
しかし、実際の運用環境においては「特定のエキスパートへの渋滞」という固有の問題が発生します。これをいかに回避するかが、システム全体のパフォーマンスを左右します。
待ち行列理論(Littleの法則)のLLM推論への適用
推論サーバーのキャパシティプランニングにおいて、最も基本的かつ強力なツールとなるのが待ち行列理論におけるLittleの法則です。
$$ L = \lambda W $$
- $L$: システム内の平均リクエスト数(並列実行数 + キュー滞留数)
- $\lambda$: 平均リクエスト到着率(Requests Per Second)
- $W$: 平均滞在時間(TTFT + 全トークン生成時間)
この法則は、システムが安定状態にある限り、どのような分布であっても成立します。目標とする平均滞在時間 $W$ が決まっており、予想されるトラフィック $\lambda$ が分かれば、必要な並列処理数 $L$ が論理的に導き出せます。
推論システムにおいては、GPUメモリ容量が許す最大の同時処理数(Max Concurrency)が $L$ の上限となります。もし到着率 $\lambda$ が増えて $L$ が上限を超えれば、溢れた分はキューに溜まり、$W$(待ち時間)が指数関数的に増大していきます。
MoE(Mixture of Experts)モデルにおけるルーティング負荷の分散
MoEモデルでは、この待ち行列の問題が「エキスパート単位」で発生します。例えば、コーディングに関するリクエストが集中した場合、「コーディング担当のエキスパート」の前だけに長蛇の列ができ、他のエキスパートは待機状態になるというリソースの偏りが起こり得ます。
これを制御するのがExpert Capacity(エキスパートキャパシティ)の設定です。通常、各エキスパートが1回のバッチで処理できるトークン数には上限(Capacity)が設けられています。
$$ C_{expert} = \frac{B \times T \times k}{N} \times \alpha $$
- $C_{expert}$: エキスパートのキャパシティ(トークン数)
- $B$: バッチサイズ
- $T$: シーケンス長
- $k$: 1トークンあたり選択されるエキスパート数(Top-k)
- $N$: エキスパートの総数
- $\alpha$: キャパシティファクター(Capacity Factor, 通常1.0〜2.0)
ここで重要な変数が $\alpha$(キャパシティファクター)です。$\alpha = 1.0$ の場合、リクエストが完全に均等に分散されることを前提とした余裕のない設計となります。しかし現実のトークン分布は偏るため、$\alpha$ に余裕を持たせないと、キャパシティを超えたトークンは処理されずにドロップ(無視)されるか、あるいは処理待ちで全体の足を引っ張ることになります。
推論時の設定として、多くのフレームワークではこのドロップを回避するために計算を強制しますが、それがレイテンシのスパイク(突発的な遅延)を引き起こす原因となります。トラフィックの偏りを考慮して $\alpha$ を1.25〜1.5程度に見積もるアプローチが推奨されます。これにより、計算コストは若干増えますが、特定エキスパートの渋滞によるレイテンシ悪化を防ぎ、TTFTを安定させることが可能になります。
適正バッチサイズを算出する方程式
具体的にバッチサイズをどう決めるべきでしょうか。動的バッチング(Continuous Batching)を採用している推論サーバーにおいて、一般的に以下のステップで最適値が探索されます。
- ターゲットTPOTの設定: ユーザー体験として許容できる最低速度(例: 20 tokens/sec = 50ms/token)を定義します。
- 最大バッチサイズの計測: 負荷試験を行い、TPOTがターゲット値を下回らない限界のバッチサイズ($B_{max}$)を見極めます。
- メモリ制約の確認と最新の最適化: その $B_{max}$ において、KVキャッシュがGPUメモリ内に収まるかを確認します。以前はPagedAttentionのようなソフトウェアレベルのメモリ管理技術への依存度が高かったものの、現在はハードウェアとデータフォーマットの進化によりアプローチが根本から変化しています。例えば、RTX 50シリーズなどの最新環境では、NVFP4やFP8といったフォーマットを活用することで消費VRAMを最大40〜60%抑制し、システムメモリへのオフロードを最適化する手法が主流となっています。従来の複雑なページ管理に頼るのではなく、最新のデータ型とハードウェア仕様に基づいたメモリ上限($\text{VRAM}_{limit}$)の再評価と、新しい推論アーキテクチャへの移行が求められます。
数式で表現するなら、以下の制約条件を満たす最大の $B$ を求める最適化問題となります。
$$ \text{maximize } B $$
$$ \text{subject to } \text{TPOT}(B) \le \text{Target}{TPOT} \text{ and } \text{Memory}(B) \le \text{VRAM}{limit} $$
このアプローチにより、「なんとなく32」といった感覚的な設定ではなく、最新のハードウェア性能と具体的なユーザー要件に基づいた論理的なキャパシティ設計が可能になります。
【実証データ】最適化設定によるパフォーマンス改善のBefore/After
理論だけでは説得力に欠けるため、実際のプロジェクトにおける最適化事例を紹介します。対象は一般的な社内向けドキュメント検索RAGシステムで、モデルは Mixtral-8x7B-Instruct、GPUは NVIDIA A100 (80GB) × 1枚を使用しているケースです。
デフォルト設定と最適化設定の比較
初期状態では、推論サーバー(vLLMを使用)のデフォルト設定に近い状態で運用していましたが、同時アクセスが50を超えたあたりからTTFTが3秒を超え、ユーザー体験が著しく低下する事態が発生していました。
Before(最適化前)の設定:
- Max Number of Seqs (Batch Size): 256
- GPU Memory Utilization: 0.90
- Block Size: 16
After(最適化後)の設定:
- Max Number of Seqs: 64 (TPOT維持のため制限)
- GPU Memory Utilization: 0.95 (KVキャッシュ領域を最大化)
- Block Size: 32 (メモリアクセス効率向上)
- Enable Chunked Prefill: True (Prefillによるブロッキングを防止)
パフォーマンス改善結果
設定変更後、同じトラフィック負荷(50 concurrent users)をかけた際のメトリクス変化は以下の通りです。
| 指標 | Before (平均) | After (平均) | 改善率 | 備考 |
|---|---|---|---|---|
| TTFT | 3.2s | 0.45s | 85%短縮 | 劇的な改善。Chunked Prefillの効果大。 |
| TPOT | 65ms | 42ms | 35%高速化 | バッチサイズ制限により個別の生成速度向上。 |
| スループット | 350 tokens/s | 310 tokens/s | 11%低下 | 全体の処理量は微減したが、UXは向上。 |
| VRAM使用率 | 92% | 98% | - | メモリを限界まで有効活用。 |
この結果から分かる重要な事実は、「スループット(システム全体の処理量)を少し犠牲にしてでも、レイテンシ(個々の応答速度)を最適化すべき」というケースが対話型AIには多いということです。
特に Chunked Prefill(長いプロンプトの処理を分割して、合間にデコード処理を挟む技術)の有効性は特筆に値します。これにより、一部のユーザーが長いドキュメントを読み込ませても、他のユーザーのチャット応答がブロックされる現象(Head-of-Line Blocking)を防ぐことが可能になります。
KVキャッシュ最適化がもたらすインパクト
また、GPUメモリ割り当て率を0.90から0.95に上げたことも着実な効果をもたらしています。LLM推論において、GPUメモリの空き容量はそのまま「KVキャッシュとして保持できるトークン数(=コンテキストの長さ × バッチ数)」に直結します。
vLLMなどの最新エンジンは PagedAttention を採用しており、OSの仮想メモリのようにKVキャッシュを非連続なメモリブロックに管理します。メモリ利用率を高める設定にすることで、キャッシュあふれによるRe-computation(再計算)やスワップアウトを防ぎ、高い並列数でも安定した動作を実現できます。
継続的な最適化のためのモニタリング基盤
一度設定を最適化して終わりではありません。ユーザーの利用パターン(プロンプトの長さ、時間帯ごとのアクセス数)は常に変化するからです。推論基盤の健全性を保つために、以下の「真のメトリクス」を監視することが強く推奨されます。
監視すべき「真の」メトリクスとは
多くの現場では nvidia-smi で見られるGPU使用率(GPU Utilization)ばかり気にしがちですが、推論サーバーにおいてはそれはあまり意味がありません。常に100%近く張り付いているのが正常だからです。
見るべきは以下の3点です。
- KV Cache Usage (%): GPUメモリ上でKVキャッシュがどれだけ埋まっているか。これが90%を超え続けるようなら、バッチサイズを絞るか、GPUを追加する必要があります。100%に達すると、システムは新しいリクエストを受け付けられなくなるか、既存のキャッシュを破棄して大幅な遅延を招きます。
- Queue Duration (ms): リクエストが処理されずに待機している時間。TTFT悪化の先行指標となります。ここが100msを超え始めたら注意が必要です。
- Generation Length Distribution: ユーザーが生成させているトークン数の分布。想定より長い生成が多い場合、TPOTの影響が大きくなるため、バッチサイズの下方修正が必要になります。
自動スケーリングのトリガー設計
クラウド環境(AWSやGCP)でオートスケーリングを組む場合、CPU使用率をトリガーにしてはいけません。推論処理はGPUで行われるため、CPUは待機状態であることが多いからです。
ベストプラクティスは、カスタムメトリクスとして 「平均リクエスト滞留数(Queue Depth)」 または 「KVキャッシュ使用率」 をCloudWatchやStackdriverに送り、それをトリガーにスケールアウトすることです。
例えば、「KVキャッシュ使用率が80%を超えた状態が1分続いたらインスタンスを追加」という設定にしておけば、メモリバウンドによる性能劣化が起きる前に、予防的にキャパシティを拡張できます。
まとめ:数理と論理で推論コストを支配せよ
LLMの推論高速化は、単なるハードウェアへの課金ゲームではありません。それは、TTFTとTPOTのバランスを見極め、MoEの特性を理解し、待ち行列理論に基づいてパラメータを調整する、高度に知的なエンジニアリングプロセスです。
今回解説したポイントを振り返ります。
- ボトルネックの特定: 計算能力不足か、メモリ帯域不足かを常に見極める。
- 指標の分解: 「遅い」をTTFTとTPOTに分解し、どちらを優先するかでバッチサイズを決める。
- MoEの特性理解: エキスパートへの負荷集中を防ぐキャパシティ設定を行う。
- 正しいモニタリング: GPU使用率ではなく、KVキャッシュとキュー滞留時間を監視する。
これらのアプローチを実践すれば、追加のGPUを購入することなく、既存のリソースで2倍、3倍のユーザー体験向上を実現できる可能性があります。まずは自社の推論サーバーのログを開き、TTFTの数値を計算してみることから始めてみることをお勧めします。
技術の進化は早いですが、基本となる数理モデルを理解していれば、投機的デコーディングや量子化技術といった最新のアプローチや、今後登場する新しいモデルにも柔軟に対応できるはずです。
コメント