🎓 レベル:発展 | 重要度:B(推奨)
📎 前提:レイテンシとスループットのトレードオフ | 関連:推論の実務(機械学習)
⚠️ 要最新確認:LLM サービングエンジン・手法は最も進化が速い領域。具体名・数値は執筆時点(2026-06)の例。
要点(BLUF)
- LLM は巨大で、推論がそのままでは遅く高価です。これを実用速度・コストにするのが LLM 推論サービング基盤。汎用の推論最適化(レイテンシとスループットのトレードオフ)に、LLM 特有の手法が加わります。
- 核となる手法:KVキャッシュ(自己回帰生成で過去トークンの計算を再利用し毎回の再計算を避ける)、連続バッチング(リクエストを生成途中でも動的に束ね直しGPU を埋める)、量子化(モデル軽量化(量子化・蒸留・枝刈り)でメモリを削る)。
- これらを実装した専用サービングエンジン(vLLM・TGI 等、要最新確認)を使うのが定石です。原理(Transformer・自己回帰・KV)は機械学習(推論の実務)へ、ここは「それを運用基盤として選び・設計する」観点に集中します。
1. なぜ LLM 推論は特別なのか
LLM はテキストを1トークンずつ自己回帰的に生成します。N トークン生成するには N 回の前向き計算が必要で、各回で過去すべてのトークンに注意を払います。素朴に実装すると、毎回過去を全部計算し直すため、生成長の2乗に比例するコストになります。さらにモデル自体が巨大(数十〜数千億パラメータ)でメモリを食う。だから汎用サービングの常識(オンライン推論サービング)に、LLM 固有の最適化が要ります。
2. KVキャッシュ:過去の計算を再利用する
自己回帰生成では、各ステップで過去トークンの Key/Value(注意機構の中間表現)が必要です。これをキャッシュしておけば、新しいトークンを生成するとき過去分を計算し直さずに済みます。
flowchart LR T1["トークン1生成"] --> KV["KVキャッシュに保存"] KV --> T2["トークン2生成:過去のKVを再利用"] T2 --> KV KV --> T3["トークン3生成:過去のKVを再利用"]
KVキャッシュにより、各ステップの計算は「新トークン1個分」で済み、生成は実用速度になります。代わりにKVキャッシュがGPUメモリを大量に消費するため、メモリ管理(PagedAttention 等の手法・要最新確認)が運用の焦点になります。
3. 連続バッチング:GPUを遊ばせない
通常のバッチング(レイテンシとスループットのトレードオフ)は「同時に来たリクエストを束ねて一斉に処理」ですが、LLM はリクエストごとに生成長が違います。短い応答が終わってもバッチ全体が長い応答を待つと GPU が遊びます。**連続バッチング(continuous batching)**は、生成の途中でも、終わったリクエストを抜き新しいリクエストを差し込むことで GPU を常に埋めます。これが LLM サービングのスループットを大きく上げます。
4. 動く最小例:KVキャッシュが計算量をどれだけ減らすか
KVキャッシュの有無で、N トークン生成の計算量がどう変わるかを試算します(実モデルは使わず、計算ステップ数のオーダーを比較)。
def compute_steps(n_tokens, use_kv_cache):
"""N トークン生成の総計算ステップ数(注意計算の回数の代理)。
KVキャッシュなし:各ステップで過去全トークンを再計算 -> 累積で O(N^2)
KVキャッシュあり:各ステップは新トークン1個分 -> O(N)"""
total = 0
for step in range(1, n_tokens + 1):
if use_kv_cache:
total += 1 # 過去はキャッシュ済み、新規1個分
else:
total += step # 過去 step 個を毎回再計算
return total
for n in [128, 512, 2048]:
without = compute_steps(n, use_kv_cache=False)
with_kv = compute_steps(n, use_kv_cache=True)
print(f"生成{n:>4}トークン : キャッシュ無={without:>9,} "
f"有={with_kv:>5,} 削減率={(1-with_kv/without)*100:.1f}%")
出力:
生成 128トークン : キャッシュ無= 8,256 有= 128 削減率=98.4%
生成 512トークン : キャッシュ無= 131,328 有= 512 削減率=99.6%
生成2048トークン : キャッシュ無=2,098,176 有=2,048 削減率=99.9%
出力の意味:KVキャッシュなしでは生成長の2乗で計算が膨らみ、2048トークンで約210万ステップ。KVキャッシュありなら2048ステップで済み、99.9%削減です。生成が長いほど効果が大きく、これなしに長文生成は実用になりません。代償は KVキャッシュのメモリ消費で、これをどう管理するか(メモリの断片化を防ぐ PagedAttention 等)が専用エンジンの腕の見せ所です(要最新確認)。連続バッチングと組み合わせて、はじめて LLM が本番の速度・コストで回ります。
5. 運用の勘所
- 専用サービングエンジンを使う:KVキャッシュ・連続バッチング・PagedAttention を自前実装せず、vLLM・TGI 等の実績あるエンジンを使う(要最新確認)。
- メモリがボトルネック:KVキャッシュとモデル重みで GPU メモリが逼迫する。量子化(モデル軽量化(量子化・蒸留・枝刈り))で重みを削り、バッチサイズ・最大文脈長を要件で制限する。
- 遅延の2指標を見る:最初のトークンまでの時間(TTFT)と、トークンあたりの生成速度。体験はこの両方で決まる。
- APIかセルフホストか:固定費(GPU)を埋められる規模・機密・低遅延要件があればセルフホスト、そうでなければ API(LLMアプリの構成(プロンプト・推論・オーケストレーション))。
- 原理は機械学習へ:自己回帰・注意機構・KV の理論は推論の実務。ここはサービング基盤の選定・設計に集中。
なぜそうするのか
LLM サービングに専用の最適化が要るのは、自己回帰生成という構造が汎用サービングの前提を破るからです。通常のモデルは「入力1個→出力1個」を1回計算しますが、LLM は「1トークンずつ N 回」生成し、各回が過去全体に依存します。素朴な実装では計算が生成長の2乗で膨らみ、リクエストごとに生成長が違うのでバッチも揃いません。KVキャッシュが2乗を線形に落とし、連続バッチングが不揃いなリクエストで GPU を埋める——この2つがあって初めて、巨大な LLM が実用的なコストと速度で本番に乗ります。だから専用エンジンを使うのが合理的です。
⚠️ よくある落とし穴
- KVキャッシュ・連続バッチングを自前実装する:実績あるエンジンを使う方が速く安全。車輪の再発明をしない。
- メモリを考えずバッチ・文脈長を上げる:KVキャッシュが GPU メモリを食い潰し OOM になる。量子化と上限設定で管理する。
- 平均遅延だけ見る:TTFT(最初のトークン)と生成速度は別物。両方を監視する。
- 規模を無視してセルフホスト:GPU を埋められない小規模ならAPIの方が安い。稼働率で判断する(ハードウェアとスケーリング)。
- LLM推論の理論をここで詳述する:注意機構・自己回帰の原理は機械学習(推論の実務)。
対応 lab
- なし(概念ノート)。KVキャッシュの計算量効果は本文 §4。汎用サービングは オンライン推論サービング の lab。
関連ノート
- レイテンシとスループットのトレードオフ(バッチングの一般論)
- モデル軽量化(量子化・蒸留・枝刈り)(LLMの量子化)
- ハードウェアとスケーリング(GPU稼働率での判断)
- LLMアプリの構成(プロンプト・推論・オーケストレーション)(API vs セルフホスト)
- 推論の実務(機械学習・LLM推論の原理)
- 第7章 LLM・生成AIの運用基盤 目次
- MLOps・AI基盤 全体目次