请求调度 (Request Scheduling)
3 秒看懂
一句话定义: 请求调度是 LLM 推理服务系统中,决定”哪些用户请求、以什么顺序、用哪些 GPU 资源、以什么批处理策略执行”的核心决策引擎。
类比: 它是 LLM 推理集群的”交通指挥中心”——决定哪辆车先走、走哪条车道、是否让道,直接决定了吞吐量(每秒处理多少 token)和延迟(用户多久拿到结果)。
核心矛盾: 吞吐 vs 延迟 vs 资源利用率——三者永远在博弈。
3 分钟产业解释
为什么请求调度突然成为关键?
2023–2024 年 LLM 应用爆发后,推理服务的成本问题急剧凸显。训练是一次性的,推理是持续性的——头部应用(ChatGPT、Claude、Gemini 等)的推理算力消耗已远超训练。在此背景下,推理服务的效率优化成为产业核心议题,而请求调度正是影响推理效率的第一道关口。
核心逻辑链:
用户请求到达 → [请求调度器] → 决定批次组成 → 分配 GPU 资源 → 执行推理 → 返回结果
↑
调度策略直接决定:
- GPU 利用率(空转 vs 满载)
- 请求排队时间(毫秒 vs 秒级)
- 系统吞吐量(tokens/s)
- 用户体感延迟(TTFT / TPOT / TPS)
产业角色定位
请求调度不是一个独立产品,而是推理引擎/推理服务平台的核心子系统。它内嵌于:
| 层级 | 代表 | 调度器的角色 |
|---|---|---|
| 开源推理引擎 | vLLM、SGLang、TensorRT-LLM、llama.cpp | 内建调度器模块 |
| 云推理服务 | AWS Bedrock、Azure AI、Google Vertex AI | 平台级调度 |
| 专用推理芯片厂商 | Groq、Cerebras、SambaNova | 调度与硬件强耦合 |
| 企业自建推理集群 | 各大厂内部 Serving 平台 | 自研调度系统 |
一句话:谁控制了调度,谁就控制了推理成本。
15 分钟专家深入
1. 请求调度的核心问题域
LLM 推理的请求调度与传统分布式系统调度(如 Kubernetes Pod 调度、数据库查询优化)有本质区别,根源在于 LLM 推理的三个独特约束:
约束一:自回归生成的动态性
- LLM 推理是逐 token 自回归生成,每个请求的输出长度在调度时不可精确预知
- 用户问”1+1=?”可能只需 1 个输出 token,问”帮我写篇文章”可能需要数千个
- 这导致请求的资源消耗(主要是 KV Cache 显存占用)随时间动态变化
约束二:KV Cache 的显存瓶颈
- 每个请求在推理过程中需要维护其所有已生成 token 的 Key/Value 缓存
- KV Cache 的显存占用随序列长度线性增长,是推理显存的最大消耗者
- 调度器必须实时感知每个 GPU 的 KV Cache 占用状态
约束三:Prefill 与 Decode 的资源特性截然不同
- Prefill 阶段(处理输入 prompt):计算密集型,GPU 算力是瓶颈
- Decode 阶段(逐 token 生成):访存密集型,显存带宽是瓶颈
- 两个阶段对硬件资源的需求模式完全不同
2. 调度决策的四个维度
┌─────────────────────────────────────────────────┐
│ 请求调度器决策空间 │
├─────────────┬───────────────┬───────────────────┤
│ ① 谁先做? │ ② 和谁一起做? │ ③ 用什么资源做? │
│ (优先级) │ (批处理策略) │ (资源分配) │
├─────────────┼───────────────┼───────────────────┤
│ FCFS │ 静态 batching │ 单 GPU 内调度 │
│ 优先级队列 │ 连续 batching │ 跨 GPU 调度 │
│ SRPT │ Chunked │ 跨节点调度 │
│ 公平调度 │ prefill │ Prefill/Decode │
│ │ │ 分离部署 │
├─────────────┴───────────────┴───────────────────┤
│ ④ 什么时候让路?(抢占与迁移策略) │
│ - 抢占低优先级请求释放 KV Cache │
│ - KV Cache 卸载到 CPU/SSD │
└─────────────────────────────────────────────────┘
3. 从静态 Batching 到连续 Batching:范式跃迁
传统静态 Batching(2022 年前主流):
时间 →
请求A: [==========]
请求B: [====== ] ← B 先生成完,但必须等 A
请求C: [========= ] ← C 也必须等
↑
整个 batch 结束才能释放资源
GPU 利用率低,延迟高
问题:短请求被长请求”绑架”,GPU 在短请求完成后处于空转状态。
连续 Batching(Continuous Batching / Iteration-level Batching):
这一范式由 Orca 论文(OSDI 2022)系统性提出。核心思想是将调度粒度从”请求级”降低到”迭代级”(即每次 forward step)。
时间 → (每个 tick = 一次 forward step)
tick1: [A] [B] [C] [D]
tick2: [A] [B] [C] [D]
tick3: [A] [B] [C] ← D 已完成,slot 空出
tick4: [A] [B] [C] [E] ← 新请求 E 立即填入
tick5: [A] [B] [E] ← C 完成
...
核心收益:
- 请求完成即释放资源,新请求可立即加入
- GPU 利用率显著提升
- 长短请求混合执行,系统吞吐量大幅提升
现状: 连续 Batching 已成为主流推理引擎的标配基线。
4. Prefill-Decode 分离调度:前沿架构
随着推理规模增长,一种更激进的调度架构出现:将 Prefill 和 Decode 阶段拆分到不同的 GPU 组(或不同类型的硬件)上执行。
┌──────────────┐
用户请求 ──────────→│ 调度路由器 │
└──────┬───────┘
│
┌────────────┼────────────┐
↓ ↓
┌──────────────────┐ ┌──────────────────┐
│ Prefill 节点组 │ │ Decode 节点组 │
│ (高算力 GPU) │ │ (高带宽 GPU) │
│ - 计算密集 │ │ - 访存密集 │
│ - 短时占用 │ │ - 长时占用 │
└────────┬─────────┘ └──────────────────┘
│
│ KV Cache 传输
↓
┌──────────────────┐
│ KV Cache 池 │
│ (高带宽互联) │
└──────────────────┘
为什么分离?
- Prefill 是 compute-bound,需要高 FLOPS;Decode 是 memory-bandwidth-bound,需要高 HBM 带宽
- 两类负载混合在同一 GPU 上会互相干扰
- 分离后可分别针对各自瓶颈优化硬件选型和调度策略
代表性工作/产品方向(定性):
- DistServe(PD 分离论文,UCSD 等)
- Splitwise(微软研究院相关工作)
- 多个云厂商在生产环境中探索 Prefill-Decode 分离部署
核心挑战: Prefill 完成后的 KV Cache 需要高速传输到 Decode 节点,互联带宽成为关键瓶颈。
5. Chunked Prefill 调度策略
一个关键优化:当长 prompt 进入 Prefill 时,它会独占 GPU 较长时间,导致正在 Decode 的请求被”饿死”(延迟飙升)。
Chunked Prefill 的核心思想:将长 prompt 的 Prefill 切成多个 chunk,每个 chunk 与 Decode 请求交替执行。
时间 →
未优化: [====长Prefill====] [D1] [D2] [D3] ...
↑ decode 请求被阻塞
Chunked: [P1][D1D2D3][P2][D1D2D3][P3][D1D2D3] ...
↑ Prefill chunks 与 decode 交错执行
效果: Decode 请求的延迟抖动(jitter)显著降低,长 prompt 不再”堵车”。
vLLM 和 SGLang 等主流引擎已支持 Chunked Prefill,具体参数(chunk 大小等)可配置。
6. 抢占与 KV Cache 管理
当 GPU 显存被 KV Cache 占满时,调度器面临选择:
抢占策略(Preemption):
- Recomputation: 低优先级请求被驱逐,重新排队;恢复时从头计算 Prefill(浪费算力但省显存)
- Swapping: 将低优先级请求的 KV Cache 卸载到 CPU 内存或 SSD,恢复时加载回来(省算力但需传输时间)
调度器需要实时决策:
新请求到达 → KV Cache 容量不足?
├─ 是 → 选择哪些请求抢占?
│ ├─ 优先级低的先抢占
│ ├─ 已生成 token 多的(重启成本高)可能保留
│ └─ 预估剩余生成长度短的(快完成了)可能等待
└─ 否 → 正常加入 batch
技术原理(深度机制讲解)
1. 请求生命周期与调度器交互
┌─────────────────────────────────────────────────────────────────┐
│ 请求完整生命周期 │
│ │
│ 用户请求到达 │
│ │ │
│ ↓ │
│ ┌──────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ 请求解析 │ → │ 调度器决策 │ → │ 等待队列 │ │
│ │ 优先级分配│ │ - 资源检查 │ │ (按策略排序) │ │
│ │ │ │ - 批次组成 │ └─────┬──────┘ │
│ └──────────┘ │ - 抢占决策 │ │ │
│ └──────────────┘ ↓ │
│ ┌──────────────┐ │
│ │ Prefill 阶段 │ │
│ │ (计算输入token│ │
│ │ 的 KV Cache) │ │
│ └──────┬───────┘ │
│ │ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Decode 阶段(逐 token 生成,参与连续 Batching) │ │
│ │ for each iteration: │ │
│ │ scheduler.select_active_requests() │ │
│ │ batch.forward_step() ← 生成 1 个 token │ │
│ │ scheduler.check_completion() │ │
│ │ scheduler.check_new_requests() ← 可能有新请求插入 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
│ 请求完成 / 超时 / 被抢占 │
│ ↓ │
│ 释放 KV Cache,返回结果 │
└─────────────────────────────────────────────────────────────────┘
2. 调度算法详解
2.1 FCFS(First-Come-First-Served)
最简单,按到达顺序调度。公平但不高效——一个超长请求可能阻塞后续所有短请求。
2.2 SRPT(Shortest Remaining Processing Time)
优先调度”预估剩余时间最短”的请求。
优势:最小化平均完成时间
挑战:LLM 请求的剩余长度难以准确预估
实践:可用 prompt 长度、模型特性、历史统计做启发式估计
风险:长请求可能被无限延迟(饥饿问题)
2.3 基于优先级的调度
优先级来源:
- 用户等级(付费 > 免费)
- 请求类型(实时对话 > 批量处理)
- SLA 约束(延迟敏感 > 吞吐敏感)
- 前缀缓存命中率(有缓存的请求启动成本低)
实现方式:
- 多优先级队列
- 加权轮询
- 抢占式 vs 非抢占式
2.4 前缀感知调度(Prefix-Aware Scheduling)
动机: 如果多个请求共享相同前缀(system prompt、few-shot examples 等),它们的 KV Cache 可以复用。
请求A: [system prompt | 用户问题A]
请求B: [system prompt | 用户问题B]
请求C: [system prompt | 用户问题C]
→ 三个请求共享 system prompt 的 KV Cache
→ 调度器应将共享前缀的请求聚合在一起执行
→ 减少重复计算,降低显存占用
代表实现: SGLang 的 RadixAttention 通过前缀树(Radix Tree)管理共享前缀的 KV Cache,调度时优先复用已有缓存的请求组合。
3. 调度器的核心数据结构
# 简化的调度器状态模型(伪代码)
class SchedulerState:
# 每个 GPU 的状态
gpu_slots: List[GpuSlot]
class GpuSlot:
total_kv_cache_budget: int # 总 KV Cache 显存预算(tokens 数)
used_kv_cache: int # 已使用的 KV Cache
active_requests: List[Request] # 当前正在 decode 的请求
waiting_queue: PriorityQueue # 等待队列
class Request:
request_id: str
prompt_tokens: int # 输入 token 数
generated_tokens: int # 已生成 token 数
max_new_tokens: int # 最大可生成 token 数
priority: int # 优先级
kv_cache_usage: int # 当前 KV Cache 占用
status: Enum(WAITING, PREFILLING, RUNNING, SWAPPED, PREEMPTED)
class Scheduler:
def schedule_step(self):
"""每次 forward step 的调度决策"""
# 1. 检查是否有请求完成,释放资源
self._handle_completions()
# 2. 尝试唤醒被抢占/swap 的请求
self._try_resume_preempted()
# 3. 从等待队列取新请求,检查 KV Cache 容量
new_batch = self._select_new_requests()
# 4. 如果容量不足,执行抢占
if not self._has_capacity(new_batch):
self._preempt(self._select_victims(new_batch))
# 5. 组装最终 batch
return self._assemble_batch(new_batch)
4. 与 KV Cache 管理的深度耦合
请求调度与 KV Cache 管理是一体两面的关系:
┌─────────────────────────────────────────────┐
│ KV Cache 管理方案演进 │
├─────────────────┬───────────────────────────┤
│ 方案 │ 调度器需要感知的维度 │
├─────────────────┼───────────────────────────┤
│ 朴素连续内存 │ 每个请求的 KV Cache │
│ │ 独占连续显存块 │
│ │ → 碎片化问题严重 │
├─────────────────┼───────────────────────────┤
│ PagedAttention │ KV Cache 分页管理 │
│ (vLLM) │ → 类似 OS 虚拟内存 │
│ │ 调度器按 page 粒度分配 │
│ │ → 显存利用率大幅提升 │
├─────────────────┼───────────────────────────┤
│ Prefix Caching │ 共享前缀的 KV Cache │
│ │ 通过引用计数复用 │
│ │ → 调度器需感知前缀亲和性 │
├─────────────────┼───────────────────────────┤
│ KV Cache 压缩 │ 量化、蒸馏、稀疏化 │
│ │ → 影响每个请求的实际占用 │
│ │ 调度器需动态感知压缩率 │
└─────────────────┴───────────────────────────┘
技术演进史
| 时间 | 里程碑 | 核心创新 | 关键论文/项目 |
|---|---|---|---|
| ~2020 | 朴素静态 Batching | 请求攒一批再执行 | 早期 TFServing / Triton |
| 2022 | Orca:连续 Batching | 迭代级调度,请求级粒度 | OSDI 2022 (UC Berkeley 等) |
| 2023 | vLLM + PagedAttention | KV Cache 分页管理 | SOSP 2023 (UC Berkeley) |
| 2023 | Sarathi / Sarathi-Serve | Chunked Prefill 与 Decode 混合 | Microsoft Research |
| 2023–2024 | DistServe / Splitwise | Prefill-Decode 分离部署 | 学术界 + 产业界 |
| 2024 | SGLang RadixAttention | 前缀树管理共享 KV Cache | UC Berkeley |
| 2024 | Prefill-Decode 分离成主流方向 | 多个推理框架支持 | vLLM / TensorRT-LLM 等 |
| 2024–2025 | 调度与硬件深度协同 | 算子级调度、编译优化融合 | 各大厂自研平台 |
关键趋势: 调度器从”软件层独立模块”逐步向”软硬件协同的系统级优化”演进。
技术路线对比
| 维度 | 静态 Batching | 连续 Batching | 连续 + Chunked Prefill | PD 分离调度 |
|---|---|---|---|---|
| 调度粒度 | 请求级 | 迭代级 | 迭代级 + chunk | 阶段级(跨节点) |
| GPU 利用率 | 低 | 高 | 更高 | 最高(各自优化) |
| 长 prompt 对 decode 影响 | 严重阻塞 | 有阻塞 | 轻微 | 无(物理隔离) |
| 短请求延迟 | 受 batch 最长请求约束 | 低 | 低 | 最低 |
| 实现复杂度 | 低 | 中 | 中高 | 高 |
| 基础设施要求 | 单 GPU 可用 | 单 GPU 可用 | 单 GPU 可用 | 需要高速互联 |
| 适用场景 | 简单批量推理 | 通用在线推理 | 混合长度负载 | 大规模生产环境 |
| 生态支持 | 通用 | 主流引擎均支持 | vLLM/SGLang/TRT-LLM | 各厂自研为主 |
| KV Cache 效率 | 低 | 中(可配合 PagedAttn) | 中高 | 高(专用池化) |
上下游
上游(请求调度器的输入依赖)
┌─────────────────────────────────────────┐
│ 上游生态 │
├──────────────┬──────────────────────────┤
│ 应用层 │ API 网关、负载均衡器 │
│ │ 用户请求队列 │
├──────────────┼──────────────────────────┤
│ 模型层 │ 模型架构(影响 KV Cache │
│ │ 大小、Prefill 计算量) │
│ │ GQA/MQA 影响 KV 维度 │
├──────────────┼──────────────────────────┤
│ Tokenizer │ 分词结果影响 Prefill 长度 │
├──────────────┼──────────────────────────┤
│ 硬件层 │ GPU 数量、显存大小、 │
│ │ HBM 带宽、NVLink/互联拓扑 │
└──────────────┴──────────────────────────┘
下游(请求调度器影响的环节)
┌─────────────────────────────────────────┐
│ 下游生态 │
├──────────────┬──────────────────────────┤
│ 推理引擎 │ 内核执行、算子调度 │
│ │ KV Cache 管理器 │
├──────────────┼──────────────────────────┤
│ 用户体验 │ TTFT(首 token 延迟) │
│ │ TPOT(每 token 延迟) │
│ │ 端到端完成时间 │
├──────────────┼──────────────────────────┤
│ 基础设施成本 │ GPU 利用率 → 单位推理成本 │
│ │ QPS 能力 → 集群规模规划 │
├──────────────┼──────────────────────────┤
│ 业务能力 │ 并发用户数上限 │
│ │ 长上下文支持能力 │
└──────────────┴──────────────────────────┘
关键指标
系统级指标
| 指标 | 定义 | 业界参考量级 |
|---|---|---|
| Throughput (tokens/s) | 系统每秒处理的总 token 数(输入+输出) | 高度依赖模型/硬件/并发,不列具体数字 |
| QPS | 每秒完成的请求数 | 高度依赖请求长度分布 |
| TTFT | Time to First Token,用户感知首 token 延迟 | 毫秒到秒级,取决于 prompt 长度和排队 |
| TPOT | Time Per Output Token,每输出 token 延迟 | 通常 10–100ms 量级(估算) |
| P50 / P99 延迟 | 中位数和尾部延迟 | SLA 核心约束 |
| GPU 利用率 | GPU 算力实际使用比例 | 优化前后差异可达数倍(定性) |
| KV Cache 利用率 | 已分配 KV Cache / 总可用 | 受碎片化影响,PagedAttention 改善显著 |
调度器效率指标
| 指标 | 含义 |
|---|---|
| 调度开销 | 调度决策本身的 CPU 时间,通常应控制在微秒到毫秒级 |
| 抢占频率 | 单位时间内发生抢占的次数,过高说明容量规划不足 |
| 排队等待时间 | 请求从到达到开始 Prefill 的等待时间 |
| 前缀缓存命中率 | 复用已有 KV Cache 的请求占比 |
供需与市场数据
需求侧
- 推理成本占比持续上升: 据各厂商财报及行业分析,头部 AI 应用的推理成本已超过训练成本,推理优化 ROI 极高。
- 长上下文需求增长: 128K–1M+ 上下文窗口的应用越来越普遍,KV Cache 管理压力倍增。
- 多模态推理复杂化: 图片/视频/音频输入的 Prefill 成本远高于纯文本。
- 混合负载需求: 同一集群同时服务实时对话(低延迟优先)和批量处理(高吞吐优先),调度复杂度飙升。
供给侧
- 开源推理引擎竞争激烈: vLLM、SGLang、TensorRT-LLM 等在调度策略上快速迭代。
- 云厂商自建优化: 各大云厂商(AWS、Azure、GCP 及国内厂商)在推理服务平台上投入大量自研优化。
- 专用硬件+调度协同: Groq(LPU)、Cerebras(WSE)等将调度逻辑深度融入硬件设计。
- 调度优化成为推理芯片差异化竞争的重要维度。
关键数据参考(定性/估算)
- 推理服务中 GPU 的典型利用率在优化前可能低至 20%–40%,经调度优化后可提升至 60%–80%+(量级估算,高度依赖具体场景)
- PagedAttention 在 vLLM 论文中报告相比朴素实现在吞吐量上有显著提升(具体倍数取决于基线和工作负载)
- Chunked Prefill 在长 prompt 场景下可有效降低 decode 请求的尾部延迟
代表公司与资本映射
| 层级 | 公司/项目 | 与请求调度的关系 | 关联标的 |
|---|---|---|---|
| 开源推理引擎 | vLLM (UC Berkeley → 商业化) | PagedAttention + 连续 Batching 的标杆 | — |
| SGLang (UC Berkeley) | RadixAttention 前缀感知调度 | — | |
| TensorRT-LLM (NVIDIA) | NVIDIA 官方推理引擎 | NVDA | |
| 云推理服务 | AWS Bedrock | 平台级推理调度 | AMZN |
| Azure AI | 平台级推理调度 | MSFT | |
| Google Vertex AI | 平台级推理调度 | GOOG | |
| 专用推理硬件 | Groq | 调度与 LPU 硬件深度耦合 | 未上市 |
| Cerebras | WSE 上的调度逻辑 | 未上市 | |
| SambaNova | DataScale 调度优化 | 未上市 | |
| 国内推理平台 | 百度千帆、阿里 PAI、字节火山引擎等 | 各家自研调度优化 | BABA 等 |
| GPU 厂商 | NVIDIA | 推理调度生态核心(Triton Server + TRT-LLM) | NVDA |
| AMD (ROCm + vLLM 支持) | 逐步完善推理调度生态 | AMD |
投资逻辑映射: 请求调度优化 → GPU 利用率提升 → 单位推理成本下降 → 或同等成本下更高吞吐。这个方向利好”卖铲子”的(GPU/推理硬件厂商,因为高利用率 = 买更少的卡 = 但每张卡的单位价值更高 = 用户愿意为高效硬件付溢价),也利好”优化铲子效率”的推理平台/引擎。
投资逻辑
核心推理框架
推理成本 = GPU 数量 × 单卡成本 × 使用时间
↓
调度优化 → 同等 QPS 下所需 GPU 数量减少 → 直接降本
→ 或同等 GPU 数量下 QPS 提升 → 提升服务能力
四条投资主线
主线一:推理硬件厂商(NVIDIA/AMD 及专用芯片)
- 调度优化使 GPU 利用率提升,短期看似”卖更少的卡”
- 但长期效应:推理成本下降 → 更多应用被经济可行地部署 → 总需求增长
- 高效调度更利好硬件带宽/算力利用率高的芯片 → 加剧硬件差异化
主线二:云推理服务平台
- 调度优化是云厂商推理服务利润的核心杠杆
- 调度效率直接转化为利润率差异
- 具备自研调度优化能力的平台更具竞争力
主线三:推理引擎/中间件
- vLLM、SGLang 等开源项目背后的商业化机会
- 类似 Red Hat 模式:开源引擎 + 商业支持/托管
- 但护城河存疑,开源竞争激烈
主线四:应用层
- 推理成本下降使得此前”太贵”的 AI 应用变得可行
- 长上下文、实时多模态、Agent 等重度推理应用受益最大
风险因素
- 硬件迭代可能弱化软件调度优势: 如果专用硬件(如 Groq LPU)在架构层面解决了调度问题,软件层面的优化空间可能被压缩
- 模型架构变革: 如线性注意力等替代 Transformer 的架构如果成熟,KV Cache 管理问题可能消失或大幅变化
- 开源社区竞争: 领先调度技术可能快速被开源社区复制,难以形成持久商业壁垒
常见误读纠偏
❌ 误读一:“连续 Batching 就是请求调度的全部”
纠偏: 连续 Batching 只是调度策略的基线。真正的调度优化还包括:
- Chunked Prefill(解决长 prompt 阻塞问题)
- 前缀感知调度(最大化 KV Cache 复用)
- 抢占与迁移策略(解决显存不足时的应急)
- Prefill-Decode 分离(架构级优化)
- 跨 GPU/节点的负载均衡
连续 Batching 类比于”操作系统有了进程调度”,但调度算法的质量差异巨大。
❌ 误读二:“请求调度只是软件优化,与硬件无关”
纠偏: 调度决策与硬件特性高度耦合:
- NVLink/NVSwitch 互联拓扑影响跨 GPU 调度策略
- HBM 带宽 vs 容量的权衡影响 KV Cache 管理策略
- 不同 GPU 的 Prefill/Decode 性能比不同,影响 PD 分离策略
- 专用推理硬件(如 Groq LPU)将调度逻辑固化在芯片架构中
调度效率的上限由硬件决定,软件调度是在硬件约束下的最优解搜索。
❌ 误读三:“调度器的 CPU 开销可以忽略”
纠偏: 在高频调度场景下,调度器本身的 CPU 开销可能成为瓶颈:
- 每次 forward step 都需要调度决策
- 复杂的抢占/迁移决策、KV Cache 管理涉及大量指针操作
- 在大集群、高并发场景下,调度器可能需要独立的 CPU 资源
- 这也是为什么生产级系统中调度器实现需要极致优化
❌ 误读四:“Prefill-Decode 分离一定优于共置”
纠偏: 分离部署引入了额外的 KV Cache 传输开销。如果互联带宽不足或请求以短序列为主,分离带来的收益可能被传输开销抵消。最佳策略取决于具体工作负载和硬件条件,不存在”一招鲜”的方案。
学习路径
入门(建立直觉)
- 理解 LLM 推理基本流程: Prefill → Decode → 逐 token 自回归
- 阅读 vLLM 官方博客/文档: 理解 PagedAttention 的核心思想
- 动手体验: 用 vLLM 部署一个小模型,观察不同 batch size 下的吞吐变化
进阶(理解机制)
- 精读 Orca 论文: 理解连续 Batching 的设计思想和迭代级调度
- 精读 vLLM 论文: 理解 PagedAttention + 调度器的完整设计
- 阅读 SGLang 的 RadixAttention: 理解前缀感知调度
- 了解 Chunked Prefill: Sarathi / Sarathi-Serve 论文
高级(系统级思考)
- 阅读 DistServe / Splitwise 相关工作: 理解 PD 分离的系统架构
- 研究 vLLM / SGLang 源码中的 Scheduler 实现: 理解工程实现细节
- 关注硬件-调度协同设计: Groq LPU 架构、TPU 的推理调度特性等
- 思考推理调度的”下一步”: 多模态调度、Agent 场景的多轮调度、跨数据中心调度
推荐阅读清单
- [论文] Orca: A Distributed Serving System for Transformer-Based Generative Models (OSDI 2022)
- [论文] Efficient Memory Management for Large Language Model Serving with PagedAttention (SOSP 2023)
- [论文] Sarathi: Efficient LLM Inference by Piggybacking Decodes with Chunked Prefills
- [论文] DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving
- [文档] vLLM 官方文档 — 调度相关章节
- [文档] SGLang 官方文档 — RadixAttention 相关章节
- [代码] vLLM GitHub 仓库
vllm/core/scheduler.py - [代码] SGLang GitHub 仓库中调度器实现
一句话总结
请求调度是 LLM 推理效率的”第一性原理”——它不改变模型能力,但直接决定了同样的 GPU 能产出多少有用 token,是推理成本战争中最关键的软件杠杆。
延伸阅读与来源
| 来源 | 说明 |
|---|---|
| Orca (OSDI 2022) | 连续 Batching 的奠基论文 |
| vLLM (SOSP 2023) | PagedAttention + 完整调度系统设计 |
| SGLang 官方文档 | RadixAttention 前缀缓存调度 |
| Sarathi / Sarathi-Serve | Chunked Prefill 方案 |
| DistServe | Prefill-Decode 分离调度 |
| vLLM / SGLang / TensorRT-LLM GitHub | 工程实现参考 |
| 各厂商技术博客 | AWS / Azure / GCP 及国内厂商推理优化实践分享 |
声明: 本文中的性能数据、优化倍数等若无明确来源标注,均为基于公开信息的定性估计或量级判断,具体数字因模型、硬件、工作负载不同而差异显著。建议以厂商官方 benchmark 和论文报告为准。