拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于 MooncakeStore 的 vLLM V0 分离式 Prefill-Decode(PD)服务部署指南

基于 MooncakeStore 的 vLLM V0 分离式 Prefill-Decode(PD)服务部署指南
  • 人工智能
  • 大模型
  • 模型推理服务
  • 后端

【免费下载链接】Mooncake

Mooncake is the serving platform for Kimi, a leading LLM service provided by Moonshot AI.

项目地址:https://gitcode.com/gh_mirrors/mo/Mooncake
点击查看免费下载

本文是 Mooncake 仓库中 vLLM V0 Disaggregated Serving with MooncakeStore 文档的深度展开版本。它以 vLLM 官方仓库的 PR #10502(intra-node KVCache 传输)与 PR #12957(inter-node 场景支持)为基础,介绍如何利用 MooncakeStore 作为共享 KV 缓存池,将 vLLM 的 Prefill(预填充)与 Decode(解码)实例解耦为独立的集群角色,并通过 RDMA/TCP 在实例之间高速搬运 KV Cache。读完本文,你将掌握:mooncake-transfer-engine与 vLLM V0 的安装组合、mooncake.json配置文件的完整字段语义、多实例kv_producer/kv_consumer集群的启动方式,以及带动态扩缩容能力的 XpYd 代理服务器(disagg_proxy_demo.py)的部署与验证流程。

