Skip to content

07. Serving Scheduling, PD, and Heterogeneous Routing | Serving 调度、PD 与异构路由 ​

页面目标 ​

从多个请求同时到达开始,观察 Prefill 和 Decode 如何争用计算、显存与队列资源;再逐层理解 Chunked Prefill、PD 分离、状态交接与异构资源路由如何共同影响服务质量。最后把调度决策放回 CPU 准备、GPU 计算和通信交接的时间线上,判断等待是否暴露在关键路径。

调度问题的四个层次 ​

本节把“调度”按决策范围逐层展开。前一层决定当前一步做什么,后一层决定更多请求如何共享资源;因此 36、37、38 不是三个并列的 backend 名词,而是从执行单元走向服务拓扑的学习顺序。

层次调度者在决定什么主要输入主要结果对应入口
单步 Decode 调度当前 Decode step 给哪些活跃请求分配 token 计算请求状态、优先级、剩余长度本轮执行顺序与步数36
Cache 资源调度请求能否继续占用 Cache,何时暂停、驱逐或恢复Cache 容量、Block、等待时间可接纳请求数与公平性37
批次与队列调度哪些 Prefill / Decode 请求组成下一批到达时间、Prompt 长度、Decode 工作量批次效率、排队和尾延迟38 的前置机制、70 的实验
服务池调度请求进入哪个实例、Prefill 池或 Decode 池GPU 资源、链路、服务等级服务吞吐、P99 和资源隔离38、70
异构 PD 路由交接 KV、重算 Prefill,还是保持同池两池能力、状态大小、链路、SLO交接代价、池利用率、回退动作39;分布式扩展见 Task6 的 79–81

执行关键路径与重叠 ​

四层调度先决定请求、Cache、批次和资源池;执行级与通信级再回答这些决定如何落到时间线上。CPU 准备、GPU 计算、数据搬运和 KV 交接如果连续排队,就会把等待暴露给请求;如果能够安全重叠,才可能降低关键路径上的空洞。这里先建立共同判断方法,Task4 的局部实现分别在 38、39、70 中验证;跨 GPU 或跨实例的通信证据留到 Task6 的 79–81。

执行级和通信级不是新的请求状态,而是调度决策的时间维度:执行级关注 CPU 准备、GPU 计算和数据搬运能否重叠;Task4 只观察局部 handoff 是否暴露在关键路径,集合通信和多卡通信证据则连接到 Task6 的 79–81。相关底层入口仍包括 Part 02 的异步执行和 Part 04 的 Stream / Graph。

时间层次调度要安排什么典型策略关键证据
执行级CPU 准备、GPU 计算、搬运和收尾的先后与重叠双流、双线程、流水线overlap ratio、idle gap、端到端延迟
通信级状态传输或集合通信与计算的重叠KV handoff、communication-compute overlap、DBO 类批次拆分transfer bytes、通信暴露时间、池利用率

Serving 执行关键路径:准备、计算、交接与下一轮调度

读图时先区分两种时间:total elapsed 是请求真正等待的时间,overlap 是被其他工作隐藏的时间。只有通信或搬运从关键路径中移开,吞吐或尾延迟才可能改善;单纯增加并行任务而造成同步、争用或池闲置,不应直接判断为优化。

观察对象需要回答的问题证据字段
请求进入请求是在排队,还是在等待输入准备?queue_wait_ms、input_transfer_ms
CPU / GPU 重叠CPU 准备是否填补了 GPU 空闲间隙?idle_gap、overlap_ratio、端到端延迟
KV handoff状态传输是否阻塞 Decode?transfer_bytes、handoff_ms、recompute_ms
网络与集合通信数据是否在通信路径上暴露出来?network_wait_ms、communication_ms、exposed_comm_ms
模型启动与流式输出冷启动或输出发送是否被误算为热请求性能?model_load_ms、stream_output_ms、cold_start
池间平衡一侧加速是否造成另一侧等待或闲置?Prefill / Decode 池利用率、P95/P99

Task4 的 I/O 证据契约 ​

