跳转到主要内容

P/D 分离:从 KV 交接到路由、背压与 SLO

固定 Dynamo 1.5.1 与 LMCache 0.5.5,区分控制面和 KV 数据面,分析交接合同、cache routing、过载与公平性能对照

· 约 8 分钟阅读

本文目录

Prefill 与 Decode 放在不同 worker pools,可以分别选择并行度、调度预算和扩容策略,减少长 prompt 对流式输出的干扰。代价是请求需要跨执行实例交接状态,并同时面对两处排队、传输与失败。

本页固定 Dynamo 1.5.1 2093662a4d4e5fd318732935213dde08dc7be818 的架构/路由文档,以及 LMCache 0.5.5 05a013b29da78cf2321b9b46ec5039dde2fb0bb0 的 MP 组合文档。先读 批处理与调度 和 推理框架;这里解释部署合同与测量方法,不提供已经验证的 GPU 性能结论。

30 秒复习
  • 一句话:P/D 用阶段隔离与独立资源配置换取服务稳定性,但必须支付可见的状态交接与两阶段排队成本。
  • 三个判断:控制面携带握手 metadata,数据面搬 KV;当前请求交接与跨请求缓存复用分开;相同总 GPU 和 SLO 下比较 goodput 才能判断收益。
  • 核心模型:TTFT≈QP+TP+Thandoff,critical+QD+Trestore/firstTTFT\approx Q_P+T_P+T_{\text{handoff,critical}}+Q_D+T_{\text{restore/first}},重叠部分只算一次;各项顺序由 backend 决定。
  • 边界:vLLM、SGLang、TensorRT-LLM 的交接流程与状态支持不同;router、KVBM、planner 的名字不代表所有能力默认启用。

1. 请求经过两种流

sequenceDiagram
    participant C as Client
    participant R as Frontend / Router
    participant P as Prefill worker
    participant D as Decode worker
    C->>R: prompt 与请求参数
    R->>P: 选择 P、执行 prefill
    P-->>R: disaggregated_params / handshake metadata
    R->>D: 请求与交接 metadata
    D->>P: 协调 KV transfer
    P-->>D: KV 数据面
    D-->>C: 经 frontend 返回生成 tokens
图 1 · Dynamo 文档中 vLLM 风格的交接简图。Router 传递控制信息,KV 在 workers 间传输;不表示 Router 代理全部 KV bytes。SGLang bootstrap 与 TensorRT-LLM 的内部路径不同。来源:固定版本 disaggregated serving 架构文档;机制示意。

该路径通常由 P 生成 KV 与 disaggregated_params,再让 D 协调读取。SGLang 的 bootstrap_info 可以让 P 在后台继续并允许交接重叠;vLLM 文档路径先同步完成 prefill,再进入 decode 交接;TensorRT-LLM 的部分细节由 backend 内部管理。不能用这幅简图推断所有 backend 的每层传输、首 token 归属或时序。

Dynamo 集成 frontend 在同一 namespace/model 发现兼容的 typed P/D 服务时,可建立两阶段路由。独立 Python router API不是自动组装两阶段 serving 的同义词,需调用者显式编排。部署笔记应写明使用哪一种入口,而不是只写“开启 Dynamo”。

2. 完整交接不止一份 KV

状态为什么需要验证方法
KV payload、dtype/scales、block/rank layoutD 必须正确解释 P 的产物记录两端 resolved 配置和实际 bytes,验证 connector 兼容性
token frontier 与位置D 要知道下一步从哪里开始对比完整 prefill 的起始 decode 状态,检查边界重复/遗漏
backend 特殊状态压缩、SWA、recurrent state 可能有独立生命周期用模型对应边界用例验证,不套用 dense KV 假设
n-gram / draft historyEngram 与投机路径可能还需 token history明确由请求 tokens 重建、metadata 传递还是 backend 自行恢复
request ownership / completion发送端 blocks 不能提前释放,失败要有结果追踪 transfer 完成、block release 与取消/重试事件

特别是 DeepSeek V4.1 Runtime:compressed cache、SWA replay、Engram 的 token history 不是同一对象。Engram 的静态权重在各 worker 加载,当前请求的 n-gram history 属于动态状态;同机 DP 共享权重不会自动为 P/D 恢复这个 history。

支持某模型的普通 serving,不代表某 connector 已支持该模型的全部 P/D 状态。不同 TP/PP 布局之间是否允许交接,也由 backend 的重分片能力决定。本页不预设 DeepSeek V4.1 已在这里列出的组合上通过 GPU 验证。

3. 两类 KV 流可以组合,但目的不同

机制复用对象生命周期典型路径
P → D handoff当前请求刚算出的 prompt 状态本次请求的交接窗口NixlConnector
外部分层复用先前请求留下的兼容状态跨请求、跨 HBM 驱逐LMCacheMPConnector 或其他分层系统

LMCache 0.5.5 MP 文档用 MultiConnector[NixlConnector, LMCacheMPConnector] 组合这两条路径。最小部署是 五个进程:P engine、D engine、每个 engine 各自的 LMCache server,以及 router。该文档要求两个 engine 不共用同一个 server;跨 pools 的复用可另加 P2P coordinator,不因启用 NIXL 交接而自动发生。

