跳转到内容

Orca — Transformer 生成模型的分布式推理调度

待复核

Orca 是 2022 年 OSDI 提出的 大模型在线推理调度系统。它解决的核心问题是:用户请求长短不一、到达时间随机,传统「整批一起算」的 batching 让 GPU 大量空转。

日常类比:餐厅如果必须等一桌人全到齐才上菜,短桌客人干等、长桌客人饿着。Orca 像回转寿司——菜(计算任务)按迭代粒度不断加进传送带,谁到了谁先算,不等整桌。

两大技术:iteration-level scheduling(按生成步调度)和 selective batching(只把当前能一起算的请求编进一批)。

读本文时会碰到三个词(先当日常物件记):

  • prefill:先把用户整段 prompt 吃进去(算力密集,像一口气读完整封信)
  • decode:之后一次吐一个 token(更吃显存带宽,像逐字回信)
  • KV cache:每条请求的「已读上下文便签」;调度必须跟便签的分配/回收绑在一起,否则桌上便签堆爆(OOM)

不懂 Orca,下面这些事说不清:

  • 为什么 vllm 的 continuous batching 不是凭空出现——Orca 是思想源头之一
  • 为什么 LLM serving 的吞吐不靠「更大的 batch」,而靠更细的调度粒度
  • 为什么同一 GPU 上混跑 1-token 和 100-token 的请求会互相拖累
  • 为什么 2022 年的系统论文比很多 2024 模型论文更影响工业部署
  1. Request-level batching 的浪费:生成模型要跑很多步,每步还活着的请求数不同;按「整个请求」组 batch,短请求结束后仍占坑做 padding。类比:大巴必须等满员才发车,先到的人干坐。

  2. Iteration-level scheduling:调度器以单步 decode 为单位组 batch。这一步结束的请求退出,新到的插进来——即 continuous batching 的前身。类比:回转寿司每转一圈都能上下菜。

  3. Selective batching:只合并当前迭代兼容的请求(同阶段、可共享算子路径),避免把 prefill 和 decode 硬塞一批。类比:同一传送带只放同温区的菜,热菜冷菜分轨。

# Request-level(3 个请求,生成长度 2/5/8)
t=0: [R1,R2,R3] prefill 一起算
t=1: [R1,R2,R3] decode → R1 已完成仍占坑(浪费)
...
# Iteration-level(Orca)
t=1: [R2,R3,R4新到] decode → R1 完成立刻腾出槽位给 R4

逐部分解释

  • 左边按「整桌」组批:R1 早结束仍占 GPU 槽位
  • 右边按「每转一圈」组批:结束立刻让位,新请求可插队
  • 吞吐提升来自减少空转,不是单纯把 batch 数字调大
class OrcaScheduler:
def schedule(self, waiting, running):
# 只收当前处于 decode 的请求,不跨阶段硬 batch
batch = [r for r in running if r.phase == "decode"]
free = max_batch - len(batch)
batch += pick_new(waiting, max_batch=free)
return run_one_iteration(batch) # 只跑一步,再重新调度

逐部分解释

  • phase == "decode":selective——阶段不对的不进本批
  • pick_new:本步有空位才拉新请求,对应 iteration-level 的「随时上下菜」
  • run_one_iteration:只前进一步,下一步重新决定谁留下

案例 3:与 vLLM 对照(思想 vs 工程)

Section titled “案例 3:与 vLLM 对照(思想 vs 工程)”
Orca (2022) → iteration-level + selective batching(时间碎片)
vLLM (2023) → + PagedAttention KV 管理(内存碎片)
工业 serving → 两者组合成今天 LLM API 的默认架构

逐部分解释

  • Orca 解决「谁何时上 GPU」(时间碎片)
  • vllm 解决「KV 便签怎么切页不碎」(内存碎片)
  • 工业默认栈通常两者都要;只抄调度不抄 cache 管理,线上仍会碎

SLO 视角:P99 常被最长生成拖累。Selective + iteration-level 让短请求能逐步插队完成,而不必等长请求整段结束——这是在线 API 体验,不只是平均吞吐数字。

  1. KV cache 没跟调度绑定:迭代调度每步进出请求,若 cache 不回收,几分钟就 OOM。
  2. prefill 与 decode 硬塞一批:算子形状/掩码对不上,轻则 padding 爆炸,重则结果错。
  3. 以为 batch 越大越好:大 batch + 长 padding 会把短请求 P99 拖死。
  4. 离线流量套用在线假设:泊松到达 + 长度方差大才吃香;纯离线静态 batch 收益很小。

适用

  • 在线 LLM API(ChatGPT 类),并发 ≥ 几十、长度方差大
  • 需要抬高 GPU 利用率、压低短请求尾延迟
  • 要理解 continuous batching 工业实现的论文源头

不适用

  • 离线大批量推理(静态 batch + 固定长度更简单)
  • 极小模型或极低 QPS(调度开销占比过高)
  • 非自回归 / 非逐步生成模型(调度假设不同)
  • 2020 前:CV 推理 batch 成熟,LLM 生成式 serving 几乎空白
  • 2022 OSDI:Orca 提出 iteration-level 范式
  • 2023vllm 加 PagedAttention,continuous batching 工业化
  • 今天:主流 inference engine 都继承这条调度路线
  1. 生成式 serving 的瓶颈在调度,不只在算子
  2. 迭代粒度是 continuous batching 的核心抽象
  3. 系统论文有时比模型论文更长寿
  4. 读 Orca + vLLM 才能拼出完整 serving 图景(时间碎片 + 内存碎片)
  • 论文:OSDI 2022 Orca
  • vllm —— PagedAttention + continuous batching 工业实现
  • orca-continuous-batching —— 思想延续条目
  • whisper-2022 —— 另一类大规模推理负载(ASR)
  • OSDI 2022 talk 视频 —— 看 iteration 时间线动画更直观
  • 复现实验时用泊松到达 + 可变长度;静态等长 batch 对比几乎无意义