欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 【Deepseek学习大模型推理】MOONCAKE: A KVCache-centric Architecture调度(中)调度

【Deepseek学习大模型推理】MOONCAKE: A KVCache-centric Architecture调度(中)调度

2025/4/24 22:13:26 来源:https://blog.csdn.net/qq_38662930/article/details/147457277  浏览:    关键词:【Deepseek学习大模型推理】MOONCAKE: A KVCache-centric Architecture调度(中)调度

https://madsys.cs.tsinghua.edu.cn/publication/mooncake-trading-more-storage-for-less-computation-a-kvcache-centric-architecture-for-serving-llm-chatbot/FAST25-qin.pdf

3 MOONCAKE设计

3.1 概述

在这里插入图片描述
在这里插入图片描述

如图2所示,MOONCAKE采用解耦架构,不仅将预填充节点与解码节点分离,还通过整合GPU集群的CPU、DRAM、SSD和RDMA资源实现解耦KVCache。为调度所有解耦组件,MOONCAKE的核心实现了一个名为Conductor的全局调度器。Conductor根据当前KVCache分布和工作负载特性分发请求。MOONCAKE Store(详见§3.2)负责管理这些KVCache块的存储与传输。

图3展示了请求的典型流程。
在这里插入图片描述完成分词后,Conductor选择一对预填充节点和一个解码节点,启动包含以下四步的工作流(若无前缀缓存则跳过):

  1. KVCache感知调度:Conductor选择节点时平衡三个目标:最大化复用KVCache、均衡不同预填充节点的负载,以及确保TTFT SLO。这实现了以KVCache为中心的调度策略(详见§4)。
  2. 增量预填充:预填充节点利用前缀缓存完成预填充阶段,并将新生成的增量KVCache存回CPU内存。若未缓存的输入Token数超过阈值(通常大于1000 Token),预填充阶段会被拆分为多个块并以流水线方式执行。采用分块但保持解耦的预填充节点的原因详见§3.3。
  3. KVCache传输:每个节点部署的MOONCAKE Store管理并传输缓存。此步骤异步执行并与增量预填充阶段重叠,将各模型层生成的KVCache流式传输至目标解码节点的CPU内存,以减少等待时间。
  4. 解码:解码节点的CPU内存接收全部KVCache后,请求以连续批处理方式加入下一个批次。Conductor根据当前负载预选解码节点,确保不违反TBT SLO。

3.2 MOONCAKE Store: KVCache 的缓存

MOONCAKE 的核心在于其高效实现的 KVCache 分布式全局缓存系统(称为 MOONCAKE Store)。如 §2.2 所述,复用缓存的 KVCache 不仅能节省计算开销,还能通过降低 TTFT 提升用户体验——尤其是在聚合带宽被充分利用时。然而,由于带宽可高达 8×400 Gbps(与 DRAM 带宽相当),实现带宽的完全利用极具挑战性。

我们将在以下部分逐步解析 MOONCAKE Store 的设计:

  • §3.2.1 首先介绍 MOONCAKE Store 如何管理 KVCache,包括其存储方案与淘汰策略(eviction policy);
  • §3.2.2 描述 MOONCAKE Store 的 基于对象的 API内存传输 API
  • §3.2.3 详述 MOONCAKE Store 的 传输引擎(transfer engine)设计。该引擎是一个高性能、零拷贝(zero-copy)的 KVCache 传输系统,旨在最大化每台机器多 RDMA 网卡(NIC)的利用效率。其通过 拓扑感知路径选择(topology-aware path selection)和 端点池化(endpoint pooling)等技术,提升执行效率与可靠性。

3.2.1 KV缓存管理

在MOONCAKE Store中,所有KV缓存以分页块(paged blocks)的形式存储于分布式缓存池内。块的大小(即每个块包含的token数量)由模型规模与最优网络传输粒度共同决定,通常介于16到512个token之间。每个块附加一个哈希键(hash key),该键由块自身的哈希值及其前缀共同确定,用于去重。同一哈希键的块可能在不同节点上存在多个副本,以缓解热点缓存访问延迟,副本分布由§4.2所述的缓存负载均衡策略控制。

