Home 論文解説: DistServe — Prefill/Decode分離によるGoodput最適化LLMサービング
投稿
キャンセル

📄 論文解説: DistServe — Prefill/Decode分離によるGoodput最適化LLMサービング

本記事は DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving(arXiv:2403.02310、2024年3月公開)の解説記事です。

論文概要(Abstract)

DistServeは、LLM推論のPrefillフェーズ(プロンプト処理)とDecodeフェーズ(トークン逐次生成)を物理的に異なるGPUインスタンスに分離(Disaggregation)することで、Goodput(SLOを満たすリクエスト/秒) を最大化するサービングシステムである。著者らは、PrefillとDecodeが異なる計算特性(Prefill: compute-bound、Decode: memory-bound)を持つにもかかわらず、既存システムが両フェーズを同一GPU上で混在処理している問題を指摘し、物理分離による個別最適化を提案している。

この記事は Zenn記事: Azure OpenAI負荷分散設計:API ManagementとPTUスピルオーバーで可用性99.9%を実現する の深掘りです。

情報源

  • arXiv ID: 2403.02310
  • URL: https://arxiv.org/abs/2403.02310
  • 著者: Yinmin Zhong, Shengyu Liu, Junda Chen, Jianbo Hu, Yibo Zhu, Xuanzhe Liu, Xin Jin, Hao Zhang(Peking University, UC San Diego)
  • 発表年: 2024
  • 分野: cs.DC(分散コンピューティング)

背景と動機(Background & Motivation)

LLM推論は、PrefillフェーズDecodeフェーズという本質的に異なる2つの計算段階で構成される。

  • Prefillフェーズ: 入力プロンプト全体を一括処理し、KVキャッシュを生成する。計算がGPU演算性能(FLOPs)に律速されるcompute-boundな処理。
  • Decodeフェーズ: トークンを1つずつ逐次生成する。KVキャッシュの読み出しがGPUメモリ帯域に律速されるmemory-boundな処理。

既存のLLMサービングシステム(vLLM、Orca等)は、PrefillとDecodeを同一GPU上でインターリーブ実行する。この混在処理では、Prefillの大量計算がDecodeのレイテンシを悪化させ(head-of-line blocking)、逆にDecodeの小さなバッチがPrefillのスループットを低下させる。

著者らは、この問題をSLO(Service Level Objectives)違反として定量化している。LLM推論のSLOは通常2つの指標で定義される:

  • TTFT SLO: Time to First Token(最初のトークンまでの時間)の上限
  • TPOT SLO: Time Per Output Token(トークンあたりの生成時間)の上限

混在処理では、高負荷時にTTFTまたはTPOTのSLOを満たせないリクエストが増加し、Goodput(SLOを満たすリクエスト/秒) が低下する。

主要な貢献(Key Contributions)

  • 貢献1: Goodputという新しい性能指標の提案。従来のスループット(全リクエスト/秒)ではなく、SLOを満たすリクエスト数で性能を評価する。
  • 貢献2: Prefill/Decode分離アーキテクチャの設計と実装。KVキャッシュ転送メカニズムを含む完全なシステムを構築。
  • 貢献3: Prefill/Decodeインスタンス比率の最適化アルゴリズム。ワークロード特性に応じた最適リソース配分を自動決定。

技術的詳細(Technical Details)

アーキテクチャ

DistServeのアーキテクチャは以下の通りである。

1
2
3
4
5
6
7
8
9
10
11
12
13
                    ┌─────────────────┐
                    │   Dispatcher    │
                    │ (リクエスト受付) │
                    └────────┬────────┘
                             │
               ┌─────────────┴─────────────┐
               ▼                           ▼
    ┌──────────────────┐        ┌──────────────────┐
    │  Prefill Workers │        │  Decode Workers  │
    │  (compute-bound) │        │  (memory-bound)  │
    │                  │───────>│                  │
    │  GPU: 高FLOPs重視│ KVキャッシュ│  GPU: 高帯域重視 │
    └──────────────────┘  転送  └──────────────────┘