I/O 在本节中不是另一个独立优化对象,而是解释调度结果为什么出现的证据层。先按时间位置区分等待、搬运和计算,再把同一组字段带入 70 的 serving benchmark;不要把模型加载、请求排队和 KV 交接相加后直接当成 TPOT。

证据阶段记录什么与调度的关系解释时的注意点
请求进入queue_wait_ms、input_transfer_bytes、input_transfer_ms反映接纳、排队与输入准备排队时间上升不等于 GPU 变慢
Prefill / Decode 执行idle_gap、overlap_ratio、stream_output_ms判断准备、计算和输出是否重叠只能用同一 workload 比较
PD / KV 交接transfer_bytes、handoff_ms、recompute_ms判断传输、重算或同池回退的代价handoff 与 recompute 不能重复计入
网络 / 通信network_wait_ms、communication_ms、exposed_comm_ms判断通信是否暴露在关键路径暴露时间应和总 elapsed 分开记录
启动阶段model_load_ms、cold_start区分扩容或首次请求成本冷启动不能和热请求 TTFT 混合平均

70 负责把这些字段放入同一份 baseline / candidate 结果记录,并继续使用 accept / tune / reject 做决策;07 只规定字段语义和归因顺序,不替代 backend 的 profiler 或服务端日志。

这里要区分三个容易混淆的对象:

  • 请求调度决定“先服务谁、这一轮服务谁”;
  • Cache 管理决定“请求的状态放在哪里、能保留多久”;
  • PD 分离决定“Prefill 和 Decode 由哪个资源池执行”;
  • 异构路由决定“两池能力不同时,状态怎样交接、何时回到同池”。

三者可以协同,但改动一个对象并不等于同时完成另外两个对象的优化。例如扩大 Cache 容量可能提高可接纳并发,却不会自动改善队列公平性;把 Prefill 和 Decode 拆成两个池,也需要重新检查跨池通信和负载平衡。

当请求量超过当前资源能够稳定处理的范围时,调度器还要做“是否接纳”的决定。接纳控制不是简单拒绝请求,而是根据 Cache 预算、队列等待、服务等级和预计工作量选择排队、限流、降级或转移。它决定系统是在负载上升时保持 P99,还是让所有请求一起变慢。

接纳动作触发条件保护对象需要观察
排队当前资源短时不足,但预计可以恢复请求完整性queue time、P99、队列长度
限流或拒绝队列或 Cache 超过安全水位已接纳请求的 SLArejection rate、超时率、P99
降级质量目标允许降低资源开销整体可用性输出长度、dtype、质量指标
转移或扩容单实例或单池持续饱和服务容量利用率、迁移/通信时间、吞吐

核心机制 ​

Serving 调度面对的不是单个算子,而是请求之间的资源竞争。先用“单 backend、基础批处理、单实例、不开启 PD 分离”的 Serving 配置建立参考行为,固定请求分布、并发度和输出长度,记录 TTFT、TPOT、吞吐、P99 与峰值显存。Prefill 通常带来突发计算和显存申请,Decode 则需要持续、稳定地读取 KV Cache;如果把两者简单混在同一批次,长 Prompt 可能阻塞正在生成的请求。因此需要分别观察批处理、队列、Cache 预算和 GPU 资源分配。

vLLM 和 SGLang 都是 Serving backend,但它们适合观察的机制重点不同:vLLM 适合作为统一基线,关注 PagedAttention、连续批处理和调度;SGLang 更适合观察 RadixAttention、前缀复用、结构化程序和 PD 分离。下面的图片先说明共同的请求链路,再对照两种 backend 的侧重点。

vLLM 与 SGLang 的 Serving 机制对比

Backend重点机制更适合观察的问题对应项目
单 backend 基线基础批处理、单实例、不开启 PD 分离建立 TTFT、TPOT、吞吐、P99 和峰值显存参照66 的基础 Serving 配置
vLLMPagedAttention、连续批处理、请求调度Cache 分配、吞吐、TTFT / TPOT、P9966 基线与 backend 对照、70 调度
SGLangRadixAttention、前缀复用、结构化执行、PD 分离Prefix Cache、共享前缀、请求组织与资源拆分66 可选对照、69 缓存、70 调度
机制主要解决的问题观察指标
Continuous Batching请求到达时间不同、生成长度不同吞吐、TPOT、P99
Chunked Prefill单次长 Prefill 阻塞其他请求TTFT、P99、Decode 抖动
Prefill / Decode 分离两类计算互相争用资源TTFT、TPOT、P95、池利用率
异构 PD 路由两池能力、链路或 backend 不同handoff ms、传输量、重算时间、P99、失败状态
队列与资源调度并发、容量和服务等级变化排队时间、并发容量、SLA

