Appearance
调度系统 — 练习
练习 1:调度行为模拟
假设系统配置如下:
max_num_seqs = 4max_num_batched_tokens = 4096- KV 缓存共 512 个 block,每个 block 16 tokens
时间线:
- T0:请求 A(prompt 2048 tokens)到达
- T1:请求 B(prompt 512 tokens)到达
- T2:请求 C(prompt 3072 tokens)到达
请模拟前 4 轮调度的决策(每轮 decode 生成 1 个 token)。
参考答案
- Iter 1:A prefill(2048 tokens,占用 128 blocks),生成 1 token。剩余 384 blocks。Running: [A]
- Iter 2:A decode(1 token),B prefill(512 tokens,占用 32 blocks)。剩余 352 blocks。Running: [A, B]
- Iter 3:A decode + B decode(各 1 token)。C prefill(3072 tokens,占用 192 blocks)。剩余 160 blocks。Running: [A, B, C]
- Iter 4:A decode + B decode + C decode(各 1 token)。如果某个请求完成则释放其 blocks,否则继续 decode。
注意:实际行为取决于 chunked prefill 的 chunk size 和显存碎片情况。
练习 2:Preemption 场景分析
在以下场景中,调度器会选择哪种 preemption 策略?
- 10 个请求同时 active,KV 缓存占用 90%,新请求到达
- 长请求和短请求混合,短请求已完成但长请求仍在 decode
- 启用了 prefix caching,多个请求共享相同 system prompt
参考答案
Re-computation:抢占一个请求释放 KV 缓存。选择最后到达的请求(FCFS 策略下优先级最低)。由于 KV 缓存压力较大,恢复时需要重新 prefill。
释放短请求的 KV 缓存:已完成的请求的 KV 缓存会被自然回收。如果仍然不够,抢占最新到达的请求。
保留共享 prefix:prefix caching 使得共享前缀的 KV 缓存块有多个引用。抢占时选择引用计数最少的块释放,保留共享 prefix 的块。
练习 3:Chunked Prefill 参数调优
分析以下参数组合对 TTFT 和吞吐量的影响:
| 配置 | max_num_batched_tokens | chunked_prefill |
|---|---|---|
| A | 2048 | off |
| B | 2048 | on |
| C | 8192 | on |
| D | 32768 | on |
参考答案
| 配置 | TTFT | 吞吐量 | 适用场景 |
|---|---|---|---|
| A | 差(短 prompt 好处少) | 差(长 prompt 阻塞 decode) | 短 prompt、低并发 |
| B | 好(chunk 小,快速响应) | 中(调度开销增加) | 交互式聊天 |
| C | 中 | 好(平衡 prefill 和 decode) | 通用场景(默认) |
| D | 差(大 chunk 等待久) | 好(GPU 利用率高) | 批量推理 |
拓展挑战
- 阅读
vllm/v1/core/sched/scheduler.py的_schedule_prefills和_schedule_decodes方法 - 分析
request_queue.py中的优先级调度实现 - 研究调度器如何处理 LoRA 请求的特殊调度需求