LLM Serving Engine では、リクエストのスケジューリング、KV Cache メモリ、GPU の実行効率、およびマルチ GPU 分散推論の同時最適化が必要です。
1. コア技術の分類
LLM Serving Engine
│
├── Scheduler
│ ├── Continuous Batching
│ └── Chunked Prefill
│
├── Memory / KV Cache
│ ├── PagedAttention
│ ├── KV Cache Management
│ └── Prefix Caching
│
├── Execution Optimization
│ ├── FlashAttention
│ ├── CUDA Graph
│ └── Speculative Decoding
│
└── Distributed Runtime
├── Tensor Parallel(TP)
├── Pipeline Parallel(PP)
├── Data Parallel(DP)
├── Expert Parallel(EP)
└── Prefill-Decode Disaggregation
2. Continuous Batching
Continuous Batching では、異なるリクエストが異なるタイミングで GPU Batch に参加または終了することができます。
従来の Static Batching:
Batch:
A B C D
A → 20 tokens
B → 100 tokens
C → 300 tokens
D → 500 tokens
固定バッチ処理でリクエストを動的に削除または補足できない場合、無効な計算が生成され、リソースが浪費されやすくなります。
Continuous Batching:
Step 1: A B C D
Step 2: E B C D ← A 完了,E 参加する
Step 3: E F C D ← B 完了,F 参加する
主な利点:
- GPU Utilizationを上げる。
- Throughputを上げる。
- バッチ処理におけるアイドルリソースを削減します。
費用:
- より複雑なリクエストのスケジューリング。
- 同時リクエストが増えると、より多くの KV Cache が占有される可能性があります。
- 高負荷時にはキューイングの遅延がさらに増加する可能性があります。
通常、Continuous Batching は動的 KV Cache Management と組み合わせる必要があります。
3. Chunked Prefill
長い Prompt を持つ Prefill は、より長期間にわたって GPU を占有する可能性があり、すでに Decode にあるリクエストに影響を与えます。
たとえば:
Request A: Prefill 100K tokens
Request B/C/D: Decode
GPU:
AAAAAAAAAAAAAAAAAAAA
B/C/D 待ってください
Chunked Prefill は、長い Prompt を複数の Chunk に分割します。
A1: 2048 tokens
A2: 2048 tokens
A3: 2048 tokens
...
スケジューラは、異なるスケジューリング ステップで Prefill と Decode を組み合わせることができます。
Step 1: A1 + B/C/D Decode
Step 2: A2 + B/C/D Decode
Step 3: A3 + B/C/D Decode
主な目的は、Prefill と Decode の間のスケジュール関係を改善することです。
考えられる利点:
- Decode がロング Prefill によってブロックされるリスクを軽減します。
- TPOTとTail Latencyを改良しました。
- 混合負荷下でのスケジューリング効率を向上させます。
トレードオフは、長い Prompt を持つ Prefill はより多くのスケジューリング ラウンドを必要とする可能性があり、単一リクエスト TTFT が必ずしも削減されるとは限らないことです。
4. PagedAttention
PagedAttention は、KV Cache を固定サイズの Block に分割し、論理アドレスと物理アドレスのマッピングによって管理されます。
従来の予約方法:
Request A: [Used=====................]
Request B: [Used===========..........]
Request C: [Used==...................]
最大 Context Length に従ってビデオ メモリを予約すると、多くの無駄が発生します。
PagedAttention:
Request A:
Logical Block 0 → Physical Block 7
Logical Block 1 → Physical Block 2
Logical Block 2 → Physical Block 9
Request B:
Logical Block 0 → Physical Block 4
Logical Block 1 → Physical Block 1
KV Block は物理ビデオ メモリ内で連続している必要はありません。
主な値:
- KV Cache メモリの断片化を軽減します。
- リクエストごとに完全な Context Length を予約することは避けてください。
- 要求に応じて KV Block を割り当ててリサイクルします。
- より高い同時実行性をサポートします。
- Block レベルで Prefix Sharing の基礎を提供します。
PagedAttention はオペレーティング システムのページング メモリ管理からアイデアを借用していますが、GPU KV Cache を処理します。
5. Prefix Cache / Prompt Caching
複数のリクエストが同じ Token Prefix を持つ場合、すでに計算された KV Cache を再利用できます。
たとえば:
Request A:
[System Prompt] + [Question A]
Request B:
[System Prompt] + [Question B]
共通部分:
System Prompt
↓
Prefill
↓
Cached KV Blocks
├── Request A
└── Request B
主な利点:
- 重複を削減 Prefill。
- 下位TTFT。
- GPU の計算オーバーヘッドを削減します。
重要な制限:
- 対応するプレフィックス一致ルールを満たす必要があります。
- Prompt の途中にある同じテキストは、Prefix Cache として直接再利用できない場合があります。
- Chat Template、Token IDsと機種構成が互換性がある必要があります。
- Cache のヒット率はリクエストのパターンによって異なります。
たとえば、vLLM は、KV Block の Token コンテンツとその以前の完全なプレフィックスに基づいてキャッシュ ID を計算することで、Automatic Prefix Caching を実装できます。
6. KV Cache Management
KV Cache Management は、Serving Engine のコアメモリ管理モジュールです。
解決する必要がある:
KV Cache Manager
├── Allocation
├── Growth
├── Sharing
├── Reuse
├── Eviction
├── Reclamation
└── Memory Pressure Handling
主な問題には次のようなものがあります。
- どのリクエストが KV Cache を取得しますか?
- リクエストごとに Block はいくつ割り当てられますか?
- リクエスト完了後、いつリリースされますか?
- どのPrefixをキープできるでしょうか?
- ビデオ メモリが不足している場合、どのキャッシュを削除する必要がありますか?
- 一部のリクエストは一時停止または再計算する必要がありますか?
KV Cache は、長いコンテキストと高い同時実行性の推論を制限するための重要なリソースです。
7. FlashAttention
FlashAttention は、Attention の計算プロセスと GPU のメモリアクセスを最適化します。
通常のAttention:
完全な Attention Matrix を HBM に直接書き込むと、大量のメモリの読み取りと書き込みが発生します。
FlashAttention は、Tiling や Online Softmax などのメソッドを使用します。
Q Block
K Block
V Block
↓
Compute Attention Tile
↓
Online Softmax
↓
Accumulate Output
可能な限り、中間計算を GPU の SRAM / Registers などのより高速なオンチップ ストレージで完了させ、HBM へのアクセスを減らします。
FlashAttention および PagedAttention
| テクノロジー | 主な最適化オブジェクト |
|---|---|
| FlashAttention | Attention KernelとIOの計算 |
| PagedAttention | KV Cache のページング ストレージとアクセス |
| Prefix Caching | KV Promptの多重化 |
この 3 つは、入れ替わるのではなく、互いに協力することができます。
8. Speculative Decoding
通常の自己回帰生成では、通常、Target Model を 1 つずつ Token 実行する必要があります。
Speculative Decoding は、まず複数の候補 Token を生成し、次に Target Model を並行して検証できるようにします。
Draft Model(Small)
↓
Generate 5 Candidate Tokens
↓
Target Model(Large)
↓
Verify Candidates
↓
Accept Valid Prefix
↓
Continue Generation
たとえば:
Draft:
The capital of France is Paris
Target Verification:
capital ✓
of ✓
France ✓
is ✓
Paris ×
検証条件を満たす連続プレフィックスは、生成を続行する前に受け入れることができます。
なぜ加速が可能なのか?
Target Model は、各候補 Token に対して完全な自己回帰ステップを個別に実行するのではなく、1 回の検証 Forward で複数の候補位置を処理できます。
一般的な解決策:
- Draft Model。
- N-gram Speculation。
- EAGLE およびその他の特殊な推測生成メカニズム。
価格と制限
- Draft の生成自体に計算が必要です。
- 候補者の合格率が低い場合、利益は小さくなる可能性があります。
- Batch が大きくなると必ずしも加速するわけではありません。
- 追加の検証と KV Cache 管理が必要です。
正しい受け入れおよび補正アルゴリズムを使用すると、Speculative Decoding はターゲット モデルの元のサンプリング分布を維持できます。ただし、異なる実装と近似スキームでは、必ずしもまったく同じ保証があるとは限りません。
コアインジケーターはAcceptance Rateと実際に取得されたDecode Speedupです。
9. Tensor Parallel(TP)
Tensor Parallel は、モデルの特定の層の計算を複数の GPU に分割します。
たとえば:
Transformer Layer
↓
Matrix Multiplication
├── GPU 0
├── GPU 1
├── GPU 2
└── GPU 3
↓
Communication / Synchronization
主な用途:
- GPU1枚では対応できません。
- 複数の GPU を利用して単一モデルの計算能力を向上させます。
価格はGPU間の頻繁な通信です。
したがって、TP には、NVLink / NVSwitch および NCCL などの GPU 相互接続帯域幅と通信ライブラリに対してより高いパフォーマンス要件があります。
TP は、GPU の数を 2 倍にすることでパフォーマンスが 2 倍になることを保証するものではありません。
10. Pipeline Parallel(PP)
Pipeline Parallel はモデル層ごとに計算されます。
たとえば、80 層モデルの場合は次のようになります。
GPU 0: Layers 0–19
GPU 1: Layers 20–39
GPU 2: Layers 40–59
GPU 3: Layers 60–79
実行プロセス:
Input
↓
GPU 0
↓
GPU 1
↓
GPU 2
↓
GPU 3
↓
Output
主な価値は、モデルを複数のデバイスに分散させることです。
Pipeline Bubble
リクエストが 1 つだけの場合、さまざまな GPU 待機が発生する可能性があります。
Time →
GPU 0: A ----
GPU 1: A ----
GPU 2: A ----
パイプラインの使用率は、複数の Micro-batch 実行をインターリーブすることで改善できます。
Time →
GPU 0: A → B → C
GPU 1: A → B → C
GPU 2: A → B → C
ただし、パイプライン方式は、特定の複数のリクエストまたは複数の Micro-batch ロードにより適しています。これは、単一リクエストの遅延が必ずしも短縮されることを意味するものではありません。
11. Data Parallel(DP)
Data Parallel は、モデルの複数のコピーを通じてさまざまなリクエストを処理します。
Request Queue
↓
Load Balancer
├── Model Replica 1
├── Model Replica 2
└── Model Replica 3
モデルが 1 枚のシート GPU に収まる場合:
GPU 0 → Full Model
GPU 1 → Full Model
GPU 2 → Full Model
モデルで複数の GPU を使用する必要がある場合は、複数の TP/PP モデル インスタンスをコピーすることもできます。
たとえば:
TP = 4
DP = 2
Replica A: GPU 0–3
Replica B: GPU 4–7
Total GPUs = 8
主な目的は、システム全体のスループットとリクエストの処理能力を向上させることです。
DP は通常、単一モデル コピーのパラメータ サイズを削減できません。
12. Expert Parallel(EP)
Expert Parallelは主にMixture-of-Experts(MoE)モデルに使用されます。
MoE モデルでは、Expert ~ Router の一部を選択することで、異なる Token が計算に参加できます。
Token Hidden State
↓
Router
↓
Select Top-k Experts
↓
Expert Computation
↓
Combine Outputs
Expert Parallel は、異なる Expert を異なる GPU に割り当てます。
GPU 0 → Expert 0, 1
GPU 1 → Expert 2, 3
GPU 2 → Expert 4, 5
GPU 3 → Expert 6, 7
主な利点:
- 大量の Expert ウェイトを分散させます。
- より大きなMoEモデルをサポートします。
- 複数の GPU Expert 計算を実装します。
主な課題:
- Token Dispatch。
- All-to-All Communication。
- Expert Load Balancing。
多数の Token が同じ Expert を選択すると、局所的な負荷の不均衡が発生する可能性があります。
EP は、DeepSeek などの大規模な MoE モデルを展開するときに知っておくべき重要なテクニックです。
13. Prefill-Decode Disaggregation
Prefill と Decode には通常、異なるリソース要件があります。
Prefill → Compute-intensive
Decode → Memory-bandwidth-intensive
PD Disaggregation は 2 つのステージを異なる Worker に展開します。
HTTP Request
↓
Prefill Worker
↓
Transfer KV Cache
↓
Decode Worker
↓
Generated Tokens
主な利点:
- Prefill リソースと Decode リソースを個別に構成します。
- DecodeへのロングPrefillの干渉を軽減します。
- TTFT、TPOT、高負荷 Tail Latency を最適化する機会があります。
主な費用:
- KV Cache は Worker を介して送信されます。
- より複雑なルーティングとリソース管理。
- 導入、運用、保守のコストが高くなります。
SGLang は、関連するアーキテクチャとトランスポート バックエンドのサポートを提供します。実際のパフォーマンスは、相互接続の速度、ワークロード、およびスケジューリング構成によって異なります。
単一の GPU 推論の場合、通常、PD の分離は必要ありません。
14. CUDA Graph
通常の状況では、CPU は GPU Kernel を 1 つずつ送信する必要があります。
CPU:
Launch Kernel A
Launch Kernel B
Launch Kernel C
Launch Kernel D
Decode は同様の計算ステップを多数繰り返すため、Kernel Launch Overhead が明らかになる可能性があります。
CUDA Graph は、一連の GPU 操作をキャプチャできます。
Capture:
A → B → C → D
↓
CUDA Graph
↓
Repeated Replay
これにより、将来的に繰り返される CPU Kernel Launch のオーバーヘッドを削減できます。
限界
CUDA Graph には通常、実行構造、メモリ アドレス、形状の安定性に関して特定の要件があります。
LLM Serving の Batch Size、シーケンス長などは動的に変化する可能性があるため、推論エンジンは多くの場合、Graph Capture を実行するか、さまざまな形状に対して他の適応方法を使用する必要があります。
CUDA Graph は、CPU から GPU へのスケジューリング オーバーヘッドを最適化します。モデルの重みが直接軽減されるわけではありませんし、KV Cache のメモリ要件がなくなるわけでもありません。
15. 技術と性能指標の対応
| テクノロジー | 主な最適化オブジェクト | 主な影響 |
|---|---|---|
| Continuous Batching | リクエストのスケジュール設定 | Throughput |
| Chunked Prefill | Prefill / Decode スケジュール | TPOT、Tail Latency |
| PagedAttention | KV Cache ビデオ メモリ管理 | 同時実行性、メモリ使用率 |
| Prefix Caching | Prompt Prefillを繰り返す | TTFT、計算コスト |
| KV Cache Management | ビデオメモリリソースの割り当て | 同時実行性、安定性 |
| FlashAttention | Attention IO | 計算速度、メモリオーバーヘッド |
| Speculative Decoding | 自己回帰生成 | TPOT |
| CUDA Graph | Kernel Launch | TPOT、実行遅延 |
| Tensor Parallel | 単一モデルの複数の GPU 計算 | モデル容量、単一リクエストのパフォーマンス |
| Pipeline Parallel | モデル層の分布 | モデル容量 |
| Data Parallel | 複数のモデルのコピー | 合計 Throughput |
| Expert Parallel | MoE Expert分布 | MoE モデルの容量と効率 |
| PD Disaggregation | Prefill / Decode リソースの分離 | Tail Latency、リソース使用率 |
実際の結果はモデル、ハードウェア、リクエストの長さ、同時実行性に依存し、すべての最適化で TTFT、TPOT、および Throughput が同時に改善されるわけではありません。
概要
LLM Serving の最適化は、次の 4 つの質問として理解できます。
| 質問 | 解決技術 |
|---|---|
| GPU より多くのリクエストを同時に処理するにはどうすればよいですか? | Continuous Batching、Chunked Prefill |
| KV Cache 効率的に保管して再利用するにはどうすればよいですか? | PagedAttention、Prefix Cache |
| 単一の GPU 計算の効率を向上させるにはどうすればよいですか? | FlashAttention、CUDA Graph、Speculative Decoding |
| 複数の GPU を使用するモデルを作成するにはどうすればよいですか? | TP、PP、DP、EP、PD Disaggregation |
核となる関係:
Requests
↓
Scheduler
├── Continuous Batching
└── Chunked Prefill
↓
KV Cache Manager
├── PagedAttention
└── Prefix Caching
↓
Execution Engine
├── FlashAttention
├── CUDA Graph
└── Speculative Decoding
↓
Distributed Runtime(オンデマンド)
├── TP / PP / DP / EP
└── PD Disaggregation
↓
GPU
vLLM/SGLang の予備学習では、以下を理解することを優先する必要があります。
- Continuous BatchingとChunked Prefill。
- PagedAttentionとPrefix Caching。
- FlashAttentionとCUDA Graph。
- Speculative Decoding。
- TP、PP、DPの違い。
Expert Parallel および PD Disaggregation は大規模な分散推論にとって重要な手法ですが、実際に複数の GPU または MoE の展開が必要な場合はさらに研究することができます。