> [!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 ダミーモデル。実モデルでの検証なし(プロプライエタリ情報保護のため) - リクエストレベル出力長予測は将来課題