MOONCAKE Store在缓存池中为每个缓存块分配空间,并记录块键、地址等元数据。当缓存池满时,MOONCAKE Store采用LRU(最近最少使用)策略驱逐现有缓存块——除非该块正被某个进行中的请求访问——并用新块覆盖被驱逐块的空间。

3.2.2 接口设计

在高层,MOONCAKE Store提供基于对象的API(如putgetchange_replica),支持以解耦方式缓存KVCache。这些API将KVCache的微型块组织为内存对象,并允许Conductor动态调整每个KVCache块的副本数量,以实现更高的带宽聚合。这些功能通过一组同步批处理传输API实现,具体细节如代码清单1所示。

传输操作同时支持DRAM和GPU显存(VRAM),并在最优情况下使用GPU Direct RDMA(需预先注册指定的内存区域)。通过getTransferStatus API可异步监控操作状态,该API会报告传输是否进行中或是否发生错误。

代码清单1:MOONCAKE Store中的内存传输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);

在这里插入图片描述

3.2.3 传输引擎

为实现上述API的高效运行,我们设计了传输引擎以实现三个关键目标:1)在多块RDMA网卡设备间高效分配传输任务;2)对API屏蔽RDMA连接管理的复杂性;3)妥善处理临时性网络故障。该传输引擎经过精心设计,可完整实现上述所有目标。

网络配置 MOONCAKE系统的优势依赖高带宽网络互连。当前我们采用标准HGX服务器架构:每个A800 GPU搭配100/200 Gbps网卡,每个H800 GPU搭配200/400 Gbps网卡——此类带宽水平已接近显存带宽,但现有库(NCCL除外)均无法充分利用该容量。而NCCL本身既无法优雅处理因节点/网卡增减引发的动态拓扑变化,也不支持DRAM到DRAM的直接传输路径。相比之下,本传输引擎能在故障时主动寻找替代路径。

针对网络拥塞问题,系统采用云服务商优化的RoCEv2协议。在调度器中,我们通过增加热点KVCache的副本来缓解拥塞(参见4.2节)。

Figure 4: Transfer engine of MOONCAKE Store.

3.2.3 拓扑感知路径选择
现代推理服务器通常由多CPU插槽、DRAM、GPU和RDMA网卡设备组成。虽然技术上可以通过任意RDMA网卡将数据从本地DRAM或显存(VRAM)传输到远端,但这些传输可能受限于超路径互联(UPI)或PCIe交换机的带宽限制。为突破这些限制,MOONCAKE Store实现了拓扑感知路径选择算法。

在处理请求前,每台服务器会生成拓扑矩阵并向集群广播。该矩阵根据内存注册时指定的内存类型,将网卡(NIC)划分为不同内存类型的"首选"和"备用"列表。在正常状态下,传输优先选择首选列表中的网卡,仅通过本地NUMA域或本地PCIe交换机内的GPU Direct RDMA执行操作。若发生故障,则可能同时使用两个列表中的网卡。具体流程包括:根据内存地址确定合适的本地与目标网卡、建立连接并执行数据传输。
Figure 4: Transfer engine of MOONCAKE Store.
以图4为例
假设需要将本地节点中分配给cpu:0的缓冲区0的数据传输至目标节点中分配给cpu:1的缓冲区1,引擎首先通过本地服务器的拓扑矩阵确定cpu:0对应的首选网卡(如mlx5_1)作为本地网卡。同理,根据目标内存地址选择目标网卡(如mlx5_3)。该机制使得能够建立从mlx5_1@local到mlx5_3@target的RDMA连接,进而执行RDMA读写操作。

为最大化带宽利用率,单个请求的传输会在内部按16 KB粒度切分为多个分片。每个分片可能选择不同传输路径,从而实现所有RDMA网卡的协同工作。

端点管理
MOONCAKE Store采用一对端点(endpoint)表示本地RDMA网卡与远端RDMA网卡间的连接。实际实现中,每个端点包含一个或多个RDMA队列对(queue pair)对象。MOONCAKE Store中的连接采用按需建立机制——端点仅在首次请求发起时才会配对,在此之前保持未配对状态。

为避免大量端点拖慢请求处理速度,MOONCAKE Store采用端点池化(endpoint pooling)机制,限制最大活跃连接数。我们使用SIEVE[19]算法管理端点淘汰策略。若某连接因链路错误失效,该连接会从双方的端点池中移除,并在下次数据传输尝试时重新建立。