:class: warning 本文对应的 vLLM V0 集成方案在当前仓库中已被标记为 **Archived**,其内容已合并进统一的 [KV Cache Storage & Sharing 指南](https://link.gitcode.com/i/d161905b1fdfe82b7957af39960ea09d)(见其中的 V0 Legacy 章节)。该方案仍处于实验阶段,接口细节可能随 vLLM 社区反馈而调整;新部署建议优先参考 [vLLM V1 LMCache integration](https://link.gitcode.com/i/139727f175c77c45a1e14a6121c50455) 对应的 V1 集成方案。

一、背景:为什么需要分离式 Prefill-Decode 服务

在传统的单体 vLLM 部署中,一次请求的 Prefill(一次性处理整个 prompt、产生 KV Cache)与 Decode(逐 token 自回归生成、逐步消费 KV Cache)在同一实例上串行完成。这种模式存在两个结构性瓶颈:

  • 显存中的 KV Cache 容量被单机限制:长上下文请求会迅速占满 GPU 显存中的 KV 缓存,吞吐受限于单实例的缓存池大小;
  • 两种阶段的最优资源配比不同:Prefill 是计算密集型(attention 矩阵计算量大),Decode 是访存/带宽密集型(每次仅新增一个 token 的 KV)。把两类负载混跑,很难同时调优。

Mooncake 提供的 vLLM V0 集成方案将二者拆开:**Prefill 实例(kv_producer)**只负责把 prompt 计算成 KV Cache,随后通过 Mooncake 的传输引擎(底层协议支持 RDMA/TCP)将 KV 块搬运到Decode 实例(kv_consumer),后者直接以收到的 KV Cache 为起点继续生成,不再重复计算 prompt。这就是业内常说的 Disaggregated Prefill-Decode(PD 分离式服务,本仓库文档中也称为XpYd,其中 X 表示 Prefill 实例数量、Y 表示 Decode 实例数量)。

与旧版 v0.x 集成相比,本版(v0.3 起的架构)引入了两个关键变化(原文 "Main changes from v0.x to v1"):

  1. XpYd 支持与编排:可以在运行时动态调整 Prefill 组与 Decode 组的实例数量,而无需重启整个集群;
  2. 更强的稳定性与容错:单个 vLLM 实例的意外崩溃是可容忍的;由于实例之间不再存在相互直连的连接(KV 的搬运改由 Mooncake 的 master/元数据服务编排),每个实例本质上仍是一个原生 vLLM 实例,即使请求不经过代理直接打到某个实例,也能被正常服务完毕。

二、安装与版本兼容性

2.1 安装 mooncake-transfer-engine

先安装传输引擎的 Python 包:

pip3 install mooncake-transfer-engine

安装注意点(原文明确提示):

  • 如果运行时报错缺少lib*.so动态库,需要先卸载该 pip 包,再按 构建指南 手动编译二进制产物:

    pip3 uninstall mooncake-transfer-engine
  • 版本匹配约束:若使用的 vLLM 版本 ≤ v0.8.4,则要求mooncake-transfer-engine <= 0.3.3.post2。此外,在最新版传输引擎中,旧的mooncake_vllm_adaptor接口已被废弃(deprecated),不再使用。

2.2 安装最新版 vLLM(V0 后端)

由于 PD 分离特性当前只在 vLLM V0 引擎上支持,需要从源码安装:

# 1. 克隆 vLLM 官方仓库 git clone git@github.com:vllm-project/vllm.git # 2. 进入目录并从源码构建(包含 C++ 与 CUDA 代码) cd vllm pip3 install -e .
  • 如果构建失败,可先尝试升级 cmake:pip3 install cmake --upgrade(这一提示来自仓库中同主题的 disagg-prefill-decode 指南);
  • 若遇到无法自行解决的问题,请参考 vLLM 官方的安装/编译指南。

从仓库的基准测试脚本可以印证该组合的典型用法:benchmarks/xypd_benchmarks/vllm-benchmarks/benchmarks.sh 中同样显式设置了export VLLM_USE_V1=0,并通过pip install vllm准备运行环境,随后以python3 -m vllm.entrypoints.openai.api_server拉起实例。

三、配置文件 mooncake.json 详解

Prefill 与 Decode 实例需要各自准备一份mooncake.json。同一节点上的所有 Prefill/Decode 实例可以共享同一份配置文件。

3.1 RDMA 场景

{ "local_hostname": "192.168.0.137", "metadata_server": "etcd://192.168.0.137:2379", "protocol": "rdma", "device_name": "erdma_0", "master_server_address": "192.168.0.137:50001" }

3.2 TCP 场景

{ "local_hostname": "192.168.0.137", "metadata_server": "etcd://192.168.0.137:2379", "protocol": "tcp", "device_name": "", "master_server_address": "192.168.0.137:50001" }

3.3 字段语义与取值说明

字段含义取值说明
local_hostname当前节点用于与元数据服务器通信的 IP 地址取值为本机可被其他节点访问到的地址,如"192.168.0.137"
metadata_serverMooncake 传输引擎的元数据服务器地址支持三种后端,见下方示例;也支持逗号分隔的多副本地址
protocol数据传输协议"rdma"或"tcp"
device_name数据传输使用的设备仅当protocol为"rdma"时必填;多 NIC 时用逗号分隔且不能有空格,如"erdma_0,erdma_1";TCP 场景填""
master_server_addressMooncakeStore master 守护进程的 IP 与端口形如"192.168.0.137:50001",须与下方启动的mooncake_master --port 50001对应

metadata_server三种后端写法(来自原文及仓库中同系列文档):

  • etcd 后端:"192.168.0.137:2379"、"etcd://192.168.0.137:2379"或带副本的"etcd://192.168.0.137:2379,192.168.0.138:2379";
  • redis 后端:"redis://192.168.0.137:6379";
  • http 后端:"http://192.168.0.137:8080/metadata"。

从仓库后续演进可以进一步理解这些字段的背景:在更早的 v0.2 版集成(对应 vllm-integration-v0.2.md)中,配置文件还需要prefill_url/decode_url/metadata_backend等字段来显式描述两端地址;而 v0.3 版改用local_hostname+ 元数据服务器 +master_server_address的方式,实例之间不再需要感知彼此 URL,这正是原文所述"instance-to-instance connections are removed"的落地体现——节点通过 MooncakeStore 的统一元数据完成 KV 块寻址与搬运。

四、端到端运行示例

以下命令均假定你在 vLLM 仓库克隆目录的根目录下执行,并且所有 IP、端口请按实际环境替换。原文档特别提醒:如果某些 vLLM 实例异常退出,连接元数据可能因未正常清理而损坏,此时建议重启mooncake_master后再进行下一轮测试。

第 1 步:启动 etcd

etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://localhost:2379 # 运行前可能需要先终止其他占用 2379 端口的 etcd 进程

第 2 步:启动 mooncake_master

mooncake_master --port 50001

mooncake_master即 MooncakeStore 的 master 守护进程,其可执行目标由仓库源码构建产生(见 mooncake-store/src/CMakeLists.txt 中add_executable(mooncake_master master.cpp),并安装到bin目录)。它负责维护各实例的连接元数据,使 KV 块可以在 Prefill 与 Decode 实例间正确寻址、搬运。

第 3 步:启动多个 vLLM 实例

kv_producer(Prefill)角色——4 个实例,分别绑定 GPU 0~3、端口 8100~8103:

MOONCAKE_CONFIG_PATH=./mooncake.json VLLM_USE_V1=0 python3 -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --port 8100 \ --max-model-len 10000 \ --gpu-memory-utilization 0.8 \ --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_producer"}' CUDA_VISIBLE_DEVICES=1 MOONCAKE_CONFIG_PATH=./mooncake.json VLLM_USE_V1=0 python3 -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --port 8101 \ --max-model-len 10000 \ --gpu-memory-utilization 0.8 \ --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_producer"}' CUDA_VISIBLE_DEVICES=2 MOONCAKE_CONFIG_PATH=./mooncake.json VLLM_USE_V1=0 python3 -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --port 8102 \ --max-model-len 10000 \ --gpu-memory-utilization 0.8 \ --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_producer"}' CUDA_VISIBLE_DEVICES=3 MOONCAKE_CONFIG_PATH=./mooncake.json VLLM_USE_V1=0 python3 -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --port 8103 \ --max-model-len 10000 \ --gpu-memory-utilization 0.8 \ --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_producer"}'

