news 2026/9/16 16:18:53

LMCache MP 模式下的 vLLM Prefill/Decode 分离部署指南:NIXL KV 移交与跨请求缓存复用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LMCache MP 模式下的 vLLM Prefill/Decode 分离部署指南:NIXL KV 移交与跨请求缓存复用

LMCache MP 模式下的 vLLM Prefill/Decode 分离部署指南:NIXL KV 移交与跨请求缓存复用

【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCache

本篇指南讲解如何在 LMCache 多进程(MP)模式下,与 vLLM 的 Prefill/Decode(P/D)分离架构组合部署:prefill 与 decode 实例分别运行、通过 NIXL 完成 KV 移交,同时每个实例旁的 LMCache server 提供跨请求的 KV 缓存复用。读完本文你将掌握 P/D 分离的完整工作原理、MultiConnector双层连接器配置、多机与单机两种部署命令,以及通过响应 ID、日志指标和 HTTP 状态接口验证部署是否正常工作的全套方法。

一、什么是 P/D 分离,LMCache MP 叠加了什么

Disaggregated prefill(P/D 分离)让 prefill 和 decode 运行在独立的 vLLM 实例上:prefill 实例负责计算 prompt 的 KV,通过 NIXL 交给decode 实例,decode 实例直接基于这些 KV 生成 token,而无需重新计算 prompt。这样一来,prefill 密集型和 decode 密集型的工作负载可以独立扩缩容,互不牵制。

LMCache MP 在此基础上叠加了跨请求的 KV 复用。每个 vLLM 实例还会把自身的 KV 卸载(offload)到与其同机部署的 LMCache server 上。因此,当后续请求出现重复前缀(recurring prefix)——无论是新请求到达,还是前缀因淘汰(eviction)已离开 GPU HBM——都可以直接从 LMCache 加载,而不用重新计算。prefill 路径上 KV 的来源优先级为:

本地 GPU 缓存(local GPU cache)→ LMCache → 重新计算(recompute)

两层能力通过 vLLM 的MultiConnector组合在一起,每个实例上并行运行两个连接器:

连接器职责
NixlConnector当前请求的 prefill→decode KV 移交,走 NIXL(UCX / RDMA)
LMCacheMPConnector向实例对应的 LMCache server 卸载/加载 KV,实现跨请求复用

在 P/D 模式下,vLLM 的router会把每个请求先路由到 prefill 实例、再路由到 decode 实例,并在两者之间串起 NIXL 握手(handshake)。

从源码看,LMCacheMPConnector实现在 lmcache/integration/vllm/lmcache_mp_connector.py 中,它继承 vLLM 的KVConnectorBase_V1,并在初始化时完成 KV cache 分组校验(validate_kv_cache_groups)、并行策略推导、ZMQ 上下文创建等步骤,最终通过--kv-transfer-configkv_connector_extra_config字段与 LMCache server 建立连接。

二、工作原理:最小部署由五个进程组成

一个最小可用的 P/D 分离 + LMCache MP 部署包含五个进程

  1. Prefill vLLM(生产者 producer)—— 连接器配置为MultiConnector[NixlConnector (kv_producer), LMCacheMPConnector]。它计算 prompt 的 KV,将 KV 存入自己的 LMCache server,并通过 NIXL 暴露给 decoder 拉取。
  2. Decode vLLM(消费者 consumer)—— 连接器配置为MultiConnector[NixlConnector (kv_consumer), LMCacheMPConnector]。它从 producer 拉取 prompt KV 并生成输出。
  3. 两个 LMCache server—— 每个 vLLM 实例对应一个独立的lmcache server进程(二者不能共用一个 server)。
  4. Router—— 运行vllm-router --vllm-pd-disaggregation,先路由到 prefill 再路由到 decode。

如果还希望 prefill 池与 decode 池之间也能共享缓存,可以在其上叠加 P2P KV cache sharing:为两个 LMCache server 都配置 coordinator 并加上--p2p-advertise-url即可。P2P 模式下各节点会把自己的 L1 缓存注册为可被对端通过 RDMA 单边读取的远程内存,使整集群在热路径上无需中央存储层即可共享 KV(详见 lmcache/v1/multiprocess/config.py 中的--p2p-advertise-url--p2p-listen-url--p2p-lookup-timeout--p2p-load-timeout等参数)。

