Prefill-Decode 解耦实战:长上下文大模型服务的延迟治理
背景:推理优化已从”单次更快”转向”阶段隔离”
过去讨论大模型推理优化,最常见的关键词是 Continuous Batching、PagedAttention、量化、KV Cache 复用和 Speculative Decoding。这些技术解决的是单个推理引擎内部的吞吐、显存和 token 生成效率问题。
但当业务进入长上下文、RAG、代码仓库问答、多轮 Agent、批量文档处理之后,一个更棘手的问题浮出水面:同一批 GPU 同时处理 prompt 预填充和逐 token 生成时,两个阶段会相互干扰。
大模型在线推理通常拆为两阶段:
| 阶段 | 英文 | 特征 | 瓶颈 |
|---|---|---|---|
| 预填充 | Prefill | 一次性计算全部输入 token 的注意力状态,生成 KV Cache | 计算密集,输入越长越重 |
| 逐 token 生成 | Decode | 基于已有 KV Cache 逐 token 生成输出 | 显存带宽与调度稳定性 |
如果这两个阶段混在同一个 GPU 池,新的长 prompt 进入时可能挤占正在 decode 的请求,导致用户看到输出突然卡顿。Hao AI Lab 对 DistServe 的回顾将这一问题概括为 Prefill-Decode Interference:prefill 与 decode 共用 GPU 时,新的 prefill 要么暂停 decode,要么与 decode 混批,两者都会拉高 decode latency。vLLM 文档也明确将 disaggregated prefilling 的目标定位于分别调优 TTFT 和 ITL 以及控制尾部 ITL,而非简单宣称吞吐提升。
核心问题:TTFT 与 TPOT 不是同一个优化目标
在线 LLM 服务至少有两个用户可感知的指标:
- TTFT(Time To First Token):用户发出请求后看到第一个 token 的时间。
- TPOT / ITL(Time Per Output Token / Inter-Token Latency):生成过程中每个 token 之间的间隔。
二者的工程含义截然不同:
| 指标 | 敏感因素 |
|---|---|
| TTFT | 输入长度、prefill 算力、队列等待、prefix cache 命中率 |
| TPOT/ITL | decode batch 大小、KV Cache 读写、显存带宽、调度抖动 |
把它们放在同一套资源池里,调度器只能做折中:为了降低 TTFT 插入 prefill,就可能拉高正在 decode 请求的 ITL;为了保护 decode,就可能让新请求排队,TTFT 变差。
Prefill-Decode 解耦的基本思路因此非常直接:不要让两种不同负载在同一资源池里争抢。把 prefill 和 decode 分别交给不同实例、不同 GPU 池,甚至不同硬件形态,再通过 KV Cache 传输将两个阶段连接起来。
这不是单纯”多起几个服务”。真正的难点在于:
- prefill 结束后生成的 KV Cache 必须可靠、低延迟地传给 decode。
- 请求调度必须知道哪个 decode worker 能拿到对应 KV。
- prefill/decode 资源比例需要根据输入长度、输出长度和 SLO 动态规划。
- 传输链路不能成为新的瓶颈。
核心原理:把一次请求拆成两个可独立扩缩的阶段
一个典型 P/D 解耦流程如下:
- API Gateway / Router 接收请求。
- Scheduler 根据输入长度、SLO、缓存命中情况,将请求送到 prefill worker。
- prefill worker 计算 prompt 的隐藏状态和 KV Cache。
- KV Connector 将 KV Cache 传输给 decode worker,或写入可共享的 KV 存储层。
- decode worker 读取 KV Cache 并开始逐 token 生成。
- Router 将生成结果流式返回给用户。
vLLM 的 disaggregated prefilling 文档给出了清晰的工程模型:运行两个 vLLM 实例,一个作为 prefill instance,一个作为 decode instance,通过 connector 传输 prefill KV caches 和结果。其内部抽象包括 Connector、LookupBuffer 和 Pipe;Connector 让 KV consumer 获取 KV producer 产生的 KV Cache,LookupBuffer 支持类似 insert/drop_select 的语义,Pipe 负责 tensor 传输。
从架构视角看,P/D 解耦将 LLM serving 从”一个推理引擎”变成了一个小型分布式系统。它的收益来自隔离,成本也来自分布式:网络传输、缓存一致性、路由、失败恢复、资源规划都会变得更复杂。
为什么 2025-2026 年这条路线变得重要
2025 年之后,P/D 解耦不再只是论文里的服务架构。Hao AI Lab 在 2025 年 11 月的回顾中指出,几乎所有生产级 LLM serving 框架都开始拥抱某种形式的 disaggregation:
- NVIDIA Dynamo
- llm-d
- Ray Serve LLM
- SGLang
- vLLM
- LMCache
- Mooncake
长上下文、业务规模化和更严格的尾延迟要求是这一变化的主要驱动力。
2026 年的研究进一步将问题推向资源规划和跨集群形态。例如,SLO-Aware Compute Resource Allocation for Prefill-Decode Disaggregated LLM Inference 将问题表述为:在总吞吐、SLO、输入输出长度分布约束下,如何决定 prefill 和 decode 资源数量。Large-Scale LLM Inference with Heterogeneous Workloads 则从排队网络和调度控制角度讨论异构负载下的 prefill/decode 竞争问题。更激进的方向还包括 Prefill-as-a-Service,将长上下文 prefill 选择性外部化到独立 prefill 集群,再将 KV Cache 传回本地 decode 集群。
这些工作共同说明一个趋势:LLM 推理优化的单位正在从 kernel、单卡、单实例,上升到资源池、网络和调度策略。
工程落地:从单实例服务演进到 P/D 解耦
第一步:先把指标拆开
不要一开始就改架构。先把现有服务的指标拆成下面几组:
- TTFT:按输入长度分桶(0–1K、1K–4K、4K–16K、16K+)。
- TPOT/ITL:按输出长度和并发量分桶。
- p95/p99:单独观察尾延迟,不要只看平均值。
- prefill queue time 与 decode queue time:分开记录等待时间。
- GPU utilization、memory bandwidth、KV Cache 占用、KV Cache 命中率。
只有当你确认”长 prompt 或 bursty prefill 正在拉高 decode 尾延迟”时,P/D 解耦才有明确的收益目标。
第二步:先做逻辑解耦,再做物理解耦
早期可以不急着跨节点传 KV。可以先在同节点、同高速互联域里做 prefill/decode worker 分离,降低工程变量。
推荐演进顺序:
| 阶段 | 做法 |
|---|---|
| 1 | 单实例 continuous batching |
| 2 | chunked prefill 缓解长 prompt 对 decode 的冲击 |
| 3 | 同节点 P/D 分离,使用高带宽链路传 KV |
| 4 | 多节点 P/D 分离,引入 KV-aware router |
| 5 | KV Cache 存储层或多级缓存,支持跨实例复用和更复杂调度 |
| 6 | 异构资源池:计算型资源偏 prefill,带宽型资源偏 decode |
vLLM 文档也提示:chunked prefill 在合适 chunk size 下可以达到类似控制 tail ITL 的目标,但实际找到合适 chunk size 并不容易;disaggregated prefilling 更可靠,但也被明确标注为 experimental,并强调不直接提升吞吐。
第三步:把 KV Cache 当作一等公民
P/D 解耦的关键资产不是请求体,而是 KV Cache。一旦拆分,KV Cache 就从进程内状态变成了跨 worker 传输的数据面。
这里至少要设计四件事:
| 维度 | 关键问题 |
|---|---|
| KV 标识 | 一个请求、一个 prefix、一个 batch 的 KV 如何命名、查找、过期 |
| KV 路由 | decode worker 如何知道从哪里读取 KV |
| KV 传输 | 走 NVLink、InfiniBand、PCIe、以太网、CPU memory、SSD 还是混合层级 |
| KV 生命周期 | 何时释放,失败后如何清理,是否允许多个请求复用 |
LMCache 的设计思路值得参考:它将 KV Cache 暴露在 LLM engine 接口层,将引擎从”独立 token processor”转向”以 KV Cache 作为存储与通信媒介的 engine 集合”,并支持 cache offloading 和 P/D disaggregation。这个方向对企业级部署尤其重要,因为真实业务中 prompt prefix 往往有大量重复——系统提示词、工具说明、文档模板、Agent 轨迹前缀皆在此列。
第四步:资源比例不要拍脑袋
P/D 解耦之后最常见的问题是:prefill 池和 decode 池应该各放多少 GPU?
答案取决于业务流量分布:
| 业务类型 | 输入特征 | 输出特征 |
|---|---|---|
| 文档问答 | 输入很长 | 输出较短 |
| 代码生成 | 输入中等 | 输出很长 |
| 多轮 Agent | 多轮、共享上下文多 | 工具调用间隔不稳定 |
可以用一个简化模型做初始估算:
prefill_load ≈ request_qps × avg_input_tokens / prefill_tokens_per_second
decode_load ≈ request_qps × avg_output_tokens / decode_tokens_per_second
然后再用 p95 输入长度、p95 输出长度、SLO 约束修正。2026 年的 SLO-Aware P/D resource allocation 研究也采用”理论建模 + 实测 benchmark”的思路:先根据吞吐需求、输入输出长度和 prefill/decode throughput 估算资源,再通过 TTFT、TPOT 等 SLO 约束校正。
工程上不要只用均值。长上下文业务的长度分布通常是重尾的,少量超长请求就可能决定尾延迟表现。
适用场景
P/D 解耦更适合下面几类业务:
1. 长上下文 RAG — 输入文档、检索片段、系统提示词和用户问题拼接后,prompt 很容易达到数千到数万 token。prefill 成本高且波动大,容易干扰正在生成的请求。
2. 代码仓库问答与代码生成 — 代码场景常见长输入和长输出并存。prefill 需要处理大量上下文,decode 又可能持续生成较长代码块。TTFT 和 TPOT 都要关注。
3. 多轮 Agent — Agent 携带系统提示词、工具描述、历史轨迹和中间结果。多轮请求中,prefix cache、append-prefill、本地 decode 复用都可能影响架构选择。
4. 多租户推理平台 — 不同租户的输入输出长度、SLO、价格模型差异大。P/D 解耦可以把资源隔离、路由策略和弹性伸缩做得更细。
5. 超大规模 GPU 集群 — 当集群规模达到数百甚至上千 GPU 时,统一资源池会放大调度干扰。P/D 解耦能将资源规划从”为最坏情况整体冗余”转向”按阶段独立扩缩”。
不适用或需要谨慎的场景
P/D 解耦不是银弹。
- 如果业务输入短、输出短、QPS 不高,单实例 continuous batching + PagedAttention + prefix cache 可能已经足够。此时引入 P/D 解耦,KV 传输、部署复杂度和排障成本可能大于收益。
- 如果网络条件弱,KV Cache 传输会成为瓶颈。长上下文 dense attention 模型的 KV 很大,跨节点甚至跨数据中心传输不一定划算。
- 如果团队缺少基础观测能力,也不建议直接上 P/D。没有 TTFT、TPOT、队列时间、KV 传输耗时和尾延迟拆分,就无法判断问题是 prefill 算力不足、decode 带宽不足、KV 传输慢,还是调度策略错误。
常见误区
误区一:P/D 解耦一定提升吞吐
vLLM 文档明确写道 disaggregated prefill does not improve throughput。它的核心价值是分别调优 TTFT 和 ITL,并控制 tail ITL。吞吐是否提升,要看是否消除了资源过度冗余、是否减少了阶段干扰、KV 传输是否足够低成本。
误区二:只要拆两个服务就是 P/D 解耦
真正的 P/D 解耦必须处理 KV Cache 的传输、匹配、生命周期和失败恢复。否则只是把一个进程内问题变成了跨服务问题。
误区三:只按平均输入输出长度规划资源
平均值会掩盖长尾。长上下文服务必须看 p90/p95/p99 输入长度、输出长度和并发分布。
误区四:忽略多轮请求的 append-prefill
多轮场景中,并非每次都需要完整 prefill。2026 年 PPD Disaggregation 相关研究指出,多轮请求中 append-prefill 的成本和干扰小于 full prefill,因此可以动态决定某些 turn 2+ 请求是否在 decode 节点本地处理。工程上,固定”所有 prefill 都外置”的策略可能不是最优。
上线检查清单
指标与压测
- 是否按输入长度、输出长度、租户、模型类型拆分 TTFT?
- 是否单独监控 TPOT/ITL 的 p50/p95/p99?
- 是否有 prefill queue time、decode queue time、KV transfer time?
- 是否有 bursty traffic、长上下文、短问短答、多轮 Agent 的混合压测?
- 是否做过资源比例 sweep(例如 1:1、1:2、1:3 的 prefill/decode GPU 比例)?
KV Cache
- KV key 是否可追踪?
- KV Cache 是否有 TTL 和清理机制?
- prefill 成功但 decode 失败时,KV 是否会泄露?
- decode worker 重启后,是否能重新拉取或放弃对应 KV?
- KV 传输失败时,请求是重试、降级,还是直接失败?
调度与路由
- Scheduler 是否知道请求的输入长度、预估输出长度和 SLO?
- Router 是否 KV-aware?
- 是否避免 decode worker 被瞬时 prefill KV 洪峰压垮?
- 是否有租户级限流和长 prompt admission control?
发布与回滚
- 是否能灰度到部分模型或部分租户?
- 是否保留原 colocated serving 回滚路径?
- 是否支持按模型、业务、租户关闭 P/D 解耦?
- 是否能在 Dashboard 中对比解耦前后的 TTFT、TPOT 和 GPU 利用率?
一个可落地的参考架构
可以将 P/D 解耦系统拆为六层:
Client / SDK
↓
API Gateway
↓
SLO-aware Router
↓
Prefill Pool ←→ KV Transfer / KV Store ←→ Decode Pool
↓
Streaming Response
关键模块职责:
| 模块 | 职责 |
|---|---|
| API Gateway | 认证、租户识别、请求大小限制、流式响应管理 |
| SLO-aware Router | 根据输入长度、租户等级、模型、缓存命中情况决定路由 |
| Prefill Pool | 偏计算密集,可使用更适合 prompt processing 的并行策略 |
| KV Transfer / KV Store | 负责 KV 的传输、缓存、复用、过期和清理 |
| Decode Pool | 偏稳定生成和带宽利用,重点保护 TPOT/ITL |
| Observability | 对 TTFT、TPOT、KV transfer、队列、失败率做全链路追踪 |
对于中小规模团队,第一版不要追求复杂的跨集群 KV 存储。优先在同机房、同高速网络域内做最小闭环,验证尾延迟收益,再逐步引入更复杂的多级 KV 缓存和异构资源池。
结论:P/D 解耦是延迟治理架构,不是单点性能开关
Prefill-Decode 解耦的价值不在于把服务拆得更复杂,而在于承认大模型推理的两个阶段具有不同的资源画像和不同的用户体验指标。
当业务进入长上下文、多轮 Agent、多租户和高并发阶段,单一 GPU 池很容易在 TTFT、TPOT、吞吐和成本之间互相牵制。P/D 解耦提供了一种更可控的架构:让 prefill 专注处理上下文,让 decode 专注稳定生成,让 KV Cache 成为连接两者的一等数据面。
但它也带来新的工程成本。上线前必须回答三个问题:
- 你的尾延迟问题是否真的来自 prefill/decode 干扰?
- 你的 KV Cache 传输链路是否足够快、可观测、可恢复?
- 你的资源比例是否基于真实输入输出长度和 SLO 压测,而不是经验猜测?
如果答案是肯定的,P/D 解耦将成为长上下文 LLM 服务从”能跑”走向”稳定、可扩展、可控成本”的关键架构。
主要参考资料:
- vLLM Documentation, Disaggregated Prefilling — https://docs.vllm.ai/en/latest/features/disagg_prefill/
- Hao AI Lab, Disaggregated Inference: 18 Months Later (2025-11-03) — https://haoailab.com/blogs/distserve-retro/
- Luchang Li et al., SLO-Aware Compute Resource Allocation for Prefill-Decode Disaggregated LLM Inference (2026-03-05) — https://arxiv.org/abs/2603.04716
- Ruihan Lin et al., Large-Scale LLM Inference with Heterogeneous Workloads (2026-02-03) — https://arxiv.org/abs/2602.02987
- Hengrui Zhang et al., SPAD: Specialized Prefill and Decode Hardware for Disaggregated LLM Inference (2025-10-09) — https://arxiv.org/abs/2510.08544
- Yihua Cheng et al., LMCache: An Efficient KV Cache Layer for Enterprise-Scale LLM Inference (2025-10-08) — https://arxiv.org/abs/2510.09665
- Ruoyu Qin et al., Prefill-as-a-Service: KVCache of Next-Generation Models Could Go Cross-Datacenter (2026-04-16) — https://arxiv.org/abs/2604.15039
- Zongze Li et al., Not All Prefills Are Equal: PPD Disaggregation for Multi-turn LLM Serving (2026-03-09) — https://arxiv.org/abs/2603.13358