kv_consumer(Decode)角色——4 个实例,分别绑定 GPU 4~7、端口 8200~8203:

CUDA_VISIBLE_DEVICES=4 MOONCAKE_CONFIG_PATH=./mooncake.json VLLM_USE_V1=0 python3 -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --port 8200 \ --max-model-len 10000 \ --gpu-memory-utilization 0.8 \ --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_consumer"}' CUDA_VISIBLE_DEVICES=5 MOONCAKE_CONFIG_PATH=./mooncake.json VLLM_USE_V1=0 python3 -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --port 8201 \ --max-model-len 10000 \ --gpu-memory-utilization 0.8 \ --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_consumer"}' CUDA_VISIBLE_DEVICES=6 MOONCAKE_CONFIG_PATH=./mooncake.json VLLM_USE_V1=0 python3 -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --port 8202 \ --max-model-len 10000 \ --gpu-memory-utilization 0.8 \ --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_consumer"}' CUDA_VISIBLE_DEVICES=7 MOONCAKE_CONFIG_PATH=./mooncake.json VLLM_USE_V1=0 python3 -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --port 8203 \ --max-model-len 10000 \ --gpu-memory-utilization 0.8 \ --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_consumer"}'

第 3.1 步:命令行参数逐项说明

参数/环境变量作用与约束
MOONCAKE_CONFIG_PATHmooncake.json配置文件的路径
VLLM_USE_V1=0必须设置:PD 分离特性当前仅在 vLLM V0 引擎上支持。也可以export VLLM_USE_V1=0到环境变量,避免在每个命令前重复书写
VLLM_USE_MODELSCOPE可选;如果能直接访问 HuggingFace,请去掉该变量
--model指定模型(示例为Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4)
--portvLLM 服务监听端口
--max-model-len模型支持的最大序列长度(示例为 10000)
--gpu-memory-utilizationGPU 显存利用率(示例为 0.8)
--tensor_parallel_size/-tp支持张量并行,例如追加-tp 2使用多 GPU 运行;所有实例的tensor_parallel_size必须一致。若 Prefill 与 Decode 同机运行,请用不同的CUDA_VISIBLE_DEVICES区分,例如 Prefill 用CUDA_VISIBLE_DEVICES=0,1、Decode 用CUDA_VISIBLE_DEVICES=2,3
--kv-transfer-configJSON 字符串,指定 KV 传输连接器及其配置;kv_connector固定为"MooncakeStoreConnector",kv_role取"kv_producer"、"kv_consumer"或"kv_both"之一

