
PD 分离到底该配多少 P 和 D?
做 PD 分离时,最容易问错的问题是:P:D 有没有一个标准答案?
没有。1:3、1:1、3:1 都可能合理。比例不是先定下来的架构参数,而是模型、硬件、流量和 SLO 算出来的容量结果。
网上常有人把 SGLang 的 96 张 H100 实验解读成固定的 P:D 配比。其实原文分别用 4 个节点测 Prefill、9 个节点测 Decode,而且明确说两边是独立压测,假设另一阶段资源无限。那组数据说明两侧各自能跑多快,不是一个线上集群的固定比例。
真正要算的只有两本账:
业务每秒给 P、D 分别制造多少工作?
一张卡或一个完整实例,能在 SLO 内处理多少工作?
用前者除以后者,卡数就出来了。
P 和 D 不是同一种负载
Prefill 一次处理整段输入,矩阵乘规模大,通常更吃计算;Decode 每一步只生成少量 Token,却要持续读取权重和历史 KV,并长期保存请求状态,通常更受显存容量、带宽和通信影响。
| 阶段 | 主要工作 | 最先关注 | 核心指标 |
|---|---|---|---|
| Prefill | 处理输入 Token,生成首份 KV | 计算吞吐、通信 | TTFT、input token/s |
| Decode | 持续生成 Token,持有并扩展 KV | KV 容量、带宽、通信 | TPOT/ITL、并发、output token/s |
所以输入越长,P 的工作通常越重;输出越长,请求在 D 里停留越久,D 的压力越大。长文档短回答偏 P,长推理、长生成偏 D,并不矛盾。
还有一个容易漏掉的点:长输入不只影响 P。Prefill 结束后,整段输入对应的 KV 会进入 D,因此它也会吃掉 D 的初始 KV 容量。
先定实例形状,再算实例数量
1. 权重能不能装下
权重显存先按下面的式子估:
300B FP8 权重大约是 300GB。两张 141GB H200 合计 282GB,连纯权重都放不下,更不用说运行时缓冲区和 KV Cache,因此实例至少要从 4 卡起步。
MoE 要分清两件事:权重存储看总参数量,单 Token 计算量主要看激活参数量。专家没有被当前 Token 选中,不代表它可以不放进显存。
2. 一个请求要占多少 KV
普通 MHA/GQA 模型可以先这样估:
这里的 2 是 K 和 V, 是每个 KV 元素的字节数。
DeepSeek-R1/V3 使用 MLA,必须按压缩潜变量和推理框架的实际缓存布局计算,不能直接套 MHA/GQA 公式。
3. D 先过显存,再过 TPOT
实例中可用于 KV 的显存是:
显存能容纳的并发上限为:
但放得下不等于跑得动。并发增加以后,每个 Decode Step 要读取更多权重和 KV,还要承担 TP/EP 通信。最终并发要取显存上限和 SLO 上限的较小值:
不适合只靠纸面带宽反推。它受 Batch、上下文、Kernel、量化、并行方式和通信影响,应该直接从目标 TPOT/ITL 下的 Profiling 结果里取。
4. P 看目标 TTFT 下的有效吞吐
稠密模型的 Linear 计算量可以粗略按每 Token 估算:
因此单卡 Prefill 产能可先估为:
MoE 的 主要看激活参数,还要补上 Attention、Router、All-to-All 和其他运行时开销。
这个公式只适合给初始量级。真正用于规划的 ,应该是目标 ISL、Batch 和 TTFT 下实测出来的 Goodput。TP 也不是越大越好:加卡可能缩短单请求 Prefill 时间,但通信开销会上升,单位卡吞吐未必更高。
配比公式其实很简单
设请求到达率为 ,平均有效输入长度为 ,平均输出长度为 ;P、D 每卡在 SLO 内的实测产能分别为 和 。
那么两侧卡数是:
两式相除:
这就是 P:D 的来源:一半由模型、硬件、并行和 Kernel 决定,另一半由业务的输入输出比例决定。
在比例里约掉了,但它仍然决定绝对卡数。Prefix Cache 命中后,P 真正需要计算的输入 Token 会减少,所以这里用的是 ;D 侧仍要按实际驻留的完整上下文核算 KV。
为了只看输入输出比例,先暂时固定 和 。假设某组 Profiling 得到:
P:1300 input token/s/GPU
D:3750 output token/s/GPU
那么:
| 流量 | 输入:输出 | 理论 P:D |
|---|---|---|
| 等长对话 | 1K:1K | 2.88:1 |
| 长文档短回答 | 8K:1K | 23:1 |
| 长推理、长生成 | 1K:8K | 1:2.8 |
这组数字只演示公式,不是推荐配置。真实环境中输入变长也会增加 D 的 KV 水位, 不会始终保持 3750;模型、Batch 和 TPOT 目标变化时,两侧产能同样要重新测。
用 Little’s Law 再校验一次 D
吞吐账算完后,还要看 D 池会积累多少请求。
请求在 D 中的平均停留时间近似为:
根据 Little’s Law:
每秒 10 个请求、平均输出 1000 Token、TPOT 20ms,D 池平均会有约 200 个活跃请求。输出增至 8000 Token,其他条件不变,并发会增至约 1600。
这个结果应该和“D 实例数 × 单实例有效并发”大致对得上。差得太多,通常是输出长度分布、TPOT、排队时间或单实例并发估错了。
KV 容量要看 P95/P99 上下文,平均吞吐则要看时间加权后的真实分布。长请求占比不高却特别吃显存时,单独分池通常比全局按 P99 预留更划算。
生产上按这个顺序落地
- 画像流量:统计峰值请求率、ISL、OSL、上下文分布、Prefix Cache 命中率和 TTFT/TPOT SLO。
- 确定 D 实例形状:先装下权重,再算 KV 容量,最后压测目标 TPOT 下的有效并发。
- 确定 D 数量:用输出 Token Goodput 算一次,再用 Little’s Law 从并发侧校验。
- 确定 P 形状和数量:根据 TTFT 选并行组,用实测 Prefill Goodput 计算实例数。
- 按完整实例取整:P 是 TP=8、D 是 TP=4 时,都不能部署半个实例。
- 加余量后压测:考虑故障、突发流量、Kernel 波动和长尾请求,最终看满足 SLO 的 Goodput,而不是裸吞吐。
纸面计算负责给出第一版配置,最终比例必须由目标流量回放决定。
Decode 有状态,还能不能扩缩容
可以,但不是无成本迁移。
D 池可以增加完整的 Decode 副本,让新请求进入新副本。缩容时,先把目标副本摘流,再等待存量请求结束;如果系统支持请求迁移,也通常是把 Prompt 加已生成 Token 重新提交,在新 Worker 上重建 KV,而不是把运行中请求的 GPU KV、CUDA 状态原封不动搬过去。
所以准确的边界是:
D 池可以做副本级弹性
≠
运行中请求的 GPU KV 可以无缝实时迁移
面试时怎么讲
我不会先拍一个 1:1 或 1:3。先用权重显存确定 P、D 的实例形状,再分别测两侧在目标 SLO 下的单位产能。P 卡数等于每秒输入 Token 量除以 P 每卡 Goodput,D 卡数等于每秒输出 Token 量除以 D 每卡 Goodput,所以 P:D 等于 D/P 每卡产能比乘有效输入/输出长度比。
D 还要额外过两道约束:显存能容纳多少 KV,以及这些并发下 TPOT 能否达标,最终取两者的最小值。然后用 Little’s Law 校验整个 D 池的并发:到达率乘平均输出长度再乘 TPOT。
因此长输入短输出通常偏 P,长推理、长生成通常偏 D。最后还要考虑 MLA、MoE、Prefix Cache、完整并行组取整和故障余量,用真实流量压测,不能照抄别人的比例。
封面摄影:mos design,拍摄于日本东京池袋。图片来源:Unsplash,按 Unsplash License 使用。