vLLM Prefill-Decode 解耦与 MORI-IO
vLLM 已在单节点部署中引入 Prefill-Decode(PD)解耦,实现了在 8-GPU AMD Instinct MI300X 节点上 2.5 倍的有效吞吐量提升。通过将计算受限的预填充阶段与内存带宽受限的解码阶段分离,vLLM 消除了这些工作负载在同一 GPU 资源竞争时通常出现的跨标记延迟(ITL)峰值。
同时部署的瓶颈
在标准的单体部署中,预填充和解码工作负载共享相同的 GPU 资源和调度器。由于预填充使用大规模 GEMM 并行处理整个提示,它受计算限制,耗时远长于单个解码步骤。当预填充请求进入批次时,会阻塞所有正在进行的解码流,导致跨标记延迟(ITL)出现不可预测的峰值。
单节点 PD 解耦架构
与解耦必须使用多节点集群的常见假设相反,vLLM 在单个 8-GPU 节点内实现了该架构。系统转向微服务架构,由三个组件组成:
- Prefill 实例: 处理输入提示并生成 KV 缓存(例如使用 GPU 0–3)。
- Decode 实例: 使用已转移的 KV 缓存生成输出标记(例如使用 GPU 4–7)。
- Proxy 服务器: 作为入口点,先将请求路由到预填充实例,再路由到解码实例。
为在这些实例之间传输数 GB 的 KV 缓存数据,vLLM 使用 MORI-IO,这是一种基于 RDMA 的 KV 缓存连接器,构建于开源 MORI(Modular RDMA Interface)框架之上。
KV 缓存传输模式:读取 vs 写入
MORI-IO 支持两种不同的传输模式,可通过 VLLM_MORIIO_CONNECTOR_READ_MODE 环境变量进行配置:
读取模式 (VLLM_MORIIO_CONNECTOR_READ_MODE=1)
在读取模式下,代理串行分发请求。它等待预填充实例完成并返回 remote_block_ids 后,才将请求转发给解码实例。解码实例随后通过 RDMA 从预填充实例的内存中拉取 KV 缓存。
写入模式(默认)
在写入模式下,代理同时向预填充和解码实例分发请求。随着预填充实例计算每一层,它会通过 RDMA WRITE 将 KV 数据直接写入解码实例预先分配的内存中。此方式消除了代理的序列化开销,并使解码队列等待能够与预填充计算重叠。
| 属性 | 读取模式 | 写入模式 |
|---|---|---|
| RDMA 方向 | 解码从预填充拉取 | 预填充推送到解码 |
| 代理分发 | 串行(等待预填充 → 分发解码) | 并行(预填充和解码并行) |
| 块 ID 中继 | 需要通过代理 | 不需要 |
| KV 清理 | 解码通知预填充释放块 | 预填充跟踪写入完成 |
性能结果与吞吐量
使用 Qwen3-235B-A22B-FP8 模型在 8-GPU MI300X 节点上(2000 标记提示,1000 标记输出),vLLM 通过 goodput(有效吞吐量)衡量性能——即在满足首标记时间(TTFT)< 1 秒且 ITL < 50 毫秒的前提下,能够达到的最大请求率。
关键发现
- 2.5 倍吞吐量提升: 写入模式在 8 req/s 的速率下实现 73/100 请求满足 SLO,而标准 TP8 服务仅为 26/100。
- 消除 ITL 峰值: 解耦模式完全消除了 ITL 违规,因为解码引擎与计算密集型预填充作业隔离。
- TTFT 权衡: 由于额外的 RDMA 传输和代理开销,解耦会增加 TTFT。写入模式比读取模式提供更好的 TTFT,因为它消除了代理序列化。
部署与配置
部署 PD 解耦需要在 vLLM 中配置 kv-transfer-config。两个实例都必须指定 MoRIIOConnector 并设置各自的角色(预填充使用 kv_producer,解码使用 kv_consumer)。
端口要求
proxy_ping_port:用于实例向代理注册的 ZMQ 端点。http_port:vLLM HTTP 服务器的推理请求端口。handshake_port:一次性元数据交换,用于 KV 缓存布局。notify_port:每个请求的同步信号,用于指示 KV 块已就绪。
用例汇总
| 情形 | 建议 |
|---|---|
| 生产负载下 ITL p99 超过 SLO | 解耦 |
| TTFT 是主要约束 | 标准服务 |
| 高并发长提示 | 解耦 |
| 低请求率短提示 | 标准服务 |