把 Serving 调度看成一个闭环:请求进入队列后,系统根据可用 Cache、Prefill/Decode 计算预算和服务等级选择下一批请求;运行结果再反馈给下一轮调度。这样可以把“调度策略更好”拆成可观察的资源账本和服务结果,而不是只看 GPU 利用率。

调度决策依据影响的系统对象需要观察的结果
等待时间与服务等级队列顺序、请求公平性P50/P99、最大等待时间、超时率
Prompt / Decode 工作量Prefill 与 Decode 的批次组成TTFT、TPOT、批次利用率
Cache 可用容量是否接纳、暂停或驱逐请求Cache 使用量、OOM、并发容量
实例与链路状态单实例、PD 池和跨设备通信吞吐、通信时间、资源利用率
状态交接预算KV 传输、重算或保持同池handoff ms、recompute ms、P99

学习和实验时按同一顺序推进:先用 36 验证单步请求选择,再用 37 加入 Cache 容量和暂停/恢复,用 38 观察 Chunked Prefill、分池与交接预算,再用 39 判断异构资源的路由、KV 传输/重算和 SLO 回退,最后在 70 中固定 workload 比较 TTFT、TPOT、throughput、P99、并发容量、公平性与池利用率。这样得到的结论才能说明“哪一层调度改善了什么”,而不是只报告 GPU 利用率变化。

多 GPU 和自动扩缩容不属于本节的主体,而是 Task6 的后续扩展。它们不改变前面的四层调度定义;完成单实例调度验证后,再进入并行机制、跨 GPU / 跨实例通信、负载平衡和部署成本的比较。

扩展方向新增约束需要补充的证据后续入口
Tensor / Pipeline / Expert Parallel分片、同步和负载平衡通信时间、空转、吞吐、显存Task6:79–81、分布式专题
MoE Expert Paralleltoken dispatch、专家容量和负载不均expert load、通信时间、空转、吞吐Task6:80;Part 01 · 22
PD 多实例跨池传输和池间负载不均transfer time、池利用率、P99Task4 基础:38、70;Task6 扩展:79–81
异构 PD资源能力、链路或 backend 不同handoff / recompute、路由命中、P99、回退率Task4 基础:39;Task6 扩展:79–81
自动扩缩容冷启动、迁移和容量预测扩容延迟、恢复时间、拒绝率性能分析与部署专题

参考入口:开源项目 vLLM 与 SGLang;论文 SGLang 和官方文档 PD Disaggregation。

判断框架 ​

本节承接 04 的 Cache 资源边界,先阅读 37 KV Cache Scheduling、38 Prefill/Decode 调度 与 39 异构 PD 与服务分层,再通过 70 Serving Scheduler Benchmark 观察真实请求 workload。阅读下表时,先固定请求分布、Prompt 长度、generated tokens、并发度、batch 策略和 Cache policy,再区分计算、排队、交接与资源分配问题。

观察到的现象优先判断下一步
长 Prompt 到达后 Decode 请求明显抖动Prefill 抢占或批次组织不合理检查 Chunked Prefill 和 Continuous Batching
TTFT 可接受但 TPOT / P99 变差Decode 资源被挤占或排队积累检查 Decode 调度和资源配额
单实例无法同时满足两类请求Prefill 与 Decode 资源需求不同评估 Chunked Prefill 与 PD 分离
PD 吞吐改善但 P99 变差交接或池间失衡暴露在关键路径比较 KV 传输、重算与同池回退
GPU 利用率低但排队时间高调度粒度、批次或跨实例通信不合理进入 profiling 和 serving benchmark

Released under the MIT License.