三、前置要求

在开始部署前,请先确认以下两点,否则 offload 或传输可能静默失效:

  • vLLM 的 MultiConnector real-blocks 修复(PR #46865)已合入。该修复解除了MultiConnector下的 LMCache offload 阻塞;没有它,offload 会静默地永不触发
  • vLLM 环境中可用 NIXL,通过lmcache[nixl]附加依赖安装,该 extra 会拉取nixl>=1.3.0。仓库中 requirements/nixl.txt 的注释说明:nixl是唯一提供可导入顶层nixl模块的元包,从 1.3.0 起会在运行时按 torch 的 CUDA 构建分派到对应的nixl_cu12/nixl_cu13后端。

四、配置详解:--kv-transfer-config与 NIXL 环境变量

每个 vLLM 实例通过--kv-transfer-config指定MultiConnector及其两个子连接器。核心键说明如下:

Key说明
kv_connector=MultiConnector并行运行kv_connector_extra_config.connectors中列出的子连接器
kv_rolekv_producer(prefill)或kv_consumer(decode);在顶层MultiConnector和嵌套的NixlConnector上都要设置
NixlConnector负责 prefill→decode 移交。设置kv_load_failure_policy=fail,使传输失败直接暴露出来,而不是静默地退化为重新计算
LMCacheMPConnector负责向本机 LMCache server 卸载/加载 KV,使用kv_role=kv_both
lmcache.mp.host/lmcache.mp.port实例对应 LMCache server 的传输地址与 ZMQ--port(每个实例各不相同)

NIXL 传输通过 vLLM 实例上的环境变量进行调优:

  • VLLM_NIXL_SIDE_CHANNEL_HOST—— 握手(handshake)时对外宣告的地址,需被对端可达;
  • VLLM_NIXL_SIDE_CHANNEL_PORT——同一主机上的实例之间必须使用不同端口(默认5600);
  • UCX_NET_DEVICES=allNCCL_CUMEM_ENABLE=1

LMCacheMPConnectorkv_connector_extra_config还支持以下可选项(见 lmcache/integration/vllm/lmcache_mp_connector.py 中LMCacheMPConnector类的文档注释):

  • lmcache.mp.server_urls—— 多 server 部署时的 server URL 列表(或逗号分隔字符串,如"tcp://host1:6667,tcp://host2:6667"),优先于单 server 的 host/port;
  • lmcache.mp.host—— 单 server 部署的 host,默认tcp://localhost
  • lmcache.mp.port—— 单 server 部署的端口,默认5555
  • lmcache.mp.mq_timeout—— 消息队列请求超时(秒);
  • lmcache.mp.heartbeat_interval—— 向 server 发送心跳的间隔(秒);
  • lmcache.mp.eager_prefetch—— 请求进入 vLLM 等待队列时就提前发起 LMCache 查询,默认关闭。

从源码还可以看到一些拓扑约束:server 数量由lmcache.mp.server_urls推导,要求world_size能被n_servers整除;多 server 模式暂不支持数据并行(DP)与流水线并行(PP,仅支持张量并行 TP);不支持时会在启动阶段直接抛出ValueError,做到快速失败(fail fast)。

lmcache server的完整参数列表见lmcache serverCLI 文档,命令本身由 lmcache/cli/commands/server.py 实现,它组合了 MP server、P2P、存储管理(L1)、HTTP 前端与可观测性多组参数。

五、多机部署:五步启动 P/D 分离集群

下面的示例把 prefill 池、decode 池和 router 放在不同的主机上。请将<PREFILL_IP>/<DECODE_IP>替换为可路由的地址,<model>替换为模型路径(两台实例上必须一致)。

Step 1 —— prefill 的 LMCache server(在 prefill 主机上执行):

lmcache server \ --port 6555 --http-port 8090 \ --l1-size-gb 100 --eviction-policy LRU --chunk-size 256 \ --instance-id prefiller

Step 2 —— prefill vLLM(生产者 producer)(在 prefill 主机上执行):

VLLM_NIXL_SIDE_CHANNEL_HOST=<PREFILL_IP> VLLM_NIXL_SIDE_CHANNEL_PORT=5600 \ UCX_NET_DEVICES=all NCCL_CUMEM_ENABLE=1 \ vllm serve <model> \ --port 8001 --tensor-parallel-size 1 \ --kv-transfer-config '{"kv_connector":"MultiConnector","kv_role":"kv_producer","kv_connector_extra_config":{"connectors":[{"kv_connector":"NixlConnector","kv_role":"kv_producer","kv_load_failure_policy":"fail"},{"kv_connector":"LMCacheMPConnector","kv_role":"kv_both","kv_connector_extra_config":{"lmcache.mp.host":"tcp://localhost","lmcache.mp.port":6555}}]}}'

producer 在<PREFILL_IP>:5600宣告其 NIXL side channel,并把 KV 卸载到 6555 端口的 LMCache server。

Step 3 —— decode 的 LMCache server(在 decode 主机上执行):

lmcache server \ --port 6556 --http-port 8091 \ --l1-size-gb 100 --eviction-policy LRU --chunk-size 256 \ --instance-id decoder

Step 4 —— decode vLLM(消费者 consumer)(在 decode 主机上执行):

VLLM_NIXL_SIDE_CHANNEL_HOST=<DECODE_IP> VLLM_NIXL_SIDE_CHANNEL_PORT=5558 \ UCX_NET_DEVICES=all NCCL_CUMEM_ENABLE=1 \ vllm serve <model> \ --port 8002 --tensor-parallel-size 1 \ --kv-transfer-config '{"kv_connector":"MultiConnector","kv_role":"kv_consumer","kv_connector_extra_config":{"connectors":[{"kv_connector":"NixlConnector","kv_role":"kv_consumer","kv_load_failure_policy":"fail"},{"kv_connector":"LMCacheMPConnector","kv_role":"kv_both","kv_connector_extra_config":{"lmcache.mp.host":"tcp://localhost","lmcache.mp.port":6556}}]}}'

consumer 把 KV 卸载到 6556 端口的 LMCache server;它的 side-channel 端口(5558)与 producer 不同,这样两者即便共宿一台主机也不会冲突。

Step 5 —— router(在能同时访问两个 vLLM 实例的任意主机上执行):

vllm-router \ --policy round_robin \ --vllm-pd-disaggregation \ --prefill http://<PREFILL_IP>:8001 \ --decode http://<DECODE_IP>:8002 \ --host 0.0.0.0 --port 30000

之后把请求发送到 router(http://<ROUTER_IP>:30000/v1/...),router 会透明地处理 prefill→decode 的切分。

服务器参数补充说明

以上lmcache server参数在源码中都有明确定义与默认值(见 lmcache/v1/multiprocess/config.py 与 lmcache/v1/distributed/config.py):

  • --port—— ZMQ server 绑定端口,默认5555
  • --http-port—— HTTP 前端端口,默认8080
  • --chunk-size—— KV 缓存操作的 chunk 大小,默认256(这也是后文验证 offload 时"prompt 至少需要达到 chunk-size 个 token 才会存储"的依据);
  • --l1-size-gb—— L1 内存大小(GB),必填
  • --eviction-policy—— 淘汰策略,可选LRUIsolatedLRUnoop必填;其中IsolatedLRU为每个cache_salt维护独立的 LRU 列表,需要配额通过 HTTP API 配置;
  • --instance-id—— 实例稳定标识,用作 coordinator 成员键和 OTel 的service.instance.id资源属性,默认不指定时启动时生成随机 UUID v4。

注意lmcache server命令需要完整的 LMCache 安装(含 CUDA 扩展),轻量安装下命令会提示用pip install lmcache安装完整包(见 lmcache/cli/commands/server.py)。

六、单机模式:本地联调与排障

单机模式在localhost上运行同样的五个进程,prefill 用 GPU 6、decode 用 GPU 7。共享主机的所有端口都必须互不相同:LMCache 的--port--http-port、vLLM 的--port、以及VLLM_NIXL_SIDE_CHANNEL_PORT

lmcache server --port 6555 --http-port 8090 \ --l1-size-gb 100 --eviction-policy LRU --chunk-size 256 --instance-id prefiller CUDA_VISIBLE_DEVICES=6 VLLM_NIXL_SIDE_CHANNEL_HOST=127.0.0.1 VLLM_NIXL_SIDE_CHANNEL_PORT=5600 \ UCX_NET_DEVICES=all NCCL_CUMEM_ENABLE=1 \ vllm serve <model> --port 8001 --enforce-eager --max-model-len 16384 --gpu-memory-utilization 0.4 \ --kv-transfer-config '{"kv_connector":"MultiConnector","kv_role":"kv_producer","kv_connector_extra_config":{"connectors":[{"kv_connector":"NixlConnector","kv_role":"kv_producer","kv_load_failure_policy":"fail"},{"kv_connector":"LMCacheMPConnector","kv_role":"kv_both","kv_connector_extra_config":{"lmcache.mp.host":"tcp://localhost","lmcache.mp.port":6555}}]}}' lmcache server --port 6556 --http-port 8091 \ --l1-size-gb 100 --eviction-policy LRU --chunk-size 256 --instance-id decoder CUDA_VISIBLE_DEVICES=7 VLLM_NIXL_SIDE_CHANNEL_HOST=127.0.0.1 VLLM_NIXL_SIDE_CHANNEL_PORT=5558 \ UCX_NET_DEVICES=all NCCL_CUMEM_ENABLE=1 \ vllm serve <model> --port 8002 --enforce-eager --max-model-len 16384 --gpu-memory-utilization 0.4 \ --kv-transfer-config '{"kv_connector":"MultiConnector","kv_role":"kv_consumer","kv_connector_extra_config":{"connectors":[{"kv_connector":"NixlConnector","kv_role":"kv_consumer","kv_load_failure_policy":"fail"},{"kv_connector":"LMCacheMPConnector","kv_role":"kv_both","kv_connector_extra_config":{"lmcache.mp.host":"tcp://localhost","lmcache.mp.port":6556}}]}}' vllm-router --policy round_robin --vllm-pd-disaggregation \ --prefill http://localhost:8001 --decode http://localhost:8002 --host 0.0.0.0 --port 30000

如需把 trace 与指标导出到本地 OpenTelemetry collector,可给每个lmcache server追加--enable-tracing --otlp-endpoint http://localhost:4317。对应的可观测性参数定义在 lmcache/v1/mp_observability/config.py:--enable-tracing默认关闭,开启 span 订阅者;--otlp-endpoint设置后指标/trace 推送至 OTel collector,未设置时回退到 Prometheus 拉取模式(默认端口 9090,由--prometheus-port控制)。

注意:在单机环境下,NIXL overlocalhost走的是 loopback/TCP 而非 RDMA,因此延迟不具备代表性——单机模式仅用于功能性测试

七、验证部署是否正常工作

先向 router 发送一个补全请求:

curl -s http://localhost:30000/v1/completions -H "Content-Type: application/json" \ -d '{"model":"<model>","prompt":"The capital of France is","max_tokens":16}'

然后从四个角度分别验证各层是否生效:

  • P/D 路由—— 响应id中带有 worker 标记,例如cmpl-___prefill_addr_localhost:8001___decode_addr_localhost:8002_...
  • NIXL 传输—— decode vLLM 日志中出现KV Transfer metrics: NixlConnector={'Num successful transfers': N, ...}
  • LMCache offload—— 查看curl -s http://localhost:8090/status中的storage_manager.l1_manager.total_object_count是否增长。该字段对应 L1 管理器中的对象总数(见 lmcache/v1/distributed/l1_manager.py 的report_status),/status接口由 lmcache/v1/multiprocess/http_apis/info_api.py 提供,返回所有 MP 组件(L1 缓存、L2 适配器、控制器、会话)的内部状态。注意:prompt 至少要达到--chunk-size(默认 256)个 token 才会产生可存储的对象
  • LMCache 命中率—— 读取 vLLM 的"External prefix cache hit rate"日志行(即由 LMCache 提供服务的 prefill token 占比),而不是LMCache server 的/status。当工作集完全容纳在 GPU HBM 中时它保持0,一旦复用溢出 GPU 缓存,该数值才会上升。

八、Kubernetes:使用 Operator 部署

对于 Kubernetes 部署,Operator 可以统一管理 prefiller 与 decoder 两种角色的LMCacheEngineCR,并自动向接入的 vLLM pod 注入MultiConnector配置与 NIXL 环境变量。详见 operator 文档中的 PD Disaggregation 一节。

该节描述了 Operator 的实现机制:在一个LMCacheEngineCR 中增加pd块后,Operator 会生成包含三个 key 的<engine>-connectionConfigMap——kv-transfer-config.json(裸LMCacheMPConnector,作为无pd-role注解 pod 的兜底)、kv-transfer-config-prefiller.jsonMultiConnector+kv_role=kv_producer)、kv-transfer-config-decoder.jsonMultiConnector+kv_role=kv_consumer);webhook 读取 vLLM pod 的lmcache.ai/pd-role注解并注入对应的--kv-transfer-config,同时注入VLLM_NIXL_SIDE_CHANNEL_HOST(经 downward API 取status.podIP)与VLLM_NIXL_SIDE_CHANNEL_PORT(来自spec.pd.nixlSideChannelPort,默认5558;若两种角色同宿且端口需不同,可在 pod env 中预先设置,webhook 会保留原值)。CacheBlendEngine也支持同样的pd块,但采用非对称连接器拓扑。

