Mooncake: Trading More Storage for Less Computation — A KVCache-Centric Architecture for Serving LLM Chatbot
Mooncake: Trading More Storage for Less Computation — A KVCache-Centric Architecture for Serving LLM Chatbot
发表时间: 2025-02 · FAST 2025
原文: https://www.usenix.org/system/files/fast25-qin.pdf
作者/机构:Ruoyu Qin, Zheming Li, Weiran He, Jialei Cui, Xinran Xu (Moonshot AI); Feng Ren, Mingxing Zhang, Yongwei Wu, Weimin Zheng (Tsinghua University)
速读
一句话结论 本文提出了以 KVCache 为中心的 LLM 推理分离架构 MOONCAKE,通过构建全局分布式缓存池,以增加存储和网络传输开销为代价换取预填充计算量的减少,在满足严格延迟指标的前提下,将真实长上下文对话负载的有效请求容量提升了最高 498%。
要解决什么问题 现代 LLM 服务需要同时满足首字延迟(TTFT)和字间延迟(TBT)的严格服务等级目标。为了降低 TTFT,现有的常规做法是缓存并复用历史 KVCache,但这种缓存通常被局限在单机的 HBM 和 DRAM 中。由于单机内存容量极其有限,在面对多轮对话和长上下文请求时,单机缓存最多只能支撑理论缓存命中率的 50%,大量本可复用的前缀缓存被频繁驱逐。这导致系统必须对长文本进行大量重复的预填充计算,严重消耗 GPU 算力。此外,预填充阶段是计算密集型,而解码阶段是访存密集型,如果强行在同一节点混合调度,长文本的预填充会严重抢占资源,导致解码的 TBT 出现巨大波动。因此,原有的单机缓存和计算耦合架构卡在了缓存容量不足与计算资源争抢这两个机制瓶颈上,无法在保证延迟指标的同时提升整体吞吐量。
怎么做的 核心思路是“以空间换时间”,将预填充和解码节点物理分离,并整合整个 GPU 集群的 CPU、DRAM、SSD 和 RDMA 网络资源,构建出一个 PB 级的全局分布式 KVCache 存储池。这种设计能绕开单机缓存容量瓶颈,只要网络传输时间小于重新计算的时间,跨节点拉取缓存就是划算的。具体而言,当网络加载带宽 $B$ 和 GPU 计算吞吐量 $G$ 满足以下条件时,全局缓存复用就能在数学上保证降低 TTFT:
$$ \frac{B}{G} > \frac{2ds}{gqa \times (apd + bd^2)} $$关键设计由三个部件构成。首先是全局调度器 Conductor,它在预填充阶段基于 KVCache 感知进行调度,不仅评估各节点的排队负载,还计算请求在各节点的缓存匹配长度,将请求分发到预估总 TTFT(传输时间加排队时间加预填充时间)最短的节点。其次是底层分布式缓存系统 MOONCAKE Store,负责管理分页缓存块,并通过启发式热点迁移策略,自动将高频访问的 KVCache 块复制到多个节点以避免单点网络拥塞;它还实现了一个拓扑感知的 RDMA 传输引擎,以极低延迟在节点间流式传输 KVCache。最后是分块流水线并行(CPP)机制,针对超长上下文,系统没有采用通信频繁的序列并行,而是将长输入切分为多个块,在多个预填充节点间进行流水线处理,仅在阶段边界通信,从而在降低 TTFT 的同时减少对 KVCache 传输网络的带宽争抢。
效果如何 实验基于 LLaMA3-70B 模型架构,在由 16 个 8x A800 GPU 节点(配备 200 Gbps RDMA 网卡)组成的集群上进行,测试数据包含真实对话、工具调用以及合成长文本负载。对比基线为开源系统 vLLM(代表传统的预填充与解码耦合路线)、开启前缀缓存的 vLLM(代表单机本地缓存路线)以及开启分块预填充的 vLLM(代表单机缓解计算干扰路线)。量化结果显示,在长上下文的真实对话负载下,MOONCAKE 在满足 30 秒 TTFT 和相应 TBT 限制的前提下,有效请求容量比基线方法提升了 59% 到 498%。在缓存效率方面,全局缓存设计使命中率比本地缓存最高提升了 2.36 倍,从而节省了高达 48% 的预填充 GPU 计算时间。其底层的 RDMA 传输引擎在 40GB 数据传输测试中,速度比传统 TCP 方案快 2.4 到 4.6 倍。在实际部署中,该架构使 Kimi 在 A800 和 H800 集群上的请求处理量分别增加了 115% 和 107%。该方法的代价是高度依赖底层网络基础设施,作者承认的局限性在于:当集群节点间的可用网络带宽低于 100 Gbps 时,跨节点传输缓存的延迟会急剧上升,导致严重的网络拥塞和 TTFT 劣化,此时系统的整体性能将大打折扣。
主要贡献
随着大型语言模型(LLM)在各种场景中的快速普及,LLM服务的计算工作负载变得显著多样化。这些工作负载在输入/输出长度、到达分布上存在差异,更重要的是,它们要求不同种类的服务等级目标(SLOs)。作为模型即服务(MaaS)提供商,Moonshot AI开发的Kimi聊天机器人面临的主要优化问题是在满足多重复杂约束(主要是首字延迟TTFT和字间延迟TBT等SLO要求)的同时,最大化整体有效吞吐量以保障收入。
为了实现这一目标,本文提出了MOONCAKE服务平台。其核心创新点如下:
1. 以KVCache为中心的解耦架构:不仅分离了Prefill(预填充)和Decoding(解码)集群,还巧妙地利用了GPU集群中未被充分利用的CPU、DRAM、SSD和NIC资源,建立了一个名为MOONCAKE Store的解耦分布式KVCache池。这体现了“用更多存储换取更少计算”的设计原则。
2. KVCache感知的全局调度器(Conductor):设计了一个全局调度器,在遵守严格的延迟SLO的前提下,通过感知KVCache的分布和匹配长度,最大化吞吐量并平衡实例负载。
3. 针对长上下文的分块流水线并行(CPP):在Prefill池中引入了分块流水线并行机制,以无缝处理动态分布的长上下文请求,减少网络消耗并简化弹性扩展的需求。
4. 高度优化的RDMA传输引擎:实现了一个支持多网卡、拓扑感知和端点池化的高性能零拷贝传输引擎,以满足海量KVCache在节点间的高速传输。
实验表明,MOONCAKE在处理长上下文输入的场景中表现优异。在真实工作负载测试中,MOONCAKE在满足SLO的情况下,有效请求容量比基线方法提高了$59\% \sim 498\%$。目前,MOONCAKE已在数千个节点上运行,每天处理超过1000亿个Token,在实际部署中使Kimi在A800和H800集群上的请求处理量分别提升了$115\%$和$107\%$。
背景知识与设计原则
LLM服务的服务等级目标:现代大型语言模型(LLMs)基于Transformer架构,利用注意力机制和多层感知机(MLP)处理输入。流行的模型(如GPT和LLaMA)采用仅解码器(decoder-only)结构。每个推理请求在逻辑上分为两个阶段:预填充(prefill)阶段和解码(decoding)阶段。在预填充阶段,所有输入Token被并行处理,计算密集度高。此阶段生成第一个输出Token,同时存储计算出的键和值的中间结果,即KVCache。随后解码阶段利用此KVCache自回归地生成新Token。由于自回归生成的限制,解码阶段每批次只能处理一个Token,这使得它受限于内存带宽,且计算时间随批处理大小呈次线性增长。因此,解码阶段广泛采用连续批处理(continuous batching)优化。由于这两个阶段的特性不同,MaaS提供商设定了不同的指标来衡量其SLO:预填充阶段主要关注请求到达至生成第一个Token的延迟(TTFT);解码阶段则关注同一请求连续生成Token之间的延迟(TBT)。在实际部署中,为了在不增加硬件的情况下缓解集群负载,系统会主动拒绝预测无法满足SLO的请求。主要目标是在遵守SLO的前提下最大化整体吞吐量(goodput)。
用更多存储换取更少计算:为了满足严格的SLO,一种普遍采用的解决方案是缓存之前生成的KVCache,并在发现前缀匹配时复用它。然而,现有方法通常将缓存限制在本地HBM和DRAM中,认为全局调度所需的传输带宽过高。但正如后文所述,本地DRAM的容量仅能支持高达$50\%$的理论缓存命中率,因此全局缓存设计至关重要。本文基于表1中的符号和LLaMA3-70B的具体参数进行了数学分析。由于当前流行的LLM是自回归语言模型,每个Token的KVCache仅依赖于其自身和前面的Token。因此,对应于相同输入前缀的KVCache可以被复用而不影响输出精度。如果当前长度为$n$的请求提示与先前缓存的KVCache共享长度为$p$的公共前缀,其预填充过程可优化为:
$q[p:n], k[p:n], v[p:n] = \mathrm{MLP}(hidden[p:n])$
$k[1:n], v[1:n] \leftarrow \mathrm{KVCache} + (k[p:n], v[p:n])$
$o[p:n] = \mathrm{Attention}(q[p:n], k[1:n], v[1:n])$
$\mathrm{KVCache} \leftarrow (k[1:n], v[1:n])$
给定输入长度$n$,预填充阶段的FLOPS可计算为:
$flops(n) = l \times (an^2d + bnd^2)$
因此,复用KVCache大约能减少$l \times (ap^2d + bpd^2)$的预填充计算成本。然而,这需要将缓存的KVCache传输到预填充GPU的HBM中,其大小为$p \times l \times (2 \times d / gqa) \times s$。假设平均计算吞吐量为$G$,平均KVCache加载速度为$B$(由$B_{h2d}$和$B_{nic}$的最小值决定),如果满足以下条件,复用KVCache在TTFT方面是有益的:
$\frac{B}{G} > \frac{2ds}{gqa \times (apd + bd^2)}$
在这些场景中,复用KVCache不仅减少了GPU时间和成本,还通过改善TTFT提升了用户体验。对于更大的$d$值(与模型大小成正比),带宽$B$相对于计算吞吐量$G$的要求更容易满足。例如,在$8 \times \mathrm{A800}$ GPU机器上运行LLaMA3-70B,假设前缀长度为8192,公式2得出所需的最小$B$为$6 \mathrm{GB/s}$。对于$8 \times \mathrm{H800}$机器,$B$的需求将扩大到$19 \mathrm{GB/s}$。在实际场景中,由于传输阶段无法完美重叠,实际带宽需求更高。但正如后文实验所示,每个NVIDIA A800 HGX网络中充分利用的100 Gbps网卡足以满足这些标准。
| Notation | Description | Value |
|---|---|---|
| l | Num layers | 80 |
| d | Model dimension | 8192 |
| a,b | Constant coefficients in Equation 1 | 4,22 |
| gqa | Num q heads / Num kv heads | 8 |
| S | Tensor element size | 2B (BFloat16) |
| G | GPU computation throughput | 8×312TFLOPS |
| Bh2d | Host-to-device bandwidth | 128GB/s |
| Bnic | NIC bandwidth | 800 Gbps |
| n,p | Prompt and matched prefix length, respectively |
表 1:符号和参数。模型和机器参数根据 LLaMA3-70B 和 8×A800 设置。
方法细节
MOONCAKE架构概览:如图2所示,MOONCAKE采用了解耦架构,不仅将Prefill节点与Decoding节点分离,还将GPU集群的CPU、DRAM、SSD和RDMA资源组合起来,实现了解耦的KVCache。为了调度所有这些解耦的组件,MOONCAKE在其中心实现了一个名为Conductor的全局调度器。Conductor负责根据当前KVCache的分布和工作负载特征来分发请求。MOONCAKE Store则负责管理这些KVCache块的存储和传输。
请求处理工作流:具体而言,图3展示了请求的典型工作流。分词(tokenizing)完成后,Conductor选择一对Prefill节点和一个Decoding节点,并启动包含四个步骤的工作流:1) KVCache复用:选定的Prefill节点(组)接收包含原始输入、可复用的前缀缓存块键以及分配给该请求的完整缓存块键的请求。它根据前缀缓存块键从远程CPU内存将前缀缓存加载到GPU内存中以引导请求。如果没有前缀缓存,则跳过此步骤。此选择平衡了三个目标:尽可能多地复用KVCache、平衡不同Prefill节点的负载、以及保证TTFT SLO。2) 增量Prefill:Prefill节点使用前缀缓存完成Prefill阶段,并将新生成的增量KVCache存储回CPU内存。如果未缓存的输入Token数量超过某个阈值(通常大于1000 Tokens,以充分利用GPU算力),则Prefill阶段将被分成多个块并以流水线方式执行。3) KVCache传输:MOONCAKE Store部署在每个节点中以管理和传输这些缓存。此步骤异步执行,并与上述增量Prefill步骤重叠,将每个模型层生成的KVCache流式传输到目标Decoding节点的CPU内存中以减少等待时间。4) 解码:所有KVCache在Decoding节点的CPU内存中接收完毕后,请求以连续批处理的方式加入下一个批次。Decoding节点由Conductor根据其当前负载预先选择,以确保不违反TBT SLO。
KVCache管理:在MOONCAKE Store中,所有KVCache作为分页块(paged blocks)存储在分布式缓存池中。块大小(即每个块包含的Token数量)由模型大小和最佳网络传输大小决定,通常在16到512个Token之间。每个块附加一个由其自身哈希和前缀哈希共同决定的哈希键用于去重。同一个哈希键可能在不同节点上有多个副本,以缓解热点缓存的访问延迟,这由系统的缓存负载均衡策略控制。MOONCAKE Store在缓存池中为每个缓存块分配空间,并记录块键及其地址等元数据。当缓存池已满时,MOONCAKE Store采用LRU(最近最少使用)策略驱逐现有的缓存块(除非该块正被进行中的请求访问),并用新块覆盖被驱逐块的空间。
MOONCAKE Store接口设计:在较高层,MOONCAKE Store提供了基于对象的API,如put、get和change_replica。这些API促进了KVCache以解耦方式进行缓存,将KVCache的小块组织为内存对象,并允许Conductor调整每个KVCache块的副本数量以实现更高的带宽聚合。这些功能由一组同步批处理传输API支持,详情见代码块。传输操作可用于DRAM和GPU VRAM,并在指定内存区域预先注册的前提下,在最佳时机利用GPU Direct RDMA。这些操作的完成情况可以通过getTransferStatus API异步监控,该API报告传输是正在进行还是遇到错误。
int registerLocalMemory(void *vaddr, size_t len, const string &type);
BatchID allocateBatchID(size_t batch_size);
int submitTransfer(BatchID batch_id, const vector<Request> &entries);
int getTransferStatus(BatchID batch_id, int request_index, Status &status);
int freeBatchID(BatchID batch_id);
传输引擎的网络设置与拓扑感知路径选择:为了高效实现上述API,系统设计了一个传输引擎,其主要目标是:1) 在多个RDMA网卡设备间有效分配传输任务;2) 从API中抽象出RDMA连接管理的复杂性;3) 妥善处理临时网络故障。MOONCAKE的优势依赖于高带宽网络互连。当前使用标准的HGX机器,其中每个A800 GPU配备100/200 Gbps网卡,每个H800 GPU配备200/400 Gbps网卡,这与内存带宽相当。现有的库(除NCCL外)无法充分利用这一容量。至于NCCL,它无法优雅地处理因节点/网卡增加或移除导致的动态拓扑变化,也不支持DRAM到DRAM的路径。相比之下,传输引擎努力在发生故障时寻找替代路径。为了解决拥塞,网络使用了云提供商调优的RoCEv2。现代推理服务器通常包含多个CPU插槽、DRAM、GPU和RDMA网卡设备。虽然技术上可以使用任何RDMA网卡将数据从本地DRAM或VRAM传输到远程位置,但这些传输可能受到超级路径互连(UPI)或PCIe交换机带宽限制的制约。为了克服这些限制,MOONCAKE Store实现了拓扑感知路径选择算法。在处理请求之前,每个服务器生成一个拓扑矩阵并广播到整个集群。该矩阵将网卡(NICs)分类为针对不同类型内存的“首选”和“次选”列表。在正常情况下,选择首选列表中的网卡进行传输,促进本地NUMA内的RDMA操作或仅通过本地PCIe交换机的GPU Direct RDMA。例如,如图4所示,要将数据从本地节点的缓冲区0(分配给cpu:0)传输到目标节点的缓冲区1(分配给cpu:1),引擎首先使用本地服务器的拓扑矩阵确定cpu:0的首选网卡,并选择一个(如mlx5_1)作为本地网卡。同样,根据目标内存地址选择目标网卡(如mlx5_3)。此设置使得建立从mlx5_1@local到mlx5_3@target的RDMA连接成为可能。为了进一步最大化带宽利用率,单个请求的传输在内部以16 KB的粒度划分为多个切片。每个切片可能使用不同的路径,从而实现所有RDMA网卡之间的协同工作。
端点管理与故障处理:MOONCAKE Store使用一对端点来表示本地RDMA网卡和远程RDMA网卡之间的连接。在实践中,每个端点包括一个或多个RDMA队列对对象。连接以按需方式建立;在发出第一个请求之前,端点保持未配对状态。为了防止大量端点减慢请求处理速度,MOONCAKE Store采用端点池化(endpoint pooling),限制最大活动连接数。系统使用SIEVE算法来管理端点驱逐。如果连接因链路错误而失败,它将从两侧的端点池中移除,并在下一次数据传输尝试期间重新建立。在多网卡环境中,常见的故障场景是特定网卡暂时不可用。如果识别出连接不可用,MOONCAKE Store会自动寻找可达的替代路径,并将请求重新提交给不同的RDMA网卡设备。此外,MOONCAKE Store能够检测其他RDMA资源(包括RDMA上下文和完成队列)的问题,在问题(如链路断开)解决之前,它会暂时避免使用这些资源。
MOONCAKE的Prefill池设计:与不可侵犯的Decoding节点不同,设计独立的弹性Prefill池的必要性和最佳实践仍存在争议。尽管许多研究者【7, Splitwise: Efficient generative llm inference using phase splitting + 2024 + ISCA】【8, Distserve: Disaggregating prefill and decoding for goodputoptimized large language model serving + 2024 + OSDI】【9, Inference without interference: Disaggregate llm inference for mixed downstream workloads + 2024 + arXiv】建议分离架构,但随着分块预填充(chunked prefill)【10, Taming throughputlatency tradeoff in llm inference with sarathi-serve + 2024 + OSDI】的引入,这种分离是否仍然必要值得讨论。经过仔细考虑,MOONCAKE决定保持解耦架构。这主要是因为在线服务通常具有更严格的SLO。虽然分块预填充减少了解码干扰,但在Prefill阶段最大化MFU与在Decoding阶段满足TBT SLO之间同时取得平衡仍然具有挑战性。另一个重要原因是,随着近期LLM可用上下文长度的快速增加(从8k到128k甚至100万Tokens),长上下文请求的输入Tokens可能比输出Tokens大10到100倍,使得优化TTFT变得至关重要。由于长上下文Prefill中存在丰富的并行性,使用多个8×GPU节点并行处理它们是理想的。然而,将张量并行(TP)扩展到多个节点需要在每层进行两次昂贵的基于RDMA的all-reduce操作,这显著降低了Prefill节点的MFU。近期许多工作提出了序列并行(SP),但在应用于较短输入请求时,SP导致的MFU低于仅使用单节点TP。此外,SP仍需要频繁的跨节点通信,这会降低MFU并与跨节点传输KVCache竞争网络资源。
分块流水线并行(CPP):为了解决上述问题,MOONCAKE利用仅解码器Transformer的自回归特性,为长上下文Prefill实现了分块流水线并行(Chunked Pipeline Parallelism, CPP)。系统将Prefill集群中每X个节点分组为一个流水线Prefill节点组。对于每个请求,其输入Tokens被划分为多个块,每个块的长度不超过prefill_chunk。同一请求的不同块可以由不同节点同时处理,从而并行化处理并降低TTFT。CPP提供两个主要好处:1) 类似于训练中的流水线并行,它仅在每个流水线阶段的边界需要跨节点通信,这很容易与计算重叠。这带来了更好的MFU,并减少了与KVCache传输的网络资源争用。2) 它自然适应短上下文和长上下文,对短上下文Prefill没有带来显著开销,并避免了频繁动态调整节点分区。
Prefill全局调度:以前关于LLM服务的研究通常使用基于分配请求数量来评估每个实例负载的负载均衡策略。而在MOONCAKE中,Prefill实例的选择考虑了更多因素——不仅是负载,还有前缀缓存命中长度和可复用KVCache块的分布。虽然系统倾向于将请求路由到具有更长前缀缓存长度的Prefill实例以降低计算成本,但将它们调度到其他节点以确保整体系统平衡并满足TTFT SLO可能是有益的。为此,系统提出了一种缓存感知的全局调度算法,该算法同时考虑了由前缀缓存决定的预填充时间以及本地排队时间。具体流程如算法1所述:对于每个新请求,将其块键与每个Prefill实例的缓存键逐一比较,以确定前缀匹配长度(prefix_len)。借助此匹配信息,Conductor使用离线数据拟合的多项式回归模型,根据请求长度和实例特有的prefix_len估算相应的执行时间。然后,它加上该请求的估算等待时间,得到该实例上的TTFT。接着,它评估如果将请求调度到非最佳匹配实例时,是否需要进行KVCache传输(当最佳匹配长度与当前实例匹配长度比值大于阈值时),并计算传输时间。最后,Conductor将请求分配给TTFT最短的实例,并相应更新该实例的缓存和队列时间。如果无法实现SLO,Conductor直接向上层返回HTTP 429过多请求响应状态码。预测传输时间较为困难,因为它不仅由传输数据大小决定,还受当前网络状态(尤其是发送节点是否拥塞)影响,这也催生了热点KVCache块的复制需求。
缓存负载均衡:在MOONCAKE中,每个Prefill实例都有自己的本地前缀缓存集。这些缓存的使用频率差异显著(例如系统提示几乎被每个请求访问,而本地长文档缓存可能只被一个用户使用)。由于工作负载高度动态且随时间显著变化,无法准确预测未来的KVCache使用情况。因此,系统提出了一种基于启发式的自动热点迁移方案来增强缓存负载均衡。当请求因为高实例负载未被定向到具有最长前缀缓存长度的Prefill实例时,如果估算的额外预填充时间短于传输时间,Conductor会将缓存的位置和请求转发给替代实例。该实例会主动从持有者处检索KVCache并将其存储在本地。更重要的是,如果最佳远程前缀匹配长度不大于当前本地可复用前缀乘以一个阈值,系统更倾向于计算输入Tokens。这两种策略不仅减少了请求的预填充时间,还促进了热点缓存的自动复制,使其能够更广泛地分布在多个实例中。图5的调度实验表明,结合缓存负载均衡的全局缓存感知算法比本地缓存感知算法进一步降低了$14\%$的平均TTFT。
实验环境
- 硬件配置:系统部署在高性能计算节点集群上,每个节点配置8张NVIDIA-A800-SXM4-80GB GPU和4张200 Gbps RDMA网卡。
- 模型架构:使用模拟LLaMA3-70B架构的Dummy模型。
- 软件配置:以vLLM (v0.5.1)作为实验基线。在MOONCAKE中,MOONCAKE Store的KVCache块大小设置为256。
- 数据集与工作负载(详见表2):
- Conversation(对话):平均输入长度12035,缓存率40%,反映长上下文且多轮对话场景。
- Tool&Agent(工具与代理):平均输入长度8596,缓存率59%,反映带有长且重复系统提示的任务。
- Synthetic(合成数据集):由ShareGPT、Leval和LooGLE组合,平均输入长度15325,缓存率66%,缓存热点分散,使用泊松分布模拟到达率。
| Conversation | Tool&Agent | Synthetic | |
|---|---|---|---|
| Avg Input Len | 12035 | 8596 | 15325 |
| Avg Output Len | 343 | 182 | 149 |
| Cache Ratio | 40% | 59% | 66% |
| Arrival Pattern | Timestamp | Timestamp | Poisson |
| Num Requests | 12031 | 23608 | 3993 |
表 2:工作负载统计。
实验结果
端到端性能实验:
在16个节点的集群上比较了MOONCAKE、vLLM、带前缀缓存的vLLM和带分块预填充的vLLM。
- 对话工作负载(图1):由于输入长度变化大且输出较长,vLLM系统的TBT波动严重。带分块预填充的vLLM难以在提升Prefill MFU和限制Decoding TBT之间取得平衡。相比之下,MOONCAKE显著提高了有效请求容量(增加$59\% \sim 498\%$)。
- Tool&Agent工作负载(图6):该负载前缀缓存比例高且输出短。vLLM及其分块预填充版本因预填充处理时间较长导致解码中断严重。MOONCAKE利用全局缓存池显著增加了缓存容量,在200ms阈值下,其有效缓存容量比带前缀缓存的vLLM提高了$42\%$。
- 合成工作负载(图7):该负载输入最长且缓存热点分散。MOONCAKE处理的大多数请求TBT保持在100ms以内,而vLLM有约$20\%$的请求超过300ms。在200ms阈值下,MOONCAKE的有效请求容量比vLLM提高了$40\%$。
- Prefill GPU时间(图8):MOONCAKE通过充分利用全局缓存,在对话、Tool&Agent和合成工作负载下,相比vLLM分别减少了$36\%$、$53\%$和$64\%$的GPU计算时间。
MOONCAKE Store全局缓存评估:
* 缓存容量定量分析(图9):分析表明,保留1TB本地DRAM(约300万Tokens)在大多数场景下达不到理论最大命中率的$50\%$。而5000万Tokens的容量(需池化至少20个节点的DRAM)几乎能达到$100\%$的理论最大命中率。
* 实际工作负载对比(图10):比较了各自拥有300万Token容量的本地缓存系统与支持跨节点共享的全局缓存系统。全局缓存系统的缓存命中率最高提升了$136\%$,预填充计算时间最高减少了$48\%$。
* 缓存副本动态行为(图11):在对话和Tool&Agent负载中,存在高度集中的热点缓存(如前100个键),系统稳定后这些缓存在Prefill池的几乎每个实例上都有副本。这证明了调度策略有效地为热点缓存提供了副本。
KVCache传输性能评估:
* 传输引擎对比(图12):在并发度64、最小传输粒度128 KB下,MOONCAKE传输引擎的延迟显著低于TCP和Gloo。在传输40 GB数据(对应LLaMA3-70B 128k tokens缓存)时,在$4 \times 200$ Gbps和$8 \times 400$ Gbps网络下分别达到$87 \mathrm{GB/s}$和$190 \mathrm{GB/s}$的带宽,比TCP协议快约$2.4\times$和$4.6\times$。
* 带宽需求(图13):模拟24 Gbps到400 Gbps带宽,当总通信带宽超过100 Gbps时,平均TTFT保持在2秒以下;低于100 Gbps时,性能显著下降并出现网络拥塞。
* 端到端延迟分解(图14):前缀缓存显著减少了预填充时间(对于128k输入长度,减少了$92\%$)。MOONCAKE引入的调度、传输和加载缓存开销可与模型推理异步进行,对吞吐量影响极小。即使考虑这些开销,前缀缓存仍能使128k输入的TTFT减少$86\%$。
补充细节
P/D比例的影响:系统探讨了Prefill节点与Decoding节点数量比例(P/D ratio)对性能的影响。在包含16个节点的集群中,改变P/D比例并测量合成工作负载下的平均TTFT和TBT。结果(图15b)表明,增加Prefill节点会降低TTFT但增加TBT,反之亦然。如图15a所示,当P/D比例约为1:1时,MOONCAKE实现了最高的有效请求容量,表明两类集群负载相对平衡。尽管此前有工作建议动态切换节点角色,但在实际部署中,在线流量的统计特征通常是稳定的,因此系统选择固定P/D比例,仅在发生显著负载波动时才切换节点角色。
相关工作引用总结:
* 资源解耦与调度:系统设计建立在vLLM【14, Efficient memory management for large language model serving with pagedattention + 2023 + SOSP】的PagedAttention动态内存管理、Orca【13, Orca: A distributed serving system for transformer-based generative models + 2022 + OSDI】的迭代级调度,以及FlexGen【36】、Sarathi-Serve【10】和FastServe【37】的调度策略之上。并进一步发展了Splitwise【7】、Distserve【8】等提出的Prefill与Decoding阶段分离的思想。
* 前缀缓存:复用KVCache的技术也见于Prompt Cache【16】和SGLang【17】(利用Radix树实现LRU缓存)。与MOONCAKE同期的一项工作CachedAttention【38】提出了分层KV缓存系统,虽然架构选择相似,但MOONCAKE专门针对长上下文推理中极大的KVCache设计了高容量、高效数据传输和以KVCache为中心的全局调度。
结论
本文提出了MOONCAKE,一种以KVCache为中心的解耦架构,专为高效服务LLM而设计,尤其是在长上下文场景中。论文详细讨论了在最大化整体有效吞吐量的同时满足延迟相关SLO要求的必要性、挑战以及设计选择。通过解耦资源并构建全局分布式缓存池,配合智能调度和高效传输引擎,MOONCAKE在实际大规模部署中展现了卓越的性能。未来的工作可结合KVCache压缩技术和KVCache友好的注意力架构,进一步提升该方法的优势。
💬 评论讨论
欢迎在这里分享您的想法和见解!