1. PD分离推理架构概述
在大语言模型(LLM)推理服务中,prefill(预填充)和decode(解码)是两个截然不同的计算阶段。prefill阶段需要并行处理整个输入序列来生成首个token,属于计算密集型操作;而decode阶段则逐个生成后续token,需要频繁访问KV cache,属于内存密集型操作。
传统continuous batching技术将这两个阶段混合处理,导致相互干扰,难以同时满足TTFT(首token延迟)和TPOT(token间延迟)的严格要求。PD分离架构通过将prefill和decode分配到不同的GPU实例上,针对各自特性进行专门优化,有效解决了这一问题。
提示:TTFT(Time To First Token)衡量用户等待首个响应的时间,直接影响交互体验;TPOT(Time Per Output Token)则决定生成过程的流畅度,两者都是评估LLM服务质量的关键指标。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 吞吐量与有效吞吐量
2.1 传统吞吐量指标的局限性
大多数LLM服务系统(如vLLM、TensorRT-LLM)以吞吐量(Throughput)作为主要性能指标,即单位时间内处理的请求数(RPS)或生成的token数。这种度量方式虽然直观,但存在明显缺陷:
- 无法反映实际服务质量:系统可能处理了大量请求,但许多未能满足延迟要求
- 与用户体验脱节:高吞吐可能伴随不可接受的延迟波动
- 资源利用率假象:GPU计算单元可能被充分利用,但服务效果不理想
2.2 Goodput概念的引入
DistServe论文提出了Goodput(有效吞吐量)概念,即在满足SLO(TTFT和TPOT要求)的前提下,每秒完成的有效请求数。其核心价值在于:
- 服务质量与成本效益的统一衡量
- 反映真实用户体验的量化指标
- 指导资源分配的优化方向
计算示例:
python复制# 假设系统配置为2个prefill worker和1个decode worker
prefill_capacity = 5.6 * 2 # 11.2 req/s
decode_capacity = 10.0 # 10.0 req/s
goodput = min(prefill_capacity, decode_capacity) / 3 # ≈3.3 req/s/GPU
2.3 SLO约束下的性能表现
不同应用场景对延迟的要求差异显著:
| 应用类型 | TTFT要求 | TPOT要求 | 典型场景 |
|---|---|---|---|
| 实时对话 | <200ms | <50ms | 客服机器人 |
| 文档摘要 | <1s | <20ms | 长文本处理 |
| 代码生成 | <500ms | <30ms | IDE智能补全 |
实验数据表明,在单卡场景下,传统架构的Goodput通常只有1.6 rps/GPU,而PD分离架构可提升至3.3 rps/GPU,效率提升超过2倍。
3. 传统架构的干扰问题
3.1 混合批处理的性能瓶颈
当prefill和decode请求在同一批次处理时,会产生以下干扰效应:
- 计算资源争用:prefill的矩阵运算占用大量计算单元,阻塞decode进程
- 内存带宽竞争:decode频繁访问KV cache,影响prefill的数据加载
- 流水线气泡:两种计算模式切换产生额外开销
3.2 量化干扰影响
不同prompt长度下的延迟放大效应:
| Prompt长度 | Decode延迟倍数 | TTFT增加幅度 |
|---|---|---|
| 128 tokens | 1.8x | 15% |
| 512 tokens | 5.2x | 40% |
| 1024 tokens | 12.6x | 85% |
3.3 资源过度配置问题
为满足SLO要求,传统架构通常需要:
- 预留30-50%的计算余量应对峰值负载
- 采用更高规格的GPU实例
- 设置更宽松的批处理大小限制
这些措施导致资源利用率低下,成本显著增加。
4. PD分离架构设计
4.1 核心设计思想
- 物理分离:prefill和decode运行在不同GPU实例
- 专用优化:针对各阶段特性定制并行策略
- 状态迁移:通过KV cache传输衔接两个阶段
4.2 工作流程
- 请求首先进入prefill worker生成首个token和KV cache
- 中间状态迁移到decode worker
- decode worker完成剩余token生成
- 结果返回客户端
4.3 架构优势对比
| 特性 | 传统架构 | PD分离架构 |
|---|---|---|
| 资源利用率 | 60-70% | 85-95% |
| SLO达标率 | 60-80% | 95%+ |
| 扩展灵活性 | 低 | 高 |
| 运维复杂度 | 低 | 中 |
| 硬件成本 | 高 | 中 |
5. 关键技术实现
5.1 KV Cache传输优化
5.1.1 传输开销分析
对于OPT-175B模型和2048 tokens序列:
code复制传输数据量 = 2048 × 4.5MB = 9GB
PCIe 5.0 x16带宽 = 64GB/s
理论延迟 = 9GB / 64GB/s ≈ 140ms
实际测得延迟 ≈ 170-200ms (含协议开销)
5.1.2 传输方式对比
| 方式 | 优点 | 缺点 |
|---|---|---|
| 中心存储 | 易扩展,支持复用 | 单点瓶颈,延迟较高 |
| P2P直连 | 延迟低,吞吐高 | 扩展性受限 |
| 分层传输 | 隐藏延迟,内存占用优 | 实现复杂 |
5.1.3 传输粒度优化
- 请求级传输:简单但TTFT受影响
- 层级传输:
- 每层计算完成后异步传输
- 可提前释放prefill内存
- 实现计算-传输流水线
- 块级传输:
- 适合超长序列场景
- 需要精细的内存管理
5.2 批处理策略优化
5.2.1 Prefill批处理特点
- 计算强度随batch size增加快速饱和
- 建议batch size:4-16(取决于模型规模)
- 需要动态调整策略:
python复制def adjust_prefill_batch(current_batch, latency): if latency > SLO_TTFT * 0.8: return max(4, current_batch // 2) elif latency < SLO_TTFT * 0.5: return min(16, current_batch * 2) return current_batch
5.2.2 Decode批处理特点
- 吞吐量随batch size线性增长
- 建议batch size:32-256
- 内存限制是主要约束因素
5.3 并行策略选择
5.3.1 Prefill并行方案
- 张量并行:适合低延迟需求
- 流水线并行:适合超大模型
- 典型配置:
yaml复制prefill_parallel: tensor_parallel: 2 pipeline_parallel: 1 batch_size: 8
5.3.2 Decode并行方案
- 数据并行:优先选择
- 序列并行:超长上下文场景
- 典型配置:
yaml复制decode_parallel: data_parallel: 4 batch_size: 64
6. 工业级实现方案
6.1 vLLM实现详解
6.1.1 KV Connector架构
vLLM通过KV Connector抽象层实现状态传输:
- Scheduler侧:
- 构建传输元数据
- 协调worker间状态同步
- Worker侧:
save_kv_layer:生产端序列化KV cachestart_load_kv:消费端反序列化
6.1.2 Connector类型对比
| 类型 | 适用场景 | 传输延迟 | 实现复杂度 |
|---|---|---|---|
| SharedStorageConnector | 小规模部署 | 高(100ms+) | 低 |
| P2pNcclConnector | 同节点GPU间 | 低(<10ms) | 中 |
| NixlConnector | 跨节点高速传输 | 中(20-50ms) | 高 |
6.1.3 配置示例
bash复制vllm --model meta-llama/Llama-2-7b \
--kv-transfer-config '{
"kv_connector": "MultiConnector",
"connectors": [
{"type": "NixlConnector"},
{"type": "SharedStorageConnector"}
]
}'
6.2 Mooncake实践
Moonshot AI的Kimi服务采用创新设计:
- 三级缓存体系:
- GPU HBM → CPU内存 → SSD
- 冷热数据自动迁移
- 预测性调度:
python复制def should_reject(request): # 基于历史数据预测请求延迟 predicted_latency = model.predict(request) return predicted_latency > SLO * 1.2 - 实测效果:
- 长上下文吞吐提升5.25倍
- 服务容量增加75%
6.3 Dynamo部署方案
NVIDIA的云原生推理框架关键组件:
- Planner:动态资源调度
- 监控GPU利用率
- 自动扩缩prefill/decode实例
- Smart Router:KV cache感知路由
- NIXL:高速传输库
Kubernetes部署示例:
yaml复制apiVersion: nvidia.com/v1alpha1
kind: DynamoGraphDeployment
spec:
services:
Frontend:
replicas: 2
VllmDecodeWorker:
replicas: 4
resources: {gpu: 1}
VllmPrefillWorker:
replicas: 2
resources: {gpu: 1}
7. 性能优化实践
7.1 资源配比建议
根据负载特征确定prefill/decode比例:
| 负载类型 | Prefill比例 | Decode比例 | 说明 |
|---|---|---|---|
| 短交互型 | 30% | 70% | 侧重decode吞吐 |
| 长文本型 | 50% | 50% | 平衡两端需求 |
| 混合型 | 40% | 60% | 动态调整权重 |
7.2 典型配置参数
Llama-2-7B模型的优化配置:
yaml复制prefill:
tensor_parallel: 2
batch_size: 8
max_seq_len: 4096
decode:
data_parallel: 4
batch_size: 64
cache_chunk_size: 512
transmission:
connector: NixlConnector
overlap: true
compression: fp16
7.3 监控指标设计
关键监控维度:
- 资源维度:
- GPU利用率(计算/内存)
- 网络吞吐量
- 服务质量维度:
- P99 TTFT/TPOT
- SLO达标率
- 业务维度:
- Goodput
- 错误率
8. 对比chunked-prefills方案
8.1 核心思想对比
| 特性 | PD分离 | chunked-prefills |
|---|---|---|
| 架构理念 | 物理分离 | 逻辑分块 |
| 计算连续性 | 阶段完整执行 | 交替执行 |
| 资源分配 | 专用化 | 共享 |
8.2 性能表现对比
实测数据(Llama-2-13B, A100×8):
| 指标 | PD分离 | chunked-prefills | 提升幅度 |
|---|---|---|---|
| Goodput | 3.2 rps/GPU | 2.1 rps/GPU | 52% |
| P99 TTFT | 180ms | 320ms | 78% |
| 内存带宽利用率 | 65% | 85% | - |
8.3 适用场景建议
选择PD分离当:
- 需要严格保证TTFT和TPOT
- 硬件资源充足
- 请求负载波动大
选择chunked-prefills当:
- 追求最大吞吐量
- 硬件资源受限
- 可以接受适度延迟波动
9. 演进方向与挑战
9.1 技术发展趋势
- 更智能的传输调度:
- 基于强化学习的动态路由
- 自适应压缩策略
- 异构硬件支持:
- CPU卸载部分decode计算
- 新型存储介质应用
- 云原生深度集成:
- Kubernetes operator优化
- 自动弹性伸缩
9.2 现存挑战
- 长上下文支持:
- 万token级序列的传输效率
- 内存管理复杂度
- 多租户隔离:
- QoS保障机制
- 资源抢占问题
- 成本控制:
- 传输带宽成本
- 状态同步开销
在实际部署中,我们观察到当序列长度超过8k tokens时,KV cache传输可能成为瓶颈。一个可行的优化是采用分层传输策略,优先传输attention头的部分维度数据,在decode端进行近似计算。