九、限制与调优建议

  • 高并发下控制冷 KV 传输规模。vLLM 原生 NIXL P/D 路径对大量同时进行的大体积冷传输(整段 prompt 均未缓存)较为敏感。建议让 decode 实例的 GPU KV 缓存足够大以容纳工作集,使传输保持小而可命中缓存;或者当单请求传输较大时降低并发度。

十、总结

P/D 分离把 prefill 与 decode 解耦成可独立扩缩容的两组实例,LMCache MP 则通过MultiConnector把 NIXL 的请求内移交(NixlConnector)与跨请求的缓存复用(LMCacheMPConnector)组合到同一套部署中。掌握了--kv-transfer-config的双层连接器写法、NIXL 环境变量约定、五进程部署顺序,以及响应 ID / NIXL 指标 /total_object_count/ 外部前缀命中率四层验证手段,你就能在生产或本地复现这一架构,并在此基础上叠加 P2P 共享或 Operator 化运维。

【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCache

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 16:17:42

STM32多传感器融合:PPG心率与MPU6050计步系统设计

简介&#xff1a;本资源是一套完整的STM32单片机毕业设计项目&#xff0c;面向电子类、自动化及物联网方向的本科生与进阶学习者&#xff0c;聚焦健康可穿戴设备开发&#xff0c;实现心率脉搏实时监测、运动计步与移动端可视化三大核心功能。项目采用SW-1801P震动传感器采集步数…