关于kv_role的补充:kv_producer是产出 KV Cache 的 Prefill 节点,kv_consumer是消费 KV Cache 的 Decode 节点,kv_both则同时具备两者能力(在 MooncakeStoreConnector 指南 中,kv_both被用于单节点 KV Cache 卸载场景)。MooncakeStoreConnector与旧版MooncakeConnector的关键差异在于:前者将 KV 块写入MooncakeDistributedStore这一共享 KV 缓存池(支持 CPU/SSD 卸载、基于块哈希的跨实例前缀缓存复用),而后者是实例间的直连传输。

仓库基准脚本 benchmarks/xypd_benchmarks/vllm-benchmarks/benchmarks.sh 的launch_nodes()函数(见第 89~126 行)正是以上述方式批量拉起 Prefill/Decode 实例,并通过wait_for_server轮询/v1/models等待实例就绪,可作为批量编排的参考实现。

第 4 步:启动代理服务器

cd vllm python3 examples/online_serving/disagg_examples/disagg_proxy_demo.py \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --prefill localhost:8100 localhost:8101 \ --decode localhost:8200 localhost:8201 \ --port 8000

参数说明:

  • --model:指定模型名,同时作为代理的 tokenizer;
  • --port:代理服务监听端口(默认 8000);
  • --prefill/-p:vLLM Prefill 实例的 IP:端口列表;
  • --decode/-d:vLLM Decode 实例的 IP:端口列表。

该代理的工作模式(从仓库源码 benchmarks/xypd_benchmarks/proxy_demo.py 可以完整印证):

  1. 收到/v1/completions或/v1/chat/completions请求后,将请求副本的max_tokens改为 1,按调度策略(默认RoundRobinSchedulingPolicy,见 proxy_demo.py)转发给某个 Prefill 实例,只做 Prefill、产出 KV Cache(见create_completion中 "Perform kv recv and decoding stage" 之前的逻辑,proxy_demo.py);
  2. 随后将原始请求转发给某个 Decode 实例,后者通过 MooncakeStoreConnector 取回 KV Cache,直接开始 Decode,最终以流式响应返回给客户端。

需要注意的是:这个disagg_proxy只是 Mooncake 团队基于 round-robin 策略实现的演示性代理。在生产阶段,服务提供商可以按自身需求实现对应的全局代理调度策略(如按负载、按前缀命中率等)。此外,代理在转发失败时还会自动将故障实例从列表中移除(remove_instance_endpoint),体现了"单个实例崩溃可容忍"的设计目标。

第 4.1 步:运行时动态调整 Prefill/Decode 实例(XpYd 编排)

如果需要在不重启的情况下动态增减 p-node 与 d-node,需要先配置管理员 API Key:

export ADMIN_API_KEY="xxxxxxxx" # 或直接在启动命令前注入: ADMIN_API_KEY="xxxxxxxx" python3 vllm/examples/online_serving/disagg_examples/disagg_demo.py \ --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \ --prefill localhost:8100 localhost:8101 \ --decode localhost:8200 localhost:8201 \ --port 8000 \ --scheduling round_robin

然后通过管理接口把新实例加入 Prefill 组或 Decode 组:

curl -X POST "http://localhost:8000/instances/add" -H "Content-Type: application/json" -H "X-API-Key: $ADMIN_API_KEY" -d '{"type": "prefill", "instance": "localhost:8102"}' curl -X POST "http://localhost:8000/instances/add" -H "Content-Type: application/json" -H "X-API-Key: $ADMIN_API_KEY" -d '{"type": "prefill", "instance": "localhost:8103"}' curl -X POST "http://localhost:8000/instances/add" -H "Content-Type: application/json" -H "X-API-Key: $ADMIN_API_KEY" -d '{"type": "decode", "instance": "localhost:8202"}' curl -X POST "http://localhost:8000/instances/add" -H "Content-Type: application/json" -H "X-API-Key: $ADMIN_API_KEY" -d '{"type": "decode", "instance": "localhost:8203"}'

