
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/DecodeP/D分离架构组合部署prefill 与 decode 实例分别运行、通过 NIXL 完成 KV 移交同时每个实例旁的 LMCache server 提供跨请求的 KV 缓存复用。读完本文你将掌握 P/D 分离的完整工作原理、MultiConnector双层连接器配置、多机与单机两种部署命令以及通过响应 ID、日志指标和 HTTP 状态接口验证部署是否正常工作的全套方法。一、什么是 P/D 分离LMCache MP 叠加了什么Disaggregated prefillP/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 移交走 NIXLUCX / RDMALMCacheMPConnector向实例对应的 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-config的kv_connector_extra_config字段与 LMCache server 建立连接。二、工作原理最小部署由五个进程组成一个最小可用的 P/D 分离 LMCache MP 部署包含五个进程Prefill vLLM生产者 producer—— 连接器配置为MultiConnector[NixlConnector (kv_producer), LMCacheMPConnector]。它计算 prompt 的 KV将 KV 存入自己的 LMCache server并通过 NIXL 暴露给 decoder 拉取。Decode vLLM消费者 consumer—— 连接器配置为MultiConnector[NixlConnector (kv_consumer), LMCacheMPConnector]。它从 producer 拉取 prompt KV 并生成输出。两个 LMCache server—— 每个 vLLM 实例对应一个独立的lmcache server进程二者不能共用一个 server。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 会拉取nixl1.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_connectorMultiConnector并行运行kv_connector_extra_config.connectors中列出的子连接器kv_rolekv_producerprefill或kv_consumerdecode在顶层MultiConnector和嵌套的NixlConnector上都要设置NixlConnector负责 prefill→decode 移交。设置kv_load_failure_policyfail使传输失败直接暴露出来而不是静默地退化为重新计算LMCacheMPConnector负责向本机 LMCache server 卸载/加载 KV使用kv_rolekv_bothlmcache.mp.host/lmcache.mp.port实例对应 LMCache server 的传输地址与 ZMQ--port每个实例各不相同NIXL 传输通过 vLLM 实例上的环境变量进行调优VLLM_NIXL_SIDE_CHANNEL_HOST—— 握手handshake时对外宣告的地址需被对端可达VLLM_NIXL_SIDE_CHANNEL_PORT——同一主机上的实例之间必须使用不同端口默认5600UCX_NET_DEVICESall与NCCL_CUMEM_ENABLE1。LMCacheMPConnector的kv_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/portlmcache.mp.host—— 单 server 部署的 host默认tcp://localhostlmcache.mp.port—— 单 server 部署的端口默认5555lmcache.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 prefillerStep 2 —— prefill vLLM生产者 producer在 prefill 主机上执行VLLM_NIXL_SIDE_CHANNEL_HOSTPREFILL_IP VLLM_NIXL_SIDE_CHANNEL_PORT5600 \ UCX_NET_DEVICESall NCCL_CUMEM_ENABLE1 \ 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 decoderStep 4 —— decode vLLM消费者 consumer在 decode 主机上执行VLLM_NIXL_SIDE_CHANNEL_HOSTDECODE_IP VLLM_NIXL_SIDE_CHANNEL_PORT5558 \ UCX_NET_DEVICESall NCCL_CUMEM_ENABLE1 \ 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之后把请求发送到 routerhttp://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—— 淘汰策略可选LRU、IsolatedLRU、noop必填其中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_DEVICES6 VLLM_NIXL_SIDE_CHANNEL_HOST127.0.0.1 VLLM_NIXL_SIDE_CHANNEL_PORT5600 \ UCX_NET_DEVICESall NCCL_CUMEM_ENABLE1 \ 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_DEVICES7 VLLM_NIXL_SIDE_CHANNEL_HOST127.0.0.1 VLLM_NIXL_SIDE_CHANNEL_PORT5558 \ UCX_NET_DEVICESall NCCL_CUMEM_ENABLE1 \ 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.jsonMultiConnectorkv_rolekv_producer、kv-transfer-config-decoder.jsonMultiConnectorkv_rolekv_consumerwebhook 读取 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),仅供参考