> [!abstract] 概要(arXiv abstract の日本語訳)
> Mooncake は Moonshot AI が提供する主力 LLM サービス Kimi のサービングプラットフォームである。
> Prefill クラスタと Decoding クラスタを分離した KVCache 中心の分散アーキテクチャを特長とする。
> また GPU クラスタ内で活用されていない CPU・DRAM・SSD リソースを利用し、KVCache の分散キャッシュを実装する。
> Mooncake の中核はその KVCache 中心スケジューラであり、全体的な有効スループットの最大化と、レイテンシに関するサービスレベル目標(SLO)の遵守を両立する。
> 全リクエストが処理されることを前提とする従来研究とは異なり、Mooncake は高過負荷シナリオという特有の課題に直面している。
> これを緩和するため、我々は予測ベースの早期拒否ポリシーを開発した。
> 実験により、Mooncake は長コンテキストシナリオで優れた性能を示すことが分かった。
> ベースライン手法と比べて、特定の模擬シナリオでは SLO を遵守しながらスループットを最大 525% 向上させることができる。
> 実ワークロードでは、Mooncake の革新的なアーキテクチャにより Kimi は 75% 多いリクエストを処理できるようになった。
## 論文情報
- **タイトル**: Mooncake: A KVCache-centric Disaggregated Architecture for LLM Serving
- **著者**: [[Ruoyu Qin]]・[[Zheming Li]]・[[Weiran He]]([[Moonshot AI]]), [[Mingxing Zhang]]・[[Yongwei Wu]]・[[Weimin Zheng]]([[Tsinghua University]]), [[Xinran Xu]]([[Moonshot AI]])
- 対応著者: [[Mingxing Zhang]](
[email protected])・[[Xinran Xu]](
[email protected])
- Preprint Tech Report by Moonshot AI and MadSys @ Tsinghua
- **媒体**: arXiv プレプリント
- **arXiv ID**: 2407.00079 (v4: 2025-09-03)
- **コード/データ**: https://github.com/kvcache-ai/Mooncake (オープンソース実リクエストトレース)
## 概要
[[Moonshot AI]] の Kimi サービス向けに設計された LLM サービングプラットフォーム Mooncake の技術報告である。Prefill・KVCache・Decode の 3 プールに分離した分散アーキテクチャで、CPU/DRAM/SSD の余剰資源を活用した分散 KVCache プールを核心とする。全体スケジューラ Conductor が KVCache 分布とワークロードに基づいてリクエストをディスパッチし、過負荷シナリオでの早期拒否も担当する。
## 問題設定
**入力**:
- 多様な入力/出力長・到着頻度・SLO 要件(主に TTFT と TBT)を持つ LLM リクエスト
- GPU クラスタの限られた VRAM・CPU/DRAM/SSD・RDMA 帯域
**出力**: 有効スループット(Goodput)を最大化しつつ TTFT/TBT SLO を満たすリクエストスケジューリング
**前提条件**:
- MaaS(Model as a Service)プロバイダの視点。GPU 資源は制限的で弾力的追加は困難
- LLM はデコーダのみの Transformer(GPT・LLaMA 系)
- Prefill は計算バウンド(注意計算が入力長の二乗で増加)、Decode はメモリバウンド(1 トークンずつ自己回帰生成、バッチサイズで準線形)
**なぜ問題か**:
- Prefill(TTFT 支配)と Decode(TBT 支配)は資源特性が異なるため同一 GPU 同居は干渉を生む
- KVCache の再利用(重複計算削減)と大バッチ集約(MFU 向上)はトレードオフ
- 過負荷時は不完全な処理で消費した計算資源が無駄になる
## 提案手法
### アーキテクチャ全体(図 1)
3 プールに分離:
1. **Prefill Pool**: Prefill インスタンス群。ローカル CPU/DRAM の分散 KVCache プールを持つ
2. **KVCache Pool**: ノード間の RDMA ベース KVCache 転送。Messenger サービスが管理
3. **Decoding Pool**: Decode インスタンス群。ローカル CPU/DRAM の分散 KVCache プールを持つ
全体スケジューラ **Conductor** がリクエストを受け取り、Prefill インスタンスと Decode インスタンスのペアを選択して 4 ステップで処理:
1. **KVCache Reuse**: 選択した Prefill インスタンスがリモート CPU メモリからプレフィックスキャッシュを GPU にロード
2. **Incremental Prefill**: Prefill が実行され、新生成の増分 KVCache を CPU メモリへストア
3. **KVCache Transfer**: Messenger がノード間 RDMA で Decode インスタンスの CPU DRAM へ転送(非同期・Prefill と重畳)
4. **Decoding**: Decode インスタンスが continuous batching でトークン生成
### KVCache プールの設計(図 3)
- CPU メモリにページ化ブロックとして KVCache を保存。LRU/LFU/LengthAwareCache などで退避
- **ブロックハッシュ**: トークンブロックを先行ブロックのハッシュも含めてハッシュ化 → 重複除去と前置キャッシュの一致判定。`A=Hash(a)`, `B=Hash(A+b)`, ... の連鎖
- GPUDirect RDMA ベースの Messenger が CPU-GPU 間・ノード間転送を担当
実データ分析(23,608 件 Kimi トレース): 平均入力 7,590 トークン、平均出力 182 トークン、平均入出力比 720。ブロック人気度の不均一性が顕著で、50% 超のブロックが未使用の一方、一部ブロックは数万回アクセスされる(図 6)。
キャッシュ容量実験(表 1): 50,000 ブロックで約 50% ヒット率(LRU 最良)。容量増加の効果は逓減。
### Prefill プールの実装(§5)
**Chunked Pipeline Parallelism(CPP)** — 長コンテキスト Prefill の複数ノード並列化:
- X ノードをパイプライン化した Prefill グループに編成
- リクエストの入力トークンを prefill_chunk(通常 1000 トークン超)以下のチャンクに分割し、異なるノードが同時処理
- シーケンス並列(SP)との比較: SP は Ring Attention で層ごとに少なくとも 1 回の通信を要するが、CPP はパイプライン段境界のみの通信で済み、MFU が高く KVCache 転送とのネットワーク競合が少ない
- 短コンテキストでもオーバーヘッドなし(動的ノード再分割不要)
**Layer-wise Prefill** — VRAM 使用量の最小化:
- Prefill は層ごとの処理なので、KVCache のロード/ストアを各層の注意計算と非同期に重畳できる
- 各層の注意計算前に非同期ロード完了を待ち、計算後に非同期ストアを起動
- 効果: VRAM に単一リクエスト分が収まればよく、Prefill スケジューリングで DRAM 空き量のみ考慮すればよくなる(図 7: 128k シーケンスで層別ストア遅延が大幅削減)
### KVCache 中心スケジューリング(§6)
**キャッシュ考慮 Prefill スケジューリング(Algorithm 1)**:
1. リクエストのトークンをブロック化してハッシュキーを計算
2. 各 Prefill インスタンスとのプレフィックス一致長(`prefix_len`)を照合
3. 各インスタンスについて TTFT = キュー待ち時間 + Prefill 実行時間 を推定
- ベスト一致との差が閾値以内: ローカルで計算
- 閾値超: リモートから KVCache 転送して最長プレフィックスのインスタンスで実行
4. 推定 TTFT が最小のインスタンスを選択。SLO 違反が予測される場合は HTTP 429 で即座に拒否
**ホットスポットマイグレーション(KVCache ロードバランシング)**:
- グローバルな将来使用予測なしに、リクエストルーティングの副作用としてホットブロックを自動複製
- 代替インスタンスへの転送コストが追加 Prefill 時間より小さい場合に KVCache を転送・ローカル保存
- 結果: ホットブロックが複数ノードに自然に分散し、転送輻輳を回避
**ロードバランシング Decode スケジューリング**: TBT SLO を満たす最も負荷の低い Decode インスタンスを選択。局所スケジューラが Prefill 後に SLO を再確認し、状況変化があれば拒否
### 過負荷指向スケジューリング(§7)
**Early Rejection**:
- Prefill 後に Decode が拒否すると Prefill の計算資源が無駄になる
- 解決策: リクエスト到着時に Prefill・Decode 両プールの負荷を予測し、重い方を基準に早期拒否
**負荷変動問題(図 9, 10)**:
- Early Rejection を単純実装すると Prefill/Decode 間で逆位相振動が発生(図 9: 20 分観測で顕著)
- 原因: Decode 負荷の予測と実行の間の時間差。Prefill が満杯→Decode が満杯→Prefill が閑散→Decode が閑散のサイクル
**予測ベース Early Rejection**:
- 各リクエストのデコードが均一時間 t_d かかると仮定し、指定時刻における Decode 負荷を推定
- システムレベル予測(バッチカウント/TBT 比率)でリクエストレベル出力長予測の困難を回避
- 結果(表 3): ベースライン 4,183 件拒否 → Early Rejection 3,771 件 → 予測ベース 3,589 件に削減
## 実験設定
- **テストベッド**: 各ノードに NVIDIA A800-SXM4-80GB × 8(NVLINK)、RDMA 800 Gbps、LLaMA2-70B 同構成のダミーモデルで実験
- **データセット**(表 2): ArXiv Summarization(avg 入力 8,088 / 出力 229)、L-Eval(avg 入力 19,019 / 出力 72 / キャッシュ率 > 80%)、模擬データ(16k〜128k プロンプト / 出力 512 / キャッシュ率 50%)、実データ(avg 入力 7,955 / 出力 194 / キャッシュ率約 50%)
- **比較対象**: vLLM(continuous batching + PagedAttention。Prefill/Decode を同居)
- **評価指標**: P90 TTFT・P90 TBT(SLO 倍率として正規化)、SLO 遵守下での最大 RPS
## 実験結果
**公開データセット(図 11, Mooncake-[3P+1D] vs vLLM-[4M])**:
- ArXiv Summarization: スループット 20% 向上(同じ SLO を遵守しながら)
- L-Eval: スループット 40% 向上(長文でのプレフィックスキャッシュ効果も寄与)
**模擬データ(図 12, 16k〜128k プロンプト)**:
- 16k: 50% 向上、32k: ~100% 向上、64k: ~200% 向上、128k: 最大 525% 向上
- vLLM は長コンテキストでバッチ処理を断念して 1 件ずつ処理、Mooncake は常にバッチ処理可能
**実ワークロード(図 13, Mooncake-[10P+10D] vs vLLM-[20M])**:
- TBT SLO(0.1 s/token): Mooncake ≈ 100% 達成、vLLM ≈ 57% のみ達成
- TTFT SLO(30 s): 両者とも ≈ 100% 達成
- Mooncake は同 SLO 遵守下で 75% 多いリクエストを処理
**Prefill スケジューリング比較(図 8, 8P+8D, 2.3 万件)**:
- random: 平均 TTFT 92.07 s
- load-balance: 60.41 s
- cache-aware: 14.36 s
- KVCache-centric(ホットスポット込み): **6.26 s**(SLO 内に収まる唯一の戦略)
## 考察
- **Mooncake の長コンテキスト優位性は CPP + Layer-wise Prefill + PD 分離の組み合わせ**: vLLM は長コンテキストで Prefill が Decode バッチを阻害するが、Mooncake は Prefill プールを隔離することでこの干渉をゼロにする。さらに CPP でノード並列化し、Layer-wise で VRAM 占有を最小化する
- **KVCache のホットスポット分布を精密予測せずに扱う**: システム全体のワークロード予測は高精度を要求するが、Mooncake のヒューリスティック・ホットスポットマイグレーションはリクエストルーティングの副作用として自然に複製を達成する
- **過負荷シナリオは PD 分離に固有の問題を生む**: 非分離システムでは Prefill/Decode が同一 GPU なので、拒否のタイミングが単純。分離では Prefill 完了後に Decode が拒否するという 2 段階問題になる
- **制限・課題**: prefill_chunk は手動設定(将来は適応制御)。P/D 比率は事前設定が必要で動的調整は今後の課題。出力長予測に基づくリクエストレベル Early Rejection は未実装。理論的最大再利用率は約 50%(現ワークロード)
## 強み / 弱点・課題
**強み**:
- 実運用 Kimi サービスからの実証。23,608 件の実リクエストトレースをオープンソース公開
- CPU/DRAM/SSD をメモリ階層として活用する具体的な実装。KVCache のハッシュベース重複除去
- 過負荷問題(一般的な LLM サービング研究が無視する)を体系的に定式化・解決
**弱点/課題**:
- prefill_chunk・kvcache_balancing_threshold は手動調整
- Prefill/Decode インスタンス比率は静的。動的な弾力的変換は今後の課題
- 実験はすべて LLaMA2-70B ダミーモデル。実モデルでの検証なし(プロプライエタリ情報保護のため)
- リクエストレベル出力長予測は将来課題