从单体到分体:为什么大模型推理正在走向 Prefill/Decode 分离部署?
2024 年下半年以来,大模型推理架构迎来了一个新的趋势——PD 分离部署(Prefill/Decode Disaggregation)。简单来说,就是将传统推理引擎中混部在同一个 GPU 上的 Prefill(预填充/首Token生成)阶段与 Decode(逐Token续写)阶段,分别部署到不同规格的 GPU 集群上,中间通过高速网络传输 KV Cache 实现衔接。
这一架构被 vLLM、SGLang、TensorRT-LLM 等主流推理框架陆续采纳,并在 DeepSeek、Anthropic 等公司的生产环境中落地。它解决了传统混部部署下长期存在的资源冲突问题。本文将从底层原理出发,逐层拆解 PD 分离的设计动机、实现要点与落地效果。

混部架构的困境:Prefill 和 Decode 为什么合不来?
在传统混部架构中,每张 GPU 同时处理多个请求的 Prefill 和 Decode 阶段。Continuous Batching 技术让同一个 GPU 上可以混合执行不同阶段的计算。表面上看似高效,实则隐藏着严重的资源冲突。
Prefill 阶段:计算密集型
Prefill 阶段处理用户输入的 prompt,需要对所有 token 并行计算注意力矩阵。对于长 prompt(例如 8K-128K tokens),这是一个巨大的矩阵乘法运算:Q · K^T 的维度为 (num_queries × seq_len),计算量占比接近整个推理过程的 60%-80%。这个阶段对 GPU 的算力(TFLOPs)极度敏感,通常需要大批量的矩阵乘来填满 Tensor Core。
Decode 阶段:访存密集型
Decode 阶段每次只生成一个 token,需要从 KV Cache 中读取过往的所有 Key 和 Value 向量来与当前 Query 计算 Attention。这里的问题是:计算量极小(一个 query 向量与所有 KV 向量的点积),但需要从 HBM 读取整个 KV Cache。以 70B 模型为例,单次 Decode 需要加载约 128 MB 的 KV Cache 数据,但实际计算量不到 1 TFLOP。这导致 GPU 的计算单元大部分时间处于空闲状态,瓶颈完全在 HBM 带宽上。
| 维度 | Prefill 阶段 | Decode 阶段 |
|---|---|---|
| 计算特性 | 计算密集型(Compute Bound) | 访存密集型(Memory Bound) |
| 核心瓶颈 | Tensor Core TFLOPs | HBM 带宽 |
| Batch size 偏好 | 大 Batch(提高算力利用率) | 小 Batch(减少显存争抢) |
| KV Cache 需求 | 写入为主(新建) | 读取为主(反复加载) |
| 对显存容量的要求 | 中等 | 高(需要缓存所有活跃序列) |
当 Prefill 和 Decode 混部在同一 GPU 上时,问题就出现了:Prefill 阶段为了追求算力利用率,倾向于拉大 Batch Size,一次性吃掉大量显存和计算资源;而 Decode 阶段则因为访存瓶颈,需要较低的 Batch Size 来保证单次延迟。两者在同一张卡上争夺同一个 SM(Streaming Multiprocessor)调度器和 HBM 带宽,结果就是——Prefill 大 Batch 阻塞了 Decode 的小请求,Decode 的 KV Cache 占住了显存让 Prefill 无法申请更大的 Batch。TTFT(Time to First Token)和 TPOT(Time Per Output Token)双双恶化。
PD 分离的核心架构:拆开看就是数据流
PD 分离部署的基本思路很直观:把 Prefill 节点和 Decode 节点拆成独立的 Server 集群,中间通过 NCCL 或 RDMA 传输 KV Cache。
架构组件
- Router / Load Balancer:接收客户端请求,按 prompt 长度、当前各节点负载分发到 Prefill 节点。
- Prefill 节点池:高算力 GPU(如 H100、A100 80GB),配大 Batch Size 来最大化算力利用率。Prefill 完成后生成完整的 KV Cache 并通过网络发送给 Decode 集群。
- KV Cache 传输层:NVLink/NVSwitch 用于机内传输,InfiniBand/RoCE 用于跨机传输。这里的关键是 KV Cache 的序列化和反序列化开销不能成为新瓶颈。
- Decode 节点池:高带宽 GPU 或专门的推理卡。每个节点维护自己负责的 KV Cache 分片。Decode 节点之间也需要互相通信来支持推理时的张量并行。
- KV Cache Router:决定将每个请求的 KV Cache 存储在哪个 Decode 节点上。哈希路由是一种简单的策略,但也有人用一致性哈希来实现负载均衡。
数据流全景
1
2
3
4
5
6
7
8
9
10
11
12
13 客户端请求
│
▼
Router ──→ Prefill Node (Prompt 8K → KV Cache)
│ │
│ ▼ (序列化 KV Cache)
│ NCCL / RDMA 传输
│ │
│ ▼ (反序列化)
└──→ Decode Node ──→ Token 1 → Token 2 → ... → Token N
│
▼ (增量更新 KV Cache)
返回流式结果
KV Cache 传输:PD 分离的阿喀琉斯之踵
Prefill 节点完成处理后,需要把完整的 KV Cache 传输给 Decode 节点。当模型规模达到 70B、序列长度达到 32K 时,单个请求的 KV Cache 可以达到数百 MB。如果不做优化,网络传输成为新的瓶颈,PD 分离带来的收益将被抵消殆尽。
KV Cache 量化
在传输之前对 KV Cache 进行 INT8 甚至 INT4 量化是最直接的优化手段。以 70B 模型、32K 序列为例:
1
2
3 FP16 KV Cache 大小 = 2 (K+V) × 80 (layers) × 32K (seq) × 128 (head_dim) × 2 (bytes) ≈ 1.3 GB
INT8 KV Cache 大小 = 同上 ÷ 2 ≈ 650 MB
INT4 KV Cache 大小 = 同上 ÷ 4 ≈ 325 MB
量化到 INT8 即可将传输数据量砍半。当然,KV Cache 量化会带来精度损失,需要通过 KVCache Quantization-Aware Scaling (KQAS) 或 Per-Channel Scaling 来缓解。
异步传输与流水线重叠
Decode 节点在收到第一个 KV Cache chunk 后就可以开始生成第一个 Token,无需等待完整传输完成。这种 pipelined KV transfer 技术把传输和解码的执行重叠起来,隐藏了网络延迟。
1
2
3 时间线:
Prefill_0: [计算]→[传输Chunk1]→[传输Chunk2]→[传输Chunk3]
Decode_0: [接收Chunk1]→[Token1]→[接收Chunk2]→[Token2]→...
KV Cache 预取与缓存
对高频出现的 prefix(例如系统 prompt、固定上下文)可以在 Decode 节点上做 KV Cache 缓存,避免重复传输。结合 RadixAttention(vLLM 引入的 prefix caching 技术),命中缓存的请求可以跳过 Prefill 节点直接进入 Decode 节点,进一步降低延迟。
负载调度策略:Prefill 和 Decode 如何协同?
PD 分离后,全局调度器需要在 Prefill 和 Decode 节点之间协调负载。常见策略包括:
基于 Prompt 长度的自适应路由
短 prompt(< 1K tokens)的 Prefill 开销小,可以直接在 Decode 节点上完成以节省一次网络传输。长 prompt 则路由到专门的 Prefill 集群。这种策略也被称为 Hybrid PD,在实际生产中很常见。
动态 Prefill 切分
当请求数量过大时,将单个请求的 Prefill 计算切分到多个 Prefill 节点上并行执行,然后合并 KV Cache。这与张量并行的思路类似,但由于 Prefill 节点无状态,切分的调度粒度更灵活。
请求级优先级队列
交互式应用(如聊天机器人)对 TTFT 敏感,流式应用(如翻译、摘要)对 TPOT 敏感。调度器维护多个优先级队列,高优交互请求的 Prefill 资源优先保障,流式任务填入空闲计算槽位。
| 调度策略 | 适用场景 | 优势 | 代价 |
|---|---|---|---|
| Hybrid PD | Prompt 长度分布较广 | 短请求省去网络传输 | 短请求占用 Decode 算力 |
| 动态 Prefill 切分 | 长 Prompt 密集到达 | 减少请求排队时间 | 增加 KV 合并开销 |
| 优先级队列 | 延迟敏感 + 吞吐型混合负载 | 确保 SLA 达标 | 需要准确的延迟预测 |
| KV Cache 感知调度 | Prefix 高频复用场景 | Cache 命中率最大化 | 调度器复杂度高 |
业内实践:从 vLLM 到 DeepSeek 的落地
vLLM 的 PD 分离实现
vLLM v0.6.0 引入了对 PD 分离的原生支持。通过部署独立的 Prefill 和 Decode 实例,中间通过
1 | --kv-transfer-config |
参数配置 NCCL 传输通道。vLLM 的实现特点是利用 共享内存(Shared Memory)进行机内 KV Cache 传输,避免了额外的序列化开销。对于跨机场景,则使用 NCCL 的
1 | ncclSend |
/
1 | ncclRecv |
原语直接传输 GPU 显存间的数据,避免了 CPU 内存拷贝。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 # Prefill 实例启动示例
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--port 8100 \
--worker-use-ray \
--pipeline-parallel-size 1 \
--tensor-parallel-size 8 \
--kv-transfer-config '{"kv_connector":"NcclConnector","kv_role":"kv_producer","kv_rank":0,"kv_parallel_size":8}'
# Decode 实例启动示例
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--port 8200 \
--worker-use-ray \
--pipeline-parallel-size 1 \
--tensor-parallel-size 8 \
--kv-transfer-config '{"kv_connector":"NcclConnector","kv_role":"kv_consumer","kv_rank":0,"kv_parallel_size":8}'
DeepSeek 的 PD 分离实践
DeepSeek 在技术博客中详细阐述了他们在生产环境中的 PD 分离方案(DeepSeek-V2 推理优化)。他们的做法有几个关键点:
- Multi-Head Latent Attention(MLA):通过低秩压缩将 KV Cache 大小减少到传统 MHA 的 1/8,极大降低了 PD 传输的负担。
- 两层调度:第一层是全局的请求分发层,用一致性哈希将请求映射到 Prefill 组;第二层是 Prefill 组内的细粒度负载均衡。
- Prefill 结果预取:利用 DeepSeek 自身对用户输入模式的统计,提前预热 KV Cache 缓存。
- 独立 Prefill 集群:用 H800 80GB 作为 Prefill 节点,用更经济的高带宽 GPU(如 L40S)作为 Decode 节点,实现成本的差异化配置。
SGLang 的 RadixAttention 加持
SGLang 利用其 RadixAttention 前缀树结构,天然适合 PD 分离场景。Prefill 阶段产出的 KV Cache 以 Radix Tree 的形式组织,Decode 节点接收到的是 prefix + 增量的组合。当多个请求共享了相同的前缀(例如系统 prompt),SGLang 可以实现零成本的 Prefix Cache 复用,完全不传输已缓存的部分。
硬件层面的考量:网络和 GPU 选择
PD 分离部署对硬件提出了新的要求:
- Prefill 节点:优先选择算力最强的 GPU(H100/H200/B200),且显存容量不需要太大(80GB 足够),因为 KV Cache 会立即传输出去。NVLink 域内通信延迟低于跨机,所以尽量在单机内完成 Prefill 的张量并行。
- Decode 节点:需要高 HBM 带宽(缓解访存瓶颈)和大容量显存(容纳多个请求的 KV Cache)。H200(141GB HBM3e, 4.8 TB/s)比 A100(80GB, 2 TB/s)更适合 Decode 场景。也可以考虑用 Grace Hopper Superchip(CPU + GPU 共享内存池)来进一步降低 KV Cache 的搬运开销。
- 网络:Prefill 到 Decode 的跨机传输需要低延迟高带宽。400Gbps InfiniBand NDR 或 800Gbps InfiniBand 是推荐配置。如果使用 RoCE v2,需要确保 PFC 和 ECN 配置正确,避免丢包导致的传输抖动。
什么时候不该用 PD 分离?
PD 分离不是放之四海皆准的方案。以下场景需要谨慎评估:
- 模型体积较小(< 7B 参数):小模型的 Prefill 和 Decode 资源差异不明显,单独部署的运维成本可能超过收益。
- 平均 Prompt 很短(< 512 tokens):短 prompt 的 Prefill 计算量小,KV Cache 传输开销占比较高。
- 仅有少量 GPU 可用(< 8 张):在 GPU 资源有限时拆成两组会导致算力碎片化,每一端的并行度都不够。
- 流量波动剧烈:如果 Prefill 和 Decode 的配比需要频繁调整,静态分离不如动态混部灵活。此时考虑 Elastic PD 方案(可以动态扩缩 Prefill/Decode 实例数)更合适。
总结与展望
PD 分离部署的核心洞察在于:Prefill 和 Decode 对硬件资源的需求特征截然不同,将它们绑定在同一 GPU 上是对两类资源的双重浪费。通过架构上的拆分,我们可以用高算力 GPU 批量处理 Prefill,用高带宽 GPU 高效运行 Decode,并通过优化 KV Cache 传输来弥合分离带来的开销。
展望未来,以下几个方向值得关注:
- 弹性 PD 分离:根据实时负载动态调整 Prefill 和 Decode 的节点配比,实现资源池的分钟级弹性伸缩。
- 跨集群 KV Cache 迁移:当用户移动(如手机切换基站)时,将 KV Cache 在不同的 Decode 节点间迁移以保持低延迟。
- 存算分离的推理架构:把 KV Cache 看作持久化状态,用 CXL(Compute Express Link)连接的共享内存池来存储,Prefill 和 Decode 节点都从中读写,彻底消除数据传输的显性开销。
- PD 分离 + Speculative Decoding:结合推测解码(Speculative Decoding)让小型 Draft Model 先跑 Decode 阶段,Large Target Model 只负责确认——这天然适配 PD 分离的架构,因为 Draft Model 运行在 Decode 节点上,Target Model 负责类似 Prefill 的验证计算。
从大模型推理的演进来看,2024 年我们解决了跑得起来的问题(vLLM、TensorRT-LLM 等推理引擎成熟),2025-2026 年正在解决跑得经济的问题。PD 分离正是 AI Infrastructure as a Service 思想的体现——不再把推理看作一个固定在单机上的黑盒,而是一个由多种异构资源组合而成的、可编排的服务。它能帮你省下 30%-50% 的推理硬件成本,代价是多了一层的网络和调度复杂度。这笔交易是否划算,取决于你的负载规模和延迟要求。对于日请求量百万以上的大模型推理服务来说,PD 分离几乎是必选项。
汤不热吧