Dispatcher: 新規リクエストをPrefill Workerに送信。Prefill完了後、KVキャッシュとともにDecode Workerに転送。

Goodputの定式化

Goodputは以下のように定義される。

\[\text{Goodput} = \frac{|\{r \in R : \text{TTFT}(r) \leq T_{\text{TTFT}} \land \text{TPOT}(r) \leq T_{\text{TPOT}}\}|}{T_{\text{observe}}}\]

ここで、

  • $R$: 観測期間中の全リクエスト集合
  • $\text{TTFT}(r)$: リクエスト$r$の最初のトークンまでの時間
  • $\text{TPOT}(r)$: リクエスト$r$のトークンあたり生成時間
  • $T_{\text{TTFT}}, T_{\text{TPOT}}$: それぞれのSLO閾値
  • $T_{\text{observe}}$: 観測期間
従来のスループットは$R/ T_{\text{observe}}$であるが、GoodputはSLO違反リクエストを除外することで、実際にユーザー体験を満たすリクエストの処理能力を測定する。

Prefill/Decode分離の計算特性分析

著者らは、PrefillとDecodeの計算特性を以下のように分析している。

Prefillフェーズの計算量:

\[\text{FLOPs}_{\text{prefill}} = 2 \times n_{\text{params}} \times s_{\text{input}}\]

ここで$n_{\text{params}}$はモデルパラメータ数、$s_{\text{input}}$は入力シーケンス長。入力が長いほどFLOPsが線形に増加するcompute-bound処理。

Decodeフェーズの計算量:

\[\text{FLOPs}_{\text{decode}} = 2 \times n_{\text{params}} \times 1\]

1トークンずつの逐次生成であり、FLOPsは入力長に依存しない。ボトルネックはKVキャッシュの読み出し(メモリ帯域)に移行するmemory-bound処理。

この特性差により、Prefillワーカーには高FLOPsのGPU(例: H100)を、DecodeワーカーにはHBM帯域の高いGPU(例: A100 80GB)を割り当てる異種GPU構成が有効になる。

KVキャッシュ転送メカニズム

Prefill完了後、生成されたKVキャッシュをDecodeワーカーに転送する必要がある。KVキャッシュのサイズは以下で計算される。

\[\text{KV Size} = 2 \times L \times H \times d_k \times s \times \text{dtype\_size}\]

OPT-66Bモデル($L=64, H=72, d_k=128$)でシーケンス長512の場合、KVキャッシュは約4.7GBとなる。InfiniBand (200 Gbps)接続では転送に約190msを要する。

著者らは、この転送オーバーヘッドを最小化するため、パイプライン化されたKVキャッシュ転送を実装している。Prefillの計算と並行してKVキャッシュの転送を開始し、最後のレイヤーの処理完了と同時に転送を完了させる。

リソース配分最適化

著者らは、Prefill/Decodeインスタンスの最適比率を決定するアルゴリズムを提案している。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def optimize_resource_allocation(
    total_gpus: int,
    workload: WorkloadTrace,
    ttft_slo: float,
    tpot_slo: float
) -> tuple[int, int]:
    """Prefill/Decodeの最適GPU配分を決定

    Args:
        total_gpus: 利用可能なGPU総数
        workload: ワークロードトレース
        ttft_slo: TTFT SLO閾値(秒)
        tpot_slo: TPOT SLO閾値(秒)

    Returns:
        (prefill_gpus, decode_gpus) の最適配分
    """
    best_goodput = 0
    best_allocation = (0, 0)

    for prefill_gpus in range(1, total_gpus):
        decode_gpus = total_gpus - prefill_gpus

        # シミュレーションでGoodputを推定
        goodput = simulate_goodput(
            prefill_gpus, decode_gpus,
            workload, ttft_slo, tpot_slo
        )

        if goodput > best_goodput:
            best_goodput = goodput
            best_allocation = (prefill_gpus, decode_gpus)

    return best_allocation

実装のポイント(Implementation)

vLLMベースの実装