固定文档还明确要求 vLLM MultiConnector real-blocks 修复:缺失时 LMCache offload 可能根本不提交。集成验收要看 store completion 与对象增长,不能以 connector 初始化日志代替能力验证。

为观察交接失败,文档示例给 NIXL 设置 kv_load_failure_policy=fail。实验中若允许失败后重算,输出正确并不能证明交接成功;应把这部分请求计入 fallback,而不是 transfer hit。单机 loopback 示例用于功能检查,不代表跨节点 RDMA 性能。

分层 KV 的命中与写入策略另见 分层 KV Cache。

4. 路由不只是“选命中最多的 worker”

对 P,长 prefix 复用可能省大量计算;对 D,需要足够的 KV 容量和持续输出预算。还要考虑两者之间的 transfer domain:同机 NVLink、跨机 RDMA、拓扑不合适时的路径,不能只选一个看起来最空闲的 worker。

Dynamo 1.5.1 文档区分实际 KV events 与预测状态。缺少 events 且没有启用相应 predicted 模式时,KV 路由可能退化为 load-only;不能把 router 的 cache score 当作实时、准确的命中证明。

P/D 路由参数也按阶段改变:P 侧不按 D 的长期 active KV blocks 模型计负载;D 侧 overlap score 为零,并默认不假设沿普通 aggregated routing 方式复用 KV。backend 的重复交接优化需另查。直接复制 aggregated 配置,可能把负载含义解释错。

一个合理选择模型是:

argmin⁡p,d(Q^P(p)+T^P(p,prefix)+T^handoff(p,d)+Q^D(d))\operatorname*{argmin}_{p,d} \left(\widehat Q_P(p)+\widehat T_P(p,\text{prefix})+ \widehat T_{\text{handoff}}(p,d)+\widehat Q_D(d)\right)

帽号表示预测;还需满足容量、兼容性与 SLO 约束。这是分析模型,不声称 Dynamo 默认精确求解此式。实际路由误差应通过预测值与请求实际经历对照校准。

5. 背压、扩容与故障要写出条件

能力固定版本的边界要记录的证据
两阶段失败P 已派发后失败会向请求暴露,不自动把同一失败请求切回 aggregated失败阶段、重试次数、响应码
busy / rejection文档中的阈值是可选配置,不能假定所有默认启用frontend 过滤、worker hard cap、实际 reject 数
planner默认 throughput 目标使用 queue/KV 等阈值;SLA 策略是另一路径实际策略、TTFT/ITL 目标、估算器与扩缩事件
分层 KV 支持KVBM 在不同 backend 的支持矩阵不同,1.5.1 对 SGLang 仍有限制对应 backend 的支持表与集成测试

P 算得更快而 D 长期拥塞时,继续扩 P 可能只会制造更多等待交接和被占用的 KV。背压应回答:何处拒绝新请求、已产出 KV 存多久、取消后谁释放、扩容需要多久。单看 P/D 两个池的平均 GPU utilization 无法回答这些问题。

6. 从 TTFT 到满足 SLO 的完成量

TTFTPD≈QP+TP+Thandoff,critical+QD+Trestore/firstTTFT_{PD}\approx Q_P+T_P+T_{\text{handoff,critical}}+ Q_D+T_{\text{restore/first}}

其中 handoff 只计暴露在请求关键路径上的区间,restore/first 包括状态就绪后的必要工作和首 token 返回。若实现把 D 排队与传输重叠,应按时间线合并区间,不把各组件的 wall time 直接相加。

分离的潜在收益包括:减少 prefill 对 decode 的干扰、提高阶段内 batching 效率、分别选择 TP/DP,并独立扩容。对很短 prompts、低并发或低带宽连接,新增传输与两处排队也可能主导 TTFT。

比较时固定总 GPU 数、型号、模型精度、输入/输出分布与 SLO。Aggregated 8 卡对 PD 的 P 8 卡 + D 8 卡不是资源相同的对照;若采用不同资源,要报告 GPU-seconds/request 与成本,不能把新增资源收益全记作架构收益。

实验用途必须一起报告
Aggregated vs PD,cold prefix测隔离与交接净收益P/D 队列、交接 bytes/时间、TTFT/ITL p50/p95/p99
短/长 ISL × 短/长 OSL找到阶段比例的适用区间固定 token 分布与 completed requests
提高到达率,保持总 GPU观察 overload 与稳定点offered rate、goodput、reject/timeout/fallback
相同 prefix 工作集,开/关外部复用隔离分层 KV 的增益GPU/external hits、load/store 流量
P:D 资源比例扫描判断真正应扩的池per-pool queue、KV occupancy、每卡 goodput

这里的 goodput 必须写出定义,例如每秒完成且同时满足 TTFT ≤ xx、ITL p95 ≤ yy 的请求数,并给出 x,yx,y 的数值。Streaming 请求还应声明 ITL 的统计层次、首间隔和最后 token 如何处理。失败、超时与重算回退单列,避免只保留成功快请求。

相关页面

来源与复核

修改历史1 次提交