TokenSpeed PD分离架构详解:Prefill与Decode解耦如何突破吞吐极限
【免费下载链接】tokenspeedTokenSpeed is a speed-of-light LLM inference engine.项目地址: https://gitcode.com/gh_mirrors/to/tokenspeed
TokenSpeed 是一款被称为"光速"的 LLM 推理引擎,其 PD 分离(Prefill-Decode 解耦)架构将大模型推理的Prefill(提示词预填充)与Decode(逐词生成)两个阶段拆分到独立的节点组上运行,让吞吐与延迟各自独立扩展。本文面向新手,完整讲解 TokenSpeed PD 分离的工作原理、P/D 角色划分、KV 缓存传输机制,以及如何通过合理配置突破单实例吞吐极限。
为什么分离?混合执行 Prefill 与 Decode 的隐藏瓶颈
理解 PD 分离,先要理解 LLM 推理的两个阶段在"性格"上截然不同:
| 阶段 | 计算特征 | 核心诉求 |
|---|---|---|
| Prefill | 一次性处理整个提示词,计算密集(compute-bound) | 快,降低首 token 延迟(TTFT) |
| Decode | 每步只生成 1 个 token,访存密集(memory-bound) | 稳,降低每 token 间隔(TPOT) |
当两者混在同一批请求中执行时,问题就出现了:一条长提示词的 Prefill 任务会"霸占"GPU 一整轮,让所有正在 Decode 的请求集体"卡顿";反过来,频繁的 Decode 小批次又会压低长文本的 Prefill 吞吐。
TokenSpeed 的解法是彻底分家:Prefill 引擎和 Decode 引擎作为独立角色启动,各自针对自己的计算特征做硬件和并行策略优化。调度器设计上甚至明确规定:PD 分离部署中的Decode 角色从不计算提示词行(提示词 logprobs 由 Prefill 节点直接返回),见 docs/design/scheduler.md。
TokenSpeed PD分离怎么配:P/D 角色划分与 KV 缓存传输
TokenSpeed 通过--disaggregation-mode参数指定节点角色,核心逻辑集中在python/tokenspeed/runtime/pd/目录:
- P 节点(Prefill):
--disaggregation-mode prefill,负责处理提示词、构建 KV 缓存,代码入口为 prefill_executor.py - D 节点(Decode):
--disaggregation-mode decode,只负责逐 token 生成,代码入口为 decode_executor.py
KV 缓存怎么跨节点传?P 节点算出的 KV 缓存必须完整送达 D 节点,否则 Decode 无法"续上"上下文。TokenSpeed 基于Mooncake传输引擎实现零拷贝高速搬运,控制面采用 ZMQ 状态机(按bootstrap_room房间号跟踪每个请求的传输状态,失败状态具有粘性,避免迟到的成功信号"复活"已损坏的传输)。关键实现:
- 传输引擎:python/tokenspeed/runtime/pd/base/mooncake_engine.py
- 收发逻辑:python/tokenspeed/runtime/pd/mooncake/ 目录下的
sender.py/receiver.py - 拓扑管理:python/tokenspeed/runtime/pd/topology.py、python/tokenspeed/runtime/pd/transfer_plan.py
一个精巧的细节:请求被分配到哪个 P 节点由room % dp_size余数决定——也就是说,放置策略内建在房间号里,无需额外的负载均衡服务参与。
灵活并行配置:P 节点拼吞吐,D 节点拼延迟
PD 分离最大的红利,是 P 和 D可以使用完全不同的并行拓扑。以官方 Kimi K3 多节点部署为例(docs/guides/kimi-k3-hopper-pd.md):
| 引擎 | 注意力并行 | 路由专家 | 执行方式 |
|---|---|---|---|
| P | PP4, TP8, DP1 | 每阶段内 EP8 | Eager + 分块 Prefill |
| D | PP1, TP8, DP4 | 跨 4 节点 EP32 | Decode CUDA Graph |
可以看到:P 节点用流水线并行(PP)+ 分块 Prefill(--chunked-prefill-size 8192)压榨长文本算力;D 节点则用数据并行(DP)+ 专家并行(EP32)+ 低延迟通信模式,把每 token 间隔压到最低。这种"各取所需"在混合部署中是做不到的。更多并行参数说明见 docs/serving/parallelism.md。
从 1P1D 到多节点:如何选择合适的分离拓扑
TokenSpeed 支持从最小的1P1D(1 个 Prefill 实例 + 1 个 Decode 实例)平滑扩展到多 P 多 D 的大规模拓扑:
- 入门级(单机多卡):1P1D 适合验证链路,例如 Qwen3.5-397B 的 1P1D 部署脚本 test/ci/serve_qwen35_397b_nvfp4_pd_1p1d.sh,以及 DeepSeek-V4.1 Flash 的对应测试 test/runtime/distributed/test_deepseek_v41_pd_1p1d.py
- 生产级(多节点):Kimi K3 采用 P 与 D 各占 4 节点共 64 卡的布局;Qwen3.5-397B 的 PD 评测配置 test/ci/eval/qwen3.5-397b-a17b-nvfp4-pd-1p1d-evalscope-aime25.yaml 展示了完整的基准测试写法
选择建议:提示词普遍很长(RAG、代码库问答)→ 加大 P 侧数量并开启分块 Prefill;并发高、输出长 → 加 D 侧 DP 副本。P/D 比例可以随业务负载独立扩缩容,这正是 PD 分离突破吞吐极限的关键所在。
性能指标速查:TTFT、TPOT 与吞吐怎么测
PD 分离的收益需要用数据说话,TokenSpeed 官方验证流程(见 docs/guides/kimi-k3-hopper-pd.md 的 Validation 章节)要求记录以下指标:
- TTFT(Time To First Token):由 P 侧主导,衡量提示词处理 + KV 传输的总耗时
- TPOT(Time Per Output Token):由 D 侧主导,衡量逐词生成速度
- P 侧吞吐:计算输入 tokens/s;D 侧吞吐:输出 tokens/s
- 每卡显存峰值与传输错误率
官方 CI 中的 PD 部署评测(如qwen3.5-397b-a17b-nvfp4-pd-1p1d)就是按这套口径自动采集的,方便你横向对比"分离 vs 混合"的真实差距。
PD 分离常用参数与官方文档索引
核心参数速览:
| 参数 | 作用 |
|---|---|
--disaggregation-mode prefill / decode | 指定节点角色 |
--chunked-prefill-size 8192 | P 侧分块大小,长文本吞吐关键 |
--pipeline-parallel-size | P 侧流水线并行深度 |
--data-parallel-size/--expert-parallel-size | D 侧扩展副本与专家并行宽度 |
--max-num-seqs | D 侧最大并发请求数 |
延伸阅读:
- 入门与启动指南:docs/guides/launching.md、docs/guides/getting-started.md
- 并行策略全解:docs/serving/parallelism.md
- 调度与容量管理:docs/design/scheduler.md
- PD 传输测试用例:test/runtime/distributed/test_pd_transfer_plan.py
🚀总结:TokenSpeed 的 PD 分离架构通过"角色分家 + 独立扩缩容 + 高速 KV 传输"三板斧,让 Prefill 拼算力、Decode 拼带宽互不干扰,是长文本、高并发场景下突破 LLM 推理吞吐极限的完整指南式方案。从 1P1D 起步验证,再按业务负载扩展 P/D 比例,即可稳定获得 TTFT 与 TPOT 的双赢。
【免费下载链接】tokenspeedTokenSpeed is a speed-of-light LLM inference engine.项目地址: https://gitcode.com/gh_mirrors/to/tokenspeed
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考