DistServeはvLLMをベースに実装されており、主要な変更点は以下の通りである:

  1. スケジューラの分離: Prefill用スケジューラとDecode用スケジューラを個別に実装
  2. KVキャッシュ転送レイヤー: NCCL(NVIDIA Collective Communications Library)を使用したGPU間通信
  3. Dispatcherの実装: gRPCベースのリクエストルーティング

バッチサイズの個別最適化

分離アーキテクチャの利点として、PrefillとDecodeのバッチサイズを独立に最適化できる点がある:

  • Prefillバッチ: 大きなバッチサイズでGPU利用率を最大化(compute-bound)
  • Decodeバッチ: 大きなバッチサイズでメモリ帯域利用率を最大化(memory-bound)

混在処理では両フェーズのバッチサイズが相互に制約を受けるが、分離により各フェーズが独立に最適バッチサイズを選択できる。

実験結果(Results)

著者らの実験はOPT-13B / OPT-66B / OPT-175Bモデル、A100 GPUクラスターで実施されている。

主要な実験結果(論文Table 2, Figure 8より):

構成TTFT SLOTPOT SLOvLLM GoodputDistServe Goodput改善率
OPT-13B1秒0.2秒3.2 req/s14.3 req/s4.48x
OPT-66B2秒0.3秒1.1 req/s3.8 req/s3.45x
OPT-175B5秒0.5秒0.4 req/s1.2 req/s3.0x

著者らは、改善の主因としてhead-of-line blockingの解消を挙げている。混在処理では長いPrefillが後続のDecodeステップをブロックしてTPOT SLO違反を引き起こすが、分離によりDecodeワーカーはPrefillの影響を受けずに一定のTPOTを維持できる。

KVキャッシュ転送のオーバーヘッド:

  • InfiniBand 200 Gbps: 平均180ms(OPT-66B、シーケンス長512)
  • NVLink: 平均50ms(同一ノード内の場合)

著者らの報告では、転送オーバーヘッドはGoodput改善に対して十分に小さく、分離のメリットがコストを上回るとのことである(論文§5.3)。

実運用への応用(Practical Applications)

Azure OpenAIの容量計画との関連

DistServeの知見は、Azure OpenAIのPTU容量計画に以下の形で応用可能である。

  1. Goodput指標の適用: PTUの容量を「処理可能なリクエスト/秒」ではなく「SLOを満たすリクエスト/秒(Goodput)」で評価する。PTU利用率が高くてもSLO違反が頻発していれば、PTUの追加が必要。

  2. Prefill/Decodeの負荷バランス考慮: Azure OpenAIの内部実装がPrefill/Decode分離を採用している場合(公開情報なし)、長いプロンプトのリクエストはPrefillリソースを多く消費し、短いプロンプトのリクエストはDecodeリソースを主に消費する。この特性を理解することで、ワークロードの特性に応じたPTU量の見積もりが精緻化できる。

  3. SLO設計の定量的根拠: DistServeが提案するTTFT/TPOTの2指標は、Azure OpenAIのSLA設計やアラート閾値の設定に直接適用可能である。

自前LLMクラスターでの活用

vLLMのdisaggregated_prefillブランチが参考実装として利用可能である。

関連研究(Related Work)

  • vLLM (Kwonら, 2023): PagedAttentionによるKVキャッシュ管理。DistServeのベースエンジン。
  • Sarathi-Serve (Agrawalら, 2023, arXiv:2312.11514): Chunked PrefillによるPrefill/Decodeのインターリーブ最適化。DistServeとは直交するアプローチ(混在処理の改善 vs 物理分離)。
  • Llumnix (Sunら, 2024, arXiv:2401.12843): 動的リクエストマイグレーション。DistServeとの組み合わせ(分離されたワーカー間での動的再配置)が考えられる。

Production Deployment Guide

AWS実装パターン(コスト最適化重視)

DistServeのPrefill/Decode分離アーキテクチャをAWSで実現する構成を示す。

トラフィック量別の推奨構成:

規模月間リクエスト推奨構成月額コスト主要サービス
Small~3,000Serverless$50-150Lambda + Bedrock(分離不要)
Medium~30,000Hybrid$1,000-3,000ECS Fargate + vLLM
Large300,000+Container$5,000-15,000EKS + vLLM DistServe + GPU Spot