作者头像 李华
网站建设 2026/9/16 16:15:33

STM32环境监测实战:20元开发板搭建温湿度烟雾报警系统

简介&#xff1a;面向物联网与嵌入式初学者的家庭环境监测系统完整工程&#xff0c;基于STM32F103C8T6&#xff0c;结合DHT11温湿度传感器、MQ-2烟雾传感器与0.9寸OLED屏&#xff0c;实现数据采集、实时显示与阈值报警。适合毕业设计、课程实训或智能家居入门&#xff0c;覆盖G…

作者头像 李华
网站建设 2026/9/16 16:14:25

毕业论文写作利器paperxie:AI辅助全流程解决方案

1. 毕业论文写作痛点与解决方案作为一名经历过毕业论文"洗礼"的过来人&#xff0c;我深知从选题到答辩的每个环节都充满挑战。记得当年我为了格式调整熬到凌晨三点&#xff0c;查重报告出来时手都在发抖。这种经历促使我深入研究了paperxie这款专为学术写作设计的智能…

作者头像 李华
网站建设 2026/9/16 16:13:55

PLC与伺服系统在高速贴标机中的协同控制方案

1. 项目背景与需求解析贴标机作为包装产线的核心设备&#xff0c;其自动化程度直接影响整线效率。在最近一个饮料产线改造项目中&#xff0c;客户要求实现每分钟120瓶的贴标速度&#xff0c;同时需兼容3种不同瓶型和5种标签规格。这要求PLC不仅要高速处理传感器信号&#xff0c…

作者头像 李华