Mooncake: A KVCache-Centric Disaggregated Architecture for LLM Serving

framework 2407.00079
disaggregated-servingkv-cacheprefill-decode-separationdistributed-inference

§1 TL;DR #

Mooncake 是 Kimi 的生产推理平台,以 KVCache 为调度核心将 prefill 与 decode 分离到独立集群,利用 CPU DRAM/SSD 构建分布式 KVCache 池实现 prefix 复用,并通过预测式 early rejection 应对过载。在真实负载下多处理 75% 请求,模拟长上下文场景吞吐提升达 525%。

§2 痛点 / 方法 / 结果 #

Q1 痛点 #

LLM 推理中 prefill 和 decode 阶段资源特征截然不同:prefill 计算密集且随输入长度超线性增长,decode 访存密集且受限于 KVCache 容量。传统耦合部署(如 vLLM)中长上下文 prefill 严重干扰 decode 的 TBT,且 GPU VRAM 不足以缓存大量 prefix KVCache。更关键的是,Kimi 等 MaaS 服务长期处于过载状态,GPU 扩容速度远低于请求增长,如何在 SLO 约束下最大化 goodput 是核心挑战。

Q2 方法 #

KVCache-centric disaggregated architecture

  1. Prefill-decode 分离:独立的 prefill 和 decode 实例池,Conductor 全局调度器统一分配请求。
  2. 分布式 KVCache 池:利用 GPU 集群中闲置的 CPU DRAM 和 SSD 作为 KVCache 存储层,通过 GPUDirect RDMA(Messenger 组件)高速传输;哈希去重实现 prefix 复用。
  3. Chunked Pipeline Parallelism (CPP):将长上下文 prefill 的输入切分为 chunk,在多节点上流水线并行执行,仅在 pipeline stage 边界通信——对比 SP 方案通信量更小且无需动态弹性调度。
  4. Layer-wise prefill:逐层完成 attention 后立即异步传输 KVCache 到 decode 节点的 CPU 内存,与计算重叠,使 prefill 阶段 VRAM 占用降至单请求级别。
  5. KVCache-centric scheduling (Algorithm 1):对每个请求,遍历 prefill 实例估算 TTFT(= 队列等待 + prefix 传输 + 增量 prefill 时间),选择最优 (prefill, decode) 实例对;超过 SLO 阈值直接拒绝(HTTP 429)。
  6. Cache load balancing:启发式热点迁移——当负载高的实例有更长 prefix 匹配时,如果传输代价 < 重算代价则主动复制 KVCache 块,自动均衡热点分布。
  7. Prediction-based early rejection:在 prefill 开始前预测 decode 阶段负载,避免已完成 prefill 的请求在 decode 侧被拒绝而浪费算力;系统级预测假设统一 $t_d$,缓解 prefill/decode 负载反相振荡。
  8. 核心技术壁垒:KVCache 热点的自动启发式迁移——无需全局使用量预测模型,仅在调度决策时触发增量复制,将 cache-aware scheduling 与 load balancing 融为一体。这是生产环境中让 prefix caching 真正可用的关键工程洞察。

    Q3 结果 #

    • 模拟 128K 长上下文:吞吐提升 525%(对比 vLLM,同 SLO 约束)
    • 公开数据集 ArXiv/L-Eval:20%–40% 吞吐提升
    • 真实负载(10P+10D vs vLLM 20M):多处理 75% 请求;vLLM TBT SLO 达标率仅 57%,Mooncake 接近 100%
    • 过载场景:prediction-based early rejection 将拒绝数从 4183 降至 3589

    §3 架构 / 方法图 #

    sequenceDiagram participant Client participant Conductor as Conductor (Global Scheduler) participant PP as Prefill Pool (CPP Groups) participant KV as CPU DRAM KVCache Pool participant Msg as Messenger (RDMA) participant DP as Decoding Pool Client->>Conductor: Request (tokenized) Conductor->>Conductor: Algorithm 1: select (p, d) pair
    cache-aware + load-balance + SLO check alt SLO unachievable Conductor-->>Client: HTTP 429 (reject) else Accept Conductor->>PP: Dispatch to prefill instance p KV->>PP: Load reusable prefix KVCache (RDMA) PP->>PP: Incremental prefill (CPP if long) PP->>KV: Store new KVCache blocks PP->>Msg: Trigger layer-wise KVCache transfer Msg->>DP: Stream KVCache to decode node d (RDMA) DP->>DP: Join continuous batching DP-->>Client: Stream output tokens end

    系统组件

    • Conductor:全局调度器,维护所有实例的 prefix cache 索引和负载状态,执行 Algorithm 1 做请求分配。
    • Prefill Pool:每 X 节点组成一个 CPP 流水线组,处理长上下文 prefill。支持逐层 KVCache 流式传输以最小化 VRAM 占用。
    • CPU DRAM KVCache Pool:分页存储 KVCache block,每个 block 附带 prefix hash 用于去重。使用 LRU 淘汰,热点 block 自动复制到多节点。
    • Messenger:独立进程,管理跨机 RDMA 传输,异步与 prefill 计算重叠。
    • Decoding Pool:连续批处理 decode,从 CPU DRAM 异步加载 KVCache。

    §4 作者证明 #

    记号表 #

    符号含义
    $P$Prefill 实例池
    $D$Decoding 实例池
    $R$当前请求
    $B$Cache block size (= 512 tokens)
    $T_{queue}$估计的 prefill 排队时间
    $T_{prefill}$估计的 prefill 执行时间
    $T_{transfer}$估计的 KVCache 传输时间
    $l_{ttft}$, $l_{tbt}$TTFT / TBT SLO 阈值
    $t_d$假设的统一 decode 时长(系统级预测)

    Algorithm 1 物理意义 #

    调度算法的核心是 最小化 TTFT:对每个 prefill 实例计算 TTFT = 排队时间 + 传输时间(如需跨机复制 prefix)+ prefill 执行时间。选择全局 TTFT 最小的实例。关键阈值 kvcache_balancing_threshold 控制是否跳过 cache 最长匹配而直接在负载较低实例重算:当本地 prefix / 远程 prefix 比值超过阈值时,优先就地计算(避免传输开销),并触发热点迁移。

    6 项检查 #

    1. TTFT/TBT 定义可操作:$\text{TTFT}_{P90} = 10\times$,$\text{TBT}_{P90} = 5\times$ 基线(单请求无干扰)——定义清晰、可测量。
    2. Goodput 定义严格:仅完整执行的请求计入 goodput,部分执行 = 全部浪费。
    3. TTFT 估计方法:离线测试拟合 prefill 执行时间模型,误差小(计算模式规律);队列时间 = 累加队列中所有请求的 prefill 时间。
    4. Cache 命中率实测:真实 trace 下最高 ~50%(Table 1),LRU 表现最佳。
    5. CPP vs SP 定性论证:CPP 仅在 pipeline stage 边界通信,可与 KVCache 传输带宽共存;SP 每层需跨节点通信,竞争网络资源。缺少定量对比。
    6. 系统级预测的粗糙性:假设统一 $t_d$ 是明确的简化,论文承认 request-level prediction 留作未来工作。
    7. 无形式化吞吐/延迟解析模型 — Algorithm 1 是启发式调度,不存在 closed-form throughput 公式。论文仅在 §7.4 给出系统级负载预测框架。

      §5 实验与数据 #

      端到端性能 #

      数据集特征(Table 2)

      DatasetAvg InputAvg OutputCache RatioPattern
      ArXiv Summarization8088229~0%Poisson
      L-Eval1901972>80%Poisson
      Simulated (16k–128k)16k–128k51250%Poisson
      Real Data7955194~50%Timestamp

      关键结果

      • 公开数据集(4 实例,Mooncake [3P+1D] vs vLLM [4M]):ArXiv +20% throughput,L-Eval +40%。Mooncake [2P+2D] 因 prefill/decode 比例失衡 TTFT 反而更差。
      • 模拟长上下文(同集群,50%–525% throughput 提升,Figure 12):128K 场景下 vLLM 几乎无法服务,Mooncake 仍维持高吞吐——disaggregation 彻底隔离了 prefill 对 decode 的干扰。
      • 真实负载(10P+10D vs vLLM 20M,Figure 13):TTFT 分布基本相同;TBT SLO 达标率 Mooncake ~100% vs vLLM 57%。多处理 75% 请求。

      过载实验(Table 3) #

      StrategyRejected Requests
      Baseline (prefill+decode 前判断)4183
      Early Rejection3771
      Prediction-based Early Rejection3589

      Prediction-based 方案通过减少反相振荡提升有效处理能力。

      调度策略消融(Figure 8) #

      KVCache-centric scheduling(cache-aware + load balancing + 热点迁移)在 TTFT 和 SLO 达标率上均显著优于 random、load-balancing、仅 cache-aware 方案。

      §6 论证链 #

      StepClaimEvidenceStrength
      1Prefill 与 decode 资源特征不同,耦合部署互相干扰Figure 2 (prefill 超线性 / decode 亚线性); vLLM TBT SLO 仅 57% (Fig 13)Strong — 定量验证
      2Disaggregation + 分布式 KVCache 池可利用闲置 CPU DRAM 实现高效 prefix cachingTable 1 (cache 命中率 30%–51%); Architecture (Fig 1, 3, 4)Medium — cache 命中率上限 50%,收益有天花板
      3CPP 优于 SP 用于多节点 prefill定性论证 (通信量更小、无需弹性调度); 无定量对比Weak — 缺少 head-to-head benchmark
      4Layer-wise prefill 使 VRAM 占用降至单请求级别Figure 7 (latency breakdown); 定性论证Medium — 展示了 overlap 效果但未量化 VRAM 节省量
      5KVCache-centric scheduling 优于简单调度策略Figure 8 (4 种策略消融)Strong — controlled experiment
      6Prediction-based early rejection 缓解反相振荡Figure 9, 10 (负载曲线); Table 3 (减少 14% 拒绝)Medium — 改进幅度有限(4183→3589),系统级预测粗糙
      7端到端:Mooncake 在长上下文和真实负载下大幅超越 vLLMFigures 11–13; Table 3Strong — 多场景验证

      §7 实现 cross-reference #

      • 开源仓库:https://github.com/kvcache-ai/Mooncake(包含 trace 数据和调度代码)
      • 评测使用 dummy model(LLaMA2-70B 架构),非生产模型权重
      • Testbed: 8×A800-SXM4-80GB per node, RDMA 800 Gbps inter-node
      • 所有实验基于 replayed trace(23,608 entries, 1-hour sample)

      关键实现细节

      1. Hash-based prefix dedup:block size = 512 tokens,每个 block 的 hash 包含自身 token 内容和所有前驱 block 的 hash,形成 prefix chain。这与 vLLM 的 radix tree 不同——hash 方案适合分布式场景(无需共享树结构)。
      2. Layer-wise KVCache streaming:prefill 每层 attention 完成后立即 async store 到 CPU DRAM,并触发下一层 async load。关键约束:prefill 实例 VRAM 只需容纳单请求的单层 KVCache + 模型权重。
      3. 核心技术壁垒(§2 补充)

        启发式热点迁移的工程 insight 在于:不需要全局 popularity 预测(动态负载下预测不可靠),而是在每次调度决策时判断"远程最长 prefix 匹配是否值得传输",如果值得但当前实例负载高,则让备选实例主动拉取 cache block。这个机制同时完成了 cache replication 和 load balancing,是 Mooncake 能在生产中稳定运行的关键。

        框架特定分析 #

        系统范围 #

        • 阶段覆盖:prefill + decode,两阶段分离部署
        • Serving 模式:continuous batching(decode 端),chunked pipeline(prefill 端)
        • 并行维度:prefill 内 TP(单节点)+ CPP(跨节点);decode 端 TP
        • 部署模式:多节点 disaggregated prefill-decode

        调度与资源管理 #

        • 调度粒度:request-level(全局 Conductor 为每个请求选择实例对)
        • 抢占策略:无抢占,SLO 违反时直接拒绝
        • 过载策略:prediction-based early rejection(系统级负载预测)
        • 公平性:无显式 per-tenant 保证(论文 §10 提及未来方向)
        • KVCache 管理:分页存储,LRU 淘汰,hash 去重,启发式热点复制
        • Swap:KVCache 存储在 CPU DRAM(主存储层),不使用 GPU-side swap

        胜负场景 #

        Workload RegimeMooncakevLLMWhy
        短 prompt, 低并发持平或略差基线disaggregation overhead 无收益,[2P+2D] 比例失衡会更差
        长 prompt (≥16K), 中/高并发50%–525% 吞吐提升受 TBT 干扰严重prefill 不再阻塞 decode;CPP 降低 TTFT
        高 prefix 复用 (L-Eval >80%)40% 提升无分布式 prefix cache分布式 KVCache 池 + cache-aware scheduling
        过载 (请求量 >> 容量)多处理 14% 请求大量浪费(先 prefill 后 reject)prediction-based early rejection

        部署上下文 #

        • Serving stage:prefill + decode 全覆盖的编排层
        • 硬件亲和性:A800/H800 集群,依赖 RDMA 网络
        • 生态集成:独立系统,非 vLLM/SGLang 插件(但 acknowledge vLLM 社区)
        • 迁移路径:需替换整个 serving stack,引入 Conductor 全局调度 + 分布式 KVCache 基础设施