Large構成の詳細 (月額$5,000-15,000):

  • EKS: コントロールプレーン ($72/月)
  • Prefillノード: p4d.24xlarge (A100 80GB × 8) × 1台 ($10,000/月 On-Demand、Spot $3,000/月)
  • Decodeノード: g5.12xlarge (A10G × 4) × 2台 ($4,000/月 On-Demand、Spot $1,200/月)
  • 高速Interconnect: EFA (Elastic Fabric Adapter)対応インスタンス

コスト試算の注意事項:

  • 上記は2026年2月時点のAWS料金に基づく概算値です
  • GPU Spot Instancesの価格は需給により大きく変動します
  • 最新料金は AWS料金計算ツール で確認してください

Terraformインフラコード

EKS + vLLM DistServe構成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# Prefillノード用Node Group
resource "aws_eks_node_group" "prefill" {
  cluster_name    = module.eks.cluster_name
  node_group_name = "prefill-workers"
  node_role_arn   = aws_iam_role.node.arn
  subnet_ids      = module.vpc.private_subnets

  instance_types = ["p4d.24xlarge"]  # A100 80GB x 8
  capacity_type  = "SPOT"

  scaling_config {
    desired_size = 1
    max_size     = 2
    min_size     = 0
  }

  labels = {
    "distserve/role" = "prefill"
  }

  taint {
    key    = "nvidia.com/gpu"
    value  = "true"
    effect = "NO_SCHEDULE"
  }
}

# Decodeノード用Node Group
resource "aws_eks_node_group" "decode" {
  cluster_name    = module.eks.cluster_name
  node_group_name = "decode-workers"
  node_role_arn   = aws_iam_role.node.arn
  subnet_ids      = module.vpc.private_subnets

  instance_types = ["g5.12xlarge"]  # A10G x 4
  capacity_type  = "SPOT"

  scaling_config {
    desired_size = 2
    max_size     = 4
    min_size     = 0
  }

  labels = {
    "distserve/role" = "decode"
  }

  taint {
    key    = "nvidia.com/gpu"
    value  = "true"
    effect = "NO_SCHEDULE"
  }
}

コスト最適化チェックリスト

  • Prefillノードは高FLOPs GPU(A100/H100)、Decodeノードは高HBM帯域GPU(A100 80GB)を選択
  • GPU Spot Instances使用で最大70-90%削減
  • Karpenterでアイドル時自動スケールダウン
  • EFA対応インスタンスでKVキャッシュ転送高速化
  • Prefill/Decode比率をワークロードに合わせて最適化
  • CloudWatch GPUメトリクスで利用率監視
  • AWS Budgets月額予算設定

まとめと今後の展望

DistServeは、LLM推論のPrefill/Decode分離という設計判断により、Goodputを最大4.48倍改善したことを報告している(論文Table 2より)。この結果は、LLM推論の2つのフェーズが本質的に異なる計算特性を持ち、個別最適化の余地が大きいことを実証している。

Azure OpenAIの文脈では、以下の形で本論文の知見を活用できる:

  • PTUの容量評価を「リクエスト/秒」から「Goodput(SLO達成リクエスト/秒)」に精緻化する
  • ワークロードのプロンプト長分布がPrefillリソース消費に与える影響を考慮したPTU見積もり
  • TTFT/TPOTの2軸SLO設計による運用アラートの最適化

今後の研究方向として、著者らは動的なPrefill/Decode比率調整やエネルギー効率を考慮したリソース配分を挙げている。

参考文献


:::message この記事はAI(Claude Code)により自動生成されました。論文の内容は原著者の主張を要約・解説したものであり、本記事の著者が独自に実験を行ったものではありません。正確な数値・詳細は原論文をご確認ください。 :::

この投稿は CC BY 4.0 でライセンスされています。

論文解説: CoALA — 認知アーキテクチャに基づくLLMエージェントのメモリ分類体系

論文解説: RAGCache — RAG向けKVキャッシュでTTFTを最大4倍高速化