故障处理
在多网卡环境中,常见故障场景是特定网卡临时不可用,而其他路由仍可连通两个节点。MOONCAKE Store设计能够有效应对此类临时故障。若某连接被判定为不可用,MOONCAKE Store会自动识别可用的替代路径,并将请求重新提交至其他RDMA网卡设备。

此外,MOONCAKE Store还能检测其他RDMA资源(如RDMA上下文和完成队列)的异常状态。对于出现问题的资源(如断开的链路),系统将暂时规避使用,直至故障修复完成。

3.3 MOONCAKE预填充池

与固定式解码节点不同,是否需要设计独立且弹性的预填充池以及其最佳实践仍存争议。例如,尽管许多研究者[7-9]与我们的思路一致,主张采用解耦架构(disaggregated architecture),但在引入分块预填充(chunked prefill)[10]后,这种解耦是否仍有必要仍需探讨。

经过审慎评估,我们最终决定保留MOONCAKE的解耦架构。这一决策主要基于两点考量:首先,在线服务通常对TTFT(首字延迟)和TBT(吞吐量延迟)的服务水平目标(SLO)有更严格要求。虽然分块预填充能减少解码阶段干扰,但要同时在预填充阶段最大化计算利用率(MFU)和解码阶段满足TBT SLO仍具挑战性(我们将在5.2节的端到端实验中论证此观点)。

其次,预填充节点需采用不同的跨节点并行策略以处理长上下文。随着近期大语言模型(LLM)支持的上下文长度从8K、128K快速扩展至100万token[20],长上下文请求的输入token量通常可达输出的10-100倍,这使得优化TTFT变得尤为关键。长上下文预填充具有丰富的并行潜力,理想情况下应使用超过单个8×GPU节点进行并行处理。然而,若将张量并行(TP)扩展到多节点,每层需执行两次基于RDMA的高代价全规约(all-reduce)操作,这将显著降低预填充节点的MFU。

近期,许多研究提出了序列并行(SP)方法[21–27]。SP通过将请求的输入序列分片到不同节点实现加速,即使长请求也能满足TTFT服务等级目标(SLO)。然而,当应用于较短输入请求时,SP相比仅使用单节点张量并行(TP)会导致更低的内存利用率(MFU)。近期研究[15]提出弹性序列并行机制以动态扩展或收缩SP组。尽管可行,但这增加了系统架构的复杂性。此外,SP仍需要频繁的跨节点通信,这会降低MFU,并与KVCache跨节点传输竞争网络资源。

相比之下,管道并行(PP)具有两个显著优势:1)与训练中的序列并行不同,PP仅需在每个管道阶段边界进行跨节点通信,这可以轻松与计算重叠,从而实现更高的MFU和更少的KVCache传输网络资源竞争。2)其天然适配长短上下文场景,在短上下文预填充阶段不会引入显著开销,且避免频繁动态调整节点分区。这种基于管道的加速方法已在训练系统[28]中得到探索,但据我们所知,这是首次将其应用于推理阶段,因为长上下文推理直到最近才成为研究热点。

为此,MOONCAKE利用仅解码器Transformer的自回归特性,针对长上下文预填充实现了分块管道并行(CPP)。我们将预填充集群中的每X个节点组成一个流水线预填充节点组。对于每个请求,其输入token被划分为多个块(chunk),每个块长度不超过预填充块大小(prefill_chunk)。同一请求的不同块可由不同节点并行处理,从而加速处理流程并降低TTFT。

4 调度

4.1 预填充全局调度
以往关于大语言模型(LLM)服务的研究通常采用基于已分配请求数量评估实例负载的负载均衡策略。然而,在MOONCAKE中,预填充实例的选择需考虑更多因素——不仅包括负载,还需考量前缀缓存命中长度和可复用KVCache块的分布。尽管倾向于将请求路由至前缀缓存更长的预填充实例以降低计算成本,但将请求调度至其他节点可能更有利于系统整体平衡并满足TTFT服务等级目标(SLO)。为应对这一复杂性,我们提出一种缓存感知的全局调度算法,综合考虑前缀缓存导致的预填充时间与本地排队时间。