查询代理当前状态:

curl localhost:8000/status | jq

从实现上看,/instances/add接口受ADMIN_API_KEY校验保护(见 proxy_demo.py 的api_key_authenticate),新增实例前会先请求该实例的/v1/models校验模型是否一致(validate_instance),校验通过后才会加入对应列表并重建 round-robin 迭代器;/status返回prefill_node_count、decode_node_count及两组节点列表。这正是 XpYd 动态编排能力的直接证据。

再次强调:请务必将命令中的 IP 地址替换为你自己的环境地址。

五、用 OpenAI 兼容接口验证

向代理发送一个 completions 请求:

curl -s http://localhost:8000/v1/completions -H "Content-Type: application/json" -d '{ "model": "Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4", "prompt": "San Francisco is a", "max_tokens": 1000 }'
  • 如果请求不是从代理所在机器发出,请把localhost改为代理服务器的 IP 地址;
  • 仓库的端到端测试 scripts/e2e/scripts/test_vllm_1p1d_erdma.sh 提供了同类验证模板:它在一台机器上启动kv_consumer(端口 8020)、另一台机器启动kv_producer(端口 8010),再通过curl /v1/chat/completions发送请求并校验响应内容,可作为集成测试的参考。

六、架构要点与使用限制

  • KV 搬运路径:Prefill 实例产生的 KV 块通过 Mooncake 传输引擎(protocol: rdma/tcp)进入共享 KV 缓存池,Decode 实例按需取回。master_server_address指向的mooncake_master是这一过程的核心协调者,因此当实例异常退出导致元数据损坏时,重启mooncake_master是最直接的处理手段。
  • 角色划分:同一份mooncake.json可被同节点的多个实例共享;角色完全由--kv-transfer-config中的kv_role决定,与配置文件无关。
  • 容错与独立性:由于实例间无直接连接,每个实例仍是原生 vLLM 实例,可独立完成不经过代理的请求,单实例崩溃不会拖垮集群。
  • 实验性声明:原文档明确标注该集成仍为实验版本,会依据 vLLM 社区反馈随时调整;且 PD 特性仅在 V0 引擎可用(VLLM_USE_V1=0)。对于新部署,请优先转向仓库提供的 vLLM V1 方案(见 vLLM V1 LMCache integration 与 vLLM V1 Mooncake Store 性能文档)。

七、延伸阅读

  • 统一的 KV Cache Storage & Sharing 指南:当前仓库推荐使用的整合版指南,包含 V0 Legacy 与 V1 两个章节;
  • MooncakeStoreConnector 部署指南:讲解MooncakeDistributedStore共享 KV 池、CPU/SSD 卸载、kv_both单节点场景与MultiConnector组合用法(含PYTHONHASHSEED=0保证 DP 各 rank 块哈希一致的注意事项);
  • Disaggregated Prefill-Decode 指南:统一了 V1(推荐)与 V0(遗留)两套MooncakeConnector使用方式,并提供故障排查建议;
  • 基准测试脚本 benchmarks/xypd_benchmarks/vllm-benchmarks/benchmarks.sh 与代理实现 benchmarks/xypd_benchmarks/proxy_demo.py:分别展示了 1P1D、2P1D、2P2D、2P4D、4P4D 等多组 XpYd 组合下的批量压测方法与可扩展的代理实现;
  • 构建依赖与入门指引:构建指南、快速开始。
  • 人工智能
  • 大模型
  • 模型推理服务
  • 后端

【免费下载链接】Mooncake

Mooncake is the serving platform for Kimi, a leading LLM service provided by Moonshot AI.

项目地址:https://gitcode.com/gh_mirrors/mo/Mooncake
点击查看免费下载

相关推荐

上一篇:Kind 终极开发者指南:如何快速参与贡献和构建自定义镜像
下一篇:MultiType-FilePicker完全指南:轻量级Android文件选择库的终极解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表