算法1详述了以KVCache为中心的预填充调度机制。
在这里插入图片描述
在这里插入图片描述
对于每个新请求,系统逐一将其块键(block keys)与各预填充实例的缓存键(cache keys)比对,以确定前缀匹配长度(prefix_len)。基于此匹配信息,Conductor根据请求长度和prefix_len(因实例而异),通过基于离线数据拟合的多项式回归模型,估算对应的执行时间。随后,系统将估算的等待时间加入该实例的TTFT中。最终,Conductor将请求分配至TTFT最短的实例,并更新该实例的缓存与队列时间。若无法满足SLO,Conductor将直接向上层返回HTTP 429 Too Many Requests状态码。

该调度框架的核心机制看似简单,但工程实现中各组件的复杂性不容忽视。例如,为预测请求预填充阶段的计算时间,我们采用基于离线测试数据构建的预测模型。该模型根据请求长度和前缀缓存命中长度估算预填充耗时。得益于Transformer的规律性计算模式,只要离线数据充足,该预测的误差范围极小。请求的排队时间则通过累加队列中所有请求的预填充时间计算得出。在实际部署中,TTFT的计算过程采用并行化处理,其耗时相比推理时间可忽略不计。

真正的挑战在于预测数据传输时间,因为其不仅取决于传输数据量,还受当前网络状态(尤其是发送节点是否处于拥塞状态)影响。这也促使我们必须实现热门KVCache块的冗余复制机制,相关内容将在§4.2详细探讨。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4.2 缓存负载均衡

在MOONCAKE中,每个预填充实例都维护独立的本地前缀缓存集,这些缓存的使用频率差异显著。例如,系统提示(system prompts)几乎被所有请求访问,而存储本地长文档内容的缓存可能仅由单个用户使用。如§4.1所述,Conductor在平衡缓存命中率与实例负载中起关键作用。因此,从分布式缓存系统的视角来看,负载均衡同样至关重要。具体而言,其核心挑战在于设计缓存备份策略,以确保全局预填充调度能同时实现高缓存命中率与低负载。

针对这一KVCache调度问题,一种简单化解决方案是:收集每个缓存块的全局使用统计信息,通过预测模型预估其未来使用频率,并据此制定调度决策。然而,与预填充时间估算不同,工作负载具有高度动态性且随时间剧烈波动。尤其对于用户规模快速增长的MaaS(Model-as-a-Service)提供商而言,精确预测未来使用模式几乎不可能。为此,我们提出一种基于启发式的自动热点迁移机制,以增强缓存负载均衡能力。

如前所述,由于实例负载过高,请求未必总能被定向至前缀缓存最长的预填充实例。在此类情况下,若估算的额外预填充时间短于传输时间,Conductor会将缓存位置与请求转发至其他实例。该实例会主动从持有者处拉取KVCache并本地存储。更重要的是,若最优远程前缀匹配长度不超过当前本地可复用前缀长度与阈值的乘积,我们倾向于直接计算输入token。这两种策略不仅缩短了请求的预填充时间,还促进了热点缓存的自动复制,使其分布到更多实例中。

为验证策略的有效性,我们进行了调度对比实验,比较随机调度、负载均衡调度与本文策略的性能差异。同时对比了§4.1描述的本地缓存感知调度与本节考虑缓存负载均衡的全局缓存感知调度。在随机调度中,预填充实例为请求随机分配;负载均衡调度则选择负载最轻的实例。具体而言,我们构建了一个包含16个8×A800节点的MOONCAKE集群,并复现了§5.2.1所述对话追踪数据进行实验。各调度算法的性能通过首令牌生成时间(TTFT)评估。如图5所示的实验结果表明,本文以KVCache为中心的调度算法显著优于随机调度与负载均衡调度。通过引入缓存负载均衡机制,全局缓存感知算法相比本地缓存感知算法进一步降低了14%的平均TTFT。

由于实例负载过高,请求未必总能被定向至前缀缓存最长的预填充实例。在此类情况下,若估算的额外预填充时间短于传输时间,Conductor会将缓存位置与请求转发至其他实例。
解释: 假如前缀缓存最长的实例,但是负载较大,那么计算时间较长, 那么要迁移到另外一个实例,虽然增加了迁移时间, 但是额外的预填存时间更短(如不需要排队),那么就应当迁移到这个实例

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词