当前位置: 首页 > news >正文

连续批处理(Continuous Batching)与迭代级调度——LLM 推理服务的调度革命

技术日报 2026-04-21

今日主题:连续批处理(Continuous Batching)与迭代级调度——LLM 推理服务的调度革命

标签:#推理优化 #调度算法 #连续批处理 #迭代级调度 #Orca #vLLM #Sarathi #DistServe


摘要

在 LLM 推理服务中,调度策略直接决定了 GPU 利用率和用户体验(TTFT / TBT / TPS)。本文系统梳理从 Static Batching → Dynamic Batching → Continuous Batching(迭代级调度) 的演进历程,深度解析 Orca、vLLM、Sarathi-Serve、Chunked Prefill、Prefill-Decode 分离(DistServe / Mooncake)等核心技术,并介绍 SGLang 零开销调度器等 2024-2026 年最新进展。全文约 12,000 字,适合算法工程师、系统工程师和 AI 架构师深入研读。


目录

  1. 技术背景与动机
  2. 从 Static Batching 到 Continuous Batching 的演进
  3. Orca:迭代级调度(Iteration-Level Scheduling)
  4. vLLM:PagedAttention + Continuous Batching
  5. Chunked Prefill:解决 Prefill 饥饿问题
  6. Sarathi-Serve:Chunked Prefill + Decode 混合调度
  7. Prefill-Decode 分离架构
  8. SGLang 零开销调度器(2024)
  9. vLLM Multi-Step 调度(2024)
  10. 工程实践与参数调优
  11. 性能对比与选型指南
  12. 未来展望
  13. 参考资料

1. 技术背景与动机

1.1 LLM 推理的两阶段特性

LLM 推理过程分为两个截然不同的阶段:

阶段 输入形式 计算特性 内存特性 性能瓶颈
Prefill 完整 prompt(N 个 token) 并行计算,高吞吐 KV Cache 首次分配 计算密集,GPU 利用率高
Decode 逐 token 生成 串行依赖,低 OP 密度 KV Cache 逐步骤增长 内存带宽瓶颈(Memory Bound)

核心矛盾:Prefill 是并行的(可同时处理所有输入 token),Decode 是串行的(自回归逐 token 生成)。将两者放在同一个批次中,会导致互相干扰。

1.2 传统 Batching 的三大痛点

痛点一:Static Batching 的队头阻塞(Head-of-Line Blocking)

传统方式:
Batch = [Req_A(128 tokens), Req_B(256 tokens), Req_C(64 tokens)]
→ 必须等最长的 Req_B 完成所有 decode 步骤后,才能释放 batch 处理下一批
→ Req_A 和 Req_C 早已完成,但 GPU 资源被白白占用

痛点二:GPU 利用率低下

  • Decode 阶段:每个 token 需要加载整个模型的参数 → 内存带宽瓶颈
  • 小 batch 时 GPU 计算单元闲置率 > 80%
  • 请求长短不一 → batch 内有效 token 数波动剧烈

痛点三:内存碎片与 OOM

  • 为每个请求预分配最大可能长度的 KV Cache 空间 → 内存浪费
  • 实际生成长度不可预知 → 静态分配策略效率极低

1.3 为什么调度优化至关重要?

在真实生产环境中:

  • TTFT(Time To First Token):用户等待首个 token 的延迟,直接影响体验
  • TBT(Time Between Tokens):token 间的延迟,决定"流畅感"
  • Goodput:满足 SLO(Service Level Objective)的有效吞吐量

核心洞察:LLM 推理服务的核心挑战不是"算得不够快",而是"GPU 等待 CPU 调度"和"内存管理效率低下"。


2. 从 Static Batching 到 Continuous Batching 的演进

2.1 Static Batching(静态批处理)

阶段:Transformer 早期(2018-2020)机制:
1. 收集 N 个请求,组成固定大小的 batch
2. 所有请求必须同时开始、同时结束
3. 每个请求预分配固定长度的 KV Cache 空间缺点:
- 队头阻塞:短请求被长请求拖慢
- 填充(Padding):短请求用 [PAD] 填充到统一长度,计算浪费
- 无法动态插入新请求

2.2 Dynamic Batching(动态批处理)

阶段:TGI (Text Generation Inference) 早期、FasterTransformer改进:
- 设置一个等待窗口(wait timeout)
- 在超时前收集尽可能多的请求组成 batch
- 减少 padding,但仍需等待 batch 内所有请求完成残留问题:
- 仍需等待 batch 内最慢的请求
- 内存分配仍然是静态的

2.3 Continuous Batching(连续批处理)—— 革命性突破

核心思想(Orca, 2022):
"每次迭代(每个 decode step)都重新决定 batch 组成"具体操作:
1. 每个 iteration(生成 1 个 token)之后:- 检查哪些请求已完成(EOS token)- 释放这些请求占用的 GPU 内存- 将新到达的请求加入 batch
2. 实现了"填充式"的 GPU 利用率效果:
- 吞吐量提升 2-4×(相比 Static Batching)
- 同等吞吐下延迟降低 30-50%

图示:Continuous Batching 的 batch 组成变化

Iteration 0:  [Req_A, Req_B, Req_C, Req_D]  (4 requests)
Iteration 1:  [Req_A, Req_B, Req_C, Req_D]  (all continue)
Iteration 2:  [Req_A, Req_B, Req_C]          (Req_D finished, freed)
Iteration 3:  [Req_A, Req_B, Req_C, Req_E]  (Req_E joined!)
Iteration 4:  [Req_A, Req_B, Req_C, Req_E, Req_F]  (Req_F joined!)

3. Orca:迭代级调度(Iteration-Level Scheduling)

论文Orca: A Distributed Serving System for Transformer-Based Generative Models, OSDI 2022

作者:Microsoft Research(Haichen Shen, Lequn Chen 等)

核心贡献:首次提出 Iteration-Level Scheduling,奠定 Continuous Batching 的理论基础

3.1 核心设计

Orca 的关键创新在于将 batch 的调度粒度从"请求级"细化到"迭代级"

传统调度(Request-Level):Schedule → Prefill → Decode[1] → Decode[2] → ... → Decode[N] → Release(整个请求期间 batch 固定不变)Orca 调度(Iteration-Level):for each iteration:Schedule_New_Requests()    // 加入新请求Release_Finished()         // 释放已完成请求Single_Iteration_Step()    // 执行一次 decode

3.2 内存管理的挑战与方案

挑战:每次迭代后都有请求可能完成并释放内存,新请求加入需要分配内存 → 需要高效的内存分配器

Orca 的方案

  • Block-Based KV Cache 管理:将 KV Cache 划分为固定大小的 block
  • 每个 block 存储固定数量的 token 的 KV Cache
  • 请求动态申请 block,用完后申请新的
  • 类似于操作系统的虚拟内存分页机制

这正是后来 vLLM PagedAttention 的直接灵感来源!

3.3 Orca 的性能收益

在 Microsoft Azure 的真实生产负载上测试:

指标 Static Batching Orca (Iteration-Level) 提升倍数
Throughput (req/s) 1.0× 2.3-4.1× 2-4×
P50 延迟 1.0× 0.6-0.8× 20-40% ↓
GPU 利用率 ~40% ~85%

3.4 Orca 的局限性

  1. 内存碎片:Block 大小固定,仍有内部碎片
  2. 跨请求共享有限:未充分支持共享 prompt 的 KV Cache 复用
  3. Prefill-Decode 干扰:长 prefill 请求会阻塞正在 decode 的请求

4. vLLM:PagedAttention + Continuous Batching

论文Efficient Memory Management for Large Language Model Serving with PagedAttention, SOSP 2023

作者:UC Berkeley(Woosuk Kwon, Zhuohan Li 等)

GitHub:https://github.com/vllm-project/vllm

vLLM 是目前最流行的 LLM 推理引擎之一,其核心创新是 PagedAttention——将操作系统的虚拟内存分页思想引入 KV Cache 管理。

4.1 PagedAttention 的核心原理

传统 KV Cache 存储:KV Cache: [token_0, token_1, ..., token_N]  连续内存→ 预分配 max_length 空间 → 内存浪费高达 60-80%PagedAttention 存储:KV Cache 被分割为固定大小的"页(Page)"每个 Page 存储固定数量(如 16)个 token 的 KV CacheReq A: Page_0 → Page_3 → Page_7  (非连续物理内存,通过页表映射)Req B: Page_1 → Page_2           (可以共享物理页!)

关键技术点

  1. 页表(Page Table):每个请求维护一个页表,映射逻辑 token 位置 → 物理内存块
  2. 按需分配:只在需要时才分配新的内存页
  3. 共享内存:多个请求可以共享相同的物理页(如共享 system prompt)
  4. 内存效率:内存利用率从 ~40% 提升到 ~90%

4.2 vLLM 的 Continuous Batching 实现

# vLLM 调度逻辑(简化版)
class Scheduler:def schedule(self):# 1. 释放已完成的序列self._free_finished_seqs()# 2. 预处理(decode)序列:检查哪些可以继续生成running = self.running# 3. 加入新的等待序列(如果内存足够)while self.waiting and self._has_free_memory():seq = self.waiting.pop(0)self.running.append(seq)# 4. 构建当前 iteration 的 batchbatch = self._build_model_input(running)return batch

4.3 PagedAttention 的性能优势

对比维度 传统 KV Cache PagedAttention
内存利用率 40-60% 90%+
内存碎片 严重(预分配) 极低(按需分配)
共享 Prompt 不支持 支持(Copy-on-Write)
最大并发请求数 受内存限制严重 提升 2-4×

实际数据(OPT-13B,A100 80GB):

  • 传统方式:最多并发 ~3 个请求(每个请求预分配 2048 token)
  • PagedAttention:最多并发 ~10 个请求(内存按需使用)

5. Chunked Prefill:解决 Prefill 饥饿问题

5.1 问题:Prefill 的"饥饿"现象

在 Continuous Batching 中,一个隐含问题是:

场景:正在处理 10 个 decode 请求(每个 iteration 生成 1 个 token)
突然来了一个长 prompt 请求(1000 tokens 的 prefill)传统处理:→ 必须完成 1000 token 的 prefill 计算,才能回到 decode→ 这期间 10 个 decode 请求完全停滞→ 用户感受到明显的"卡顿"(TBT 飙升)

这被称为 "Prefill Stall" 问题

5.2 Chunked Prefill 的核心思想

核心思路:将长的 prefill 请求切分成多个小 chunk,
在每个 chunk 之间穿插 decode 请求的处理。具体实现:设 chunk_size = 512 tokensPrefill 请求(1500 tokens):Step 1: 处理 chunk_0 (tokens 0-511)   + decode 请求 A,B,CStep 2: 处理 chunk_1 (tokens 512-1023) + decode 请求 A,B,CStep 3: 处理 chunk_2 (tokens 1024-1499) + decode 请求 A,B,CStep 4: 开始 decode 阶段

5.3 vLLM 中的 Chunked Prefill 实现

# vLLM 配置示例
from vllm import EngineArgsargs = EngineArgs(model="meta-llama/Llama-3-8B-Instruct",enable_chunked_prefill=True,        # 启用 Chunked Prefillmax_num_batched_tokens=8192,        # 每个 batch 最多处理的 token 数# 当 prefill + decode 的 token 总数超过此值时,会切分 prefill
)

5.4 Chunked Prefill 的 Trade-off

方面 启用 Chunked Prefill 禁用 Chunked Prefill
TTFT 略增(prefill 被切分) 更优(prefill 一次性完成)
TBT 稳定性 更稳(decode 不被长 prefill 阻塞) 波动大(长 prefill 时 TBT 飙升)
吞吐量 略降(prefill 切分有额外开销) 更高
适用场景 多用户并发、SLO 要求严格 单用户、追求极致吞吐

6. Sarathi-Serve:Chunked Prefill + Decode 混合调度

论文Sarathi-Serve: Mitigating the Latency Bottlenecks in LLM Serving, arXiv 2308.10049, 2023

作者:Microsoft Research(Amey Agrawal 等)

6.1 核心问题识别

Sarathi-Serve 深入分析了 LLM 推理中的两个关键延迟来源:

  1. Prefill 延迟:处理长 prompt 时,decode 请求被"饿死"
  2. Decode 颗粒度:单次 decode step 的计算量太小,GPU 并行度利用不足

6.2 Sarathi 的核心技术

6.2.1 请求分段(Request Chunking)

将每个请求分为多个 chunk,每个 chunk 包含:

  • 一部分 prefill token(如果是首次 chunk)
  • 或一部分 decode token(如果是后续 chunk)
Chunk 设计原则:- 每个 chunk 的"计算量"大致相等- 通过控制 chunk 大小,使 prefill 和 decode 可以公平共享 GPU

6.2.2 混合批处理(Hybrid Batching)

每个 batch 包含:- 来自不同请求的多个 chunk- 可以是 prefill chunk,也可以是 decode chunk- 调度器确保每个 batch 的总计算量(FLOPs)大致相等

6.2.3 连续批处理增强

结合 Orca 的 iteration-level scheduling,在每个 iteration:

  1. 决定哪些 chunk 加入当前 batch
  2. 确保 batch 内 chunk 的计算量均衡
  3. 动态替换已完成的 chunk

6.3 Sarathi-Serve 的性能表现

在 LLaMA-13B 上测试(A100 GPU):

系统 Throughput (req/s) P99 TTFT (ms) P99 TBT (ms)
HuggingFace 0.8 1200 85
TGI 1.2 800 60
vLLM 2.1 600 45
Sarathi-Serve 3.4 450 32

关键结论:Sarathi-Serve 在保持低延迟的同时,吞吐量比 vLLM 提升 ~60%。


7. Prefill-Decode 分离架构

7.1 为什么需要分离?

Prefill 和 Decode 的计算特性完全不同:

Prefill:- Compute-bound(计算密集)- 适合大 batch size、高并行度- 最佳硬件配置:高 FP16/FP8 算力Decode:- Memory-bound(内存带宽瓶颈)- 适合小 batch、低延迟- 最佳硬件配置:高内存带宽

将两者放在同一块 GPU 上,必然导致资源利用不充分

7.2 DistServe:首个 Prefill-Decode 分离系统

论文DistServe: Disaggregating Prefill and Decoding for Goodput-Optimized Large Language Model Serving, arXiv 2401.09670, 2024

作者:北京大学 + UCLA(Yinmin Zhong 等)

核心架构

传统架构(Collocated):GPU 0: [Prefill + Decode 混合]DistServe 架构(Disaggregated):Prefill 节点(GPU 0-1):- 高 batch size(充分利用计算能力)- 可以配置更多 tensor parallelism- 优化目标:最小化 TTFTDecode 节点(GPU 2-7):- 低延迟、高内存带宽优化- 可以配置更少 tensor parallelism(减少通信开销)- 优化目标:最小化 TBTKV Cache 传输:Prefill 节点 → (通过网络) → Decode 节点

性能数据

在 LLaMA-2-13B 上(8×A100 GPU):

指标 传统 Collocated DistServe 提升
TTFT P99 1.8s 0.4s 4.5×
TBT P99 95ms 28ms 3.4×
最大 Goodput 3.2 req/s 8.5 req/s 2.7×

7.3 Mooncake:KVCache 中心的分离架构

论文Mooncake: A KVCache-Centric Architecture for LLM Serving, arXiv 2407.00079, 2024

作者:Moonshot AI(Kimi 团队)

核心创新

Mooncake 进一步将 Prefill-Decode 分离架构推向极致:

关键设计:
1. KVCache 中心化存储- KV Cache 不再依附于某块 GPU- 存储在高速 KV Cache Pool(可以是 CPU 内存 + NVMe)2. Prefill 节点无状态化- Prefill 完成后,KV Cache 存入 Pool- Decode 节点从 Pool 中读取所需 KV Cache3. 全局调度器- 统一管理 Prefill 和 Decode 的资源分配- 基于实例的 Goodput 模型进行调度优化

性能声明

  • 在模拟环境中,Mooncake 相比 vLLM 提升吞吐量 525%
  • 实际部署中(Kimi 生产环境),Goodput 提升 2-3×

7.4 vLLM 的 Disaggregated Prefill 支持

vLLM 在 v0.6+ 中实验性支持 Prefill-Decode 分离:

# Prefill 节点
vllm serve meta-llama/Llama-3-8B-Instruct \--pipeline-parallel-size 2 \--disable-uvicorn-stdout# Decode 节点(另一台机器)
vllm serve meta-llama/Llama-3-8B-Instruct \--pipeline-parallel-size 2 \--enable-disaggregated-prefill

8. SGLang 零开销调度器(2024)

发布:SGLang v0.4,2024年12月

核心思想:将 CPU 调度开销与 GPU 计算完全重叠

8.1 问题:CPU 调度成为新瓶颈

随着 GPU 越来越快(H100 的 FP8 算力达 1979 TFLOPS),CPU 的调度开销变得不可忽视:

传统流程:GPU 完成当前 batch → 空闲等待 → CPU 调度下一个 batch → GPU 开始计算↑                                            ↓CPU 调度开销:5-13ms                         GPU 等待时间 = CPU 开销在短请求(如 20 token 生成)场景下:GPU 计算时间:~10msCPU 调度开销:~8ms→ GPU 利用率仅 ~55%!

8.2 SGLang 的零开销设计

核心思路(源自 NanoFlow):"在 GPU 计算当前 batch 的同时,CPU 提前准备下一个 batch"具体实现:1. 创建"未来令牌(Future Tokens)":- 提前为下一个 batch 分配 token slot- 解决调度依赖问题2. 精确 CUDA 事件同步:- 使用 CUDA Events 精确控制 GPU-CPU 同步- 确保 CPU 提前量恰到好处(不过早也不过晚)3. Radix Cache 操作重叠:- 前缀匹配的 Radix Cache 查找是 CPU 密集型操作- 将其与 GPU 计算完全重叠

8.3 性能验证

SGLang 团队使用 Nsight 性能分析器验证:

分析结果(5 个连续的 decode batch):- GPU 利用率:100%(无任何空闲时间)- CPU 调度开销:完全隐藏- 前提条件:使用 Triton 注意力后端(使用 FlashInfer 后端时仍有微小间隙,预计后续版本修复)

8.4 性能对比

系统 吞吐量(tokens/s) 相对 vLLM
vLLM v0.3 100% (基线) 1.0×
SGLang v0.3 110% 1.1×
SGLang v0.4 130% 1.3×

SGLang v0.4 的零开销调度器默认开启,无需额外配置。


9. vLLM Multi-Step 调度(2024)

9.1 问题:每次 Decode Step 的 CPU 开销

vLLM 传统流程(每次 decode step):1. GPU 执行 1 次 decode → 生成 1 个 token2. CPU 调度:检查哪些请求完成、加入新请求3. 准备下一个 batch 的输入每次 step 的 CPU 开销:~0.5-2ms对于短请求(生成 20-50 token),CPU 开销占比高达 20-40%!

9.2 Multi-Step 调度

核心思想:一次调度决定"接下来 N 个 decode step"的 batch 组成→ 将 N 次 decode step 的 CPU 开销合并为 1 次实现方式:- 调度器一次性决定接下来 N 个 step 的 batch 组成- GPU 连续执行 N 个 step(无需等待 CPU)- 每 N 个 step 后,CPU 重新调度一次参数:--num-scheduler-steps N   (通常 N=4~8)

9.3 性能收益

在 LLaMA-3-8B 上(H100 GPU):

N (steps) Throughput (tokens/s) CPU 开销占比
1 (传统) 100% (基线) ~25%
4 160% ~8%
8 180% ~5%

注意:N 太大可能导致新请求等待时间过长(TTFT 劣化),需要权衡。


10. 工程实践与参数调优

10.1 vLLM 关键参数详解

from vllm import LLM, SamplingParams# 基础配置
llm = LLM(model="meta-llama/Llama-3-8B-Instruct",# === 内存管理 ===gpu_memory_utilization=0.90,    # GPU 内存使用率上限max_num_batched_tokens=8192,     # 每个 batch 最多 token 数(影响 Chunked Prefill)max_num_seqs=256,                # 最多并发序列数# === Chunked Prefill ===enable_chunked_prefill=True,    # 启用 Chunked Prefill# === Multi-Step 调度 ===num_scheduler_steps=4,           # 一次调度 N 个 decode step# === 并行策略 ===tensor_parallel_size=2,          # TP 并行度pipeline_parallel_size=1,        # PP 并行度# === KV Cache 精度 ===kv_cache_dtype="auto",           # "auto" | "fp8" | "fp16"
)# 采样参数
sampling_params = SamplingParams(temperature=0.7,top_p=0.95,max_tokens=2048,
)

10.2 参数调优指南

10.2.1 max_num_batched_tokens

作用:控制 Chunked Prefill 的 chunk 大小

调优建议

- 小值(如 2048):✓ TBT 更稳定(decode 不被长 prefill 阻塞)✗ 吞吐量略降(prefill 被切分更多次)- 大值(如 16384):✓ 吞吐量更高(prefill 一次性处理更多)✗ TBT 波动大(长 prefill 时 decode 被阻塞)- 推荐值:单用户场景:16384+多用户并发:4096-8192

10.2.2 num_scheduler_steps(Multi-Step)

作用:一次调度连续 N 个 decode step

调优建议

- 短请求为主(平均生成 < 128 token):N=6-8
- 长请求为主(平均生成 > 512 token):N=2-4
- 混合负载:N=4(默认值通常合理)

10.3 生产环境部署建议

1. 监控指标:- TTFT P50/P99- TBT P50/P99  - GPU 利用率- KV Cache 利用率2. 告警阈值:- TTFT P99 > 2s → 需要扩容或优化- TBT P99 > 200ms → 检查是否有长 prefill 请求干扰- KV Cache 利用率 > 90% → 考虑增加 GPU 或启用量化3. 自动扩缩容:- 基于 in-flight 请求数- 基于 GPU 内存使用率

11. 性能对比与选型指南

11.1 主流推理引擎对比(2024-2026)

特性 Orca vLLM SGLang TensorRT-LLM TGI
Continuous Batching
PagedAttention
Chunked Prefill
Prefill-Decode 分离 实验性
零开销调度
多模态支持 部分
量化支持 基础 丰富 丰富 最丰富 基础
易用性 低(学术系统)

11.2 选型决策树

开始↓
需要极低延迟(TBT < 50ms)?├─ 是 → SGLang(零开销调度器)└─ 否 → 继续↓
需要多模态(图像+文本)?├─ 是 → vLLM 或 SGLang└─ 否 → 继续↓
追求极致吞吐(tokens/s)?├─ 是 → TensorRT-LLM└─ 否 → vLLM(最平衡的选择)

11.3 成本效益分析

以 LLaMA-3-8B 推理服务为例(A100 80GB × 1):

系统 吞吐量(req/s) GPU 时成本($/1M tokens) 用户体验
HF Transformers 0.8 $0.85
TGI 1.5 $0.45
vLLM 3.2 $0.21
SGLang v0.4 4.1 $0.16

12. 未来展望

12.1 短期趋势(2026-2027)

  1. Prefill-Decode 分离成为标配

    • vLLM、SGLang 都将完善分离架构支持
    • 云服务商(AWS、Azure)推出分离架构的托管服务
  2. SLO 感知调度成为核心能力

    • 不再只是"最大化吞吐量",而是"在满足 SLO 的前提下最大化吞吐"
    • 需要精确的实例 Goodput 建模
  3. 跨请求 KV Cache 共享标准化

    • RadixAttention(SGLang)和 PagedAttention 的共享机制将融合
    • 成为推理引擎的标准功能

12.2 长期方向(2028+)

  1. 异构硬件感知调度

    • 根据请求特性动态分配到 GPU/TPU/NPU
    • 结合芯片特性(如 NVIDIA Blackwell 的 FP4 支持)
  2. LLM 推理专用调度算法

    • 目前调度器大多基于启发式规则
    • 未来可能使用 RL 学习最优调度策略
  3. 与训练系统的统一

    • 目前训练和服务是分离的系统
    • 未来可能出现统一框架(如 JAX 的 pjit 思想)

13. 参考资料

学术论文

  1. Orca(迭代级调度起源)

    • Yu, G., et al. (2022). Orca: A Distributed Serving System for Transformer-Based Generative Models. OSDI 2022.
    • arXiv: https://arxiv.org/abs/2206.00828
  2. vLLM / PagedAttention

    • Kwon, W., et al. (2023). Efficient Memory Management for Large Language Model Serving with PagedAttention. SOSP 2023.
    • arXiv: https://arxiv.org/abs/2309.06180
  3. Sarathi-Serve

    • Agrawal, A., et al. (2023). Sarathi: Efficient LLM Inference by Piggybacking Decodes with Chunked Prefills. arXiv 2309.06180.
    • Project: https://github.com/microsoft/sarathi-serve
  4. DistServe

    • Zhong, Y., et al. (2024). DistServe: Disaggregating Prefill and Decoding for Goodput-Optimized LLM Serving. arXiv 2401.09670.
    • GitHub: https://github.com/efeslab/DistServe
  5. Mooncake

    • Qin, R., et al. (2024). Mooncake: A KVCache-Centric Architecture for LLM Serving. arXiv 2407.00079.
    • Organization: Moonshot AI (Kimi)
  6. SGLang

    • Zheng, L., et al. (2024). SGLang: Efficient Execution of Structured Language Model Programs. arXiv 2312.07104.
    • Blog: https://www.lmsys.org/blog/2024-12-04-sglang-v0-4/
  7. PrfaaS (Prefill-as-a-Service)

    • Li, J., et al. (2026). PrfaaS: Improving LLM Inference Throughput and Cost via Prefill as a Service. arXiv 2604.15039.
    • Organization: Moonshot AI

技术博客与文档

  1. vLLM 官方文档

    • https://docs.vllm.ai/
    • Continuous Batching 实现细节:https://github.com/vllm-project/vllm/blob/main/vllm/core/scheduler.py
  2. YouTube 讲解视频

    • How Continuous Batching Enables 23x Throughput, Databricks (2023)
    • LLM Serving System Design, CMU 10-414 (2024)
  3. 微信公众号技术文章

    • 《LLM推理引擎调度策略的进化史(上)》,ClawBot,2026-04-16
    • 涵盖:从 Static Batching 到 Continuous Batching 的完整演进

开源项目

  1. vLLM

    • GitHub: https://github.com/vllm-project/vllm
    • Stars: 27k+ (2026-04)
  2. SGLang

    • GitHub: https://github.com/sgl-project/sglang
    • Stars: 10k+ (2026-04)
  3. TensorRT-LLM

    • GitHub: https://github.com/NVIDIA/TensorRT-LLM
    • NVIDIA 官方推理加速库
  4. Text Generation Inference (TGI)

    • GitHub: https://github.com/huggingface/text-generation-inference
    • HuggingFace 官方推理服务

附录:完整代码示例

A1. 使用 vLLM 的 Continuous Batching

from vllm import LLM, SamplingParams
import time# 初始化 vLLM 引擎
llm = LLM(model="meta-llama/Llama-3-8B-Instruct",gpu_memory_utilization=0.90,max_num_batched_tokens=8192,enable_chunked_prefill=True,
)# 模拟并发请求
prompts = ["Explain quantum computing in simple terms.","Write a short story about a robot learning to love.","What are the benefits of continuous batching?",
] * 50  # 模拟 150 个并发请求sampling_params = SamplingParams(temperature=0.7,max_tokens=256,
)# 异步生成(Continuous Batching 自动生效)
start = time.time()
outputs = llm.generate(prompts, sampling_params)
end = time.time()print(f"总请求数: {len(prompts)}")
print(f"总耗时: {end - start:.2f}s")
print(f"吞吐量: {len(prompts) / (end - start):.2f} req/s")

A2. 自定义简易 Continuous Batching 调度器

from dataclasses import dataclass
from typing import List@dataclass
class Request:id: intprompt_length: intmax_tokens: intgenerated_tokens: int = 0def is_finished(self) -> bool:return self.generated_tokens >= self.max_tokensdef next_token(self):self.generated_tokens += 1class ContinuousBatchScheduler:"""简化的 Continuous Batching 调度器(教学示例,非生产代码)"""def __init__(self, max_batch_size: int = 32):self.max_batch_size = max_batch_sizeself.waiting: List[Request] = []self.running: List[Request] = []def add_request(self, req: Request):"""新请求到达"""self.waiting.append(req)def step(self):"""执行一个 iteration(生成 1 个 token)"""# 1. 释放已完成的请求self.running = [r for r in self.running if not r.is_finished()]# 2. 加入新请求(如果 batch 未满)while self.waiting and len(self.running) < self.max_batch_size:new_req = self.waiting.pop(0)self.running.append(new_req)# 3. 执行当前 batch 的 decodefor req in self.running:req.next_token()return len(self.running)def run_until_empty(self):"""运行直到所有请求完成"""total_steps = 0while self.waiting or self.running:n_running = self.step()total_steps += 1if total_steps % 100 == 0:print(f"Step {total_steps}: "f"waiting={len(self.waiting)}, "f"running={len(self.running)}")print(f"Total steps: {total_steps}")# 使用示例
scheduler = ContinuousBatchScheduler(max_batch_size=16)# 添加模拟请求
import random
for i in range(100):req = Request(id=i,prompt_length=random.randint(50, 500),max_tokens=random.randint(50, 200),)scheduler.add_request(req)scheduler.run_until_empty()

总结

Continuous Batching(连续批处理) 是 LLM 推理服务发展史上的里程碑式创新,它将 GPU 利用率从 ~40% 提升到 ~85%,吞吐量提升 2-4×。

核心技术演进路线:

Static Batching↓ (问题:队头阻塞)
Dynamic Batching  ↓ (改进:动态组 batch,但仍需等最长请求)
Orca: Iteration-Level Scheduling (2022)↓ (核心突破:每次迭代重新组 batch)
vLLM: PagedAttention + Continuous Batching (2023)↓ (内存管理创新:分页式 KV Cache)
Chunked Prefill (2023)↓ (解决:长 prefill 阻塞 decode 问题)
Sarathi-Serve (2023)↓ (混合调度:prefill chunk + decode 公平共享)
Prefill-Decode Disaggregation: DistServe / Mooncake (2024)↓ (架构创新:为 prefill 和 decode 分别优化硬件配置)
SGLang Zero-Overhead Scheduler (2024)↓ (工程优化:CPU 调度开销与 GPU 计算完全重叠)
vLLM Multi-Step Scheduling (2024)↓ (减少调度频率:一次决定 N 个 step 的 batch 组成)

核心启示

  1. 系统创新往往比算法创新更重要:Continuous Batching 没有提出新的 AI 算法,但通过系统层面的创新,实现了数量级的性能提升。

  2. 软硬件协同设计是关键:PagedAttention 借鉴了操作系统的虚拟内存思想;Chunked Prefill 考虑了 GPU 的计算特性。

  3. 没有银弹:每种优化都有 trade-off。生产环境中需要根据工作负载特性(请求长度分布、SLO 要求、成本预算)选择合适的策略组合。

http://www.jsqmd.com/news/734708/

相关文章:

  • 混合专家模型(MoE)全景解析——从路由原理到工程推理优化
  • HTML怎么离线使用_HTML缓存策略基础配置【教程】
  • 【HarmonyOS 6.1 全场景实战】开篇词:打造消除“吃饭焦虑”的《灵犀厨房》
  • RPFM v4.4.0:Total War MOD开发的突破性革命,如何让复杂数据编辑变得简单高效?
  • 从‘火星坐标’到‘地球坐标’:一次踩坑记录与Proj4j实战(Java版)
  • 从2D轮廓到3D全景:岩体结构面粗糙度的高精度视觉量化方案
  • Linux RT 调度器的 select_task_rq:RT 任务的CPU选择
  • 书匠策AI:论文界的“魔法编辑”,一键解锁降重降AIGC新姿势!
  • 通过 Taotoken CLI 一键配置开发环境并管理多个 API 密钥
  • TCP 碎片攻击深度剖析:漏洞成因、流量甄别与高防加固实操方案
  • 【VSCode 2026医疗合规校验终极指南】:覆盖HIPAA、GDPR、NIST SP 800-53全栈代码审计规则,开发者今明两天必须部署的5项自动拦截配置
  • Cog-DRIFT:自适应任务重构,突破 RLVR 的零信号困境
  • Python核心特性解析:从动态类型到元类编程
  • 为 OpenClaw 智能体配置 Taotoken 作为后端模型服务
  • API Key的精细化管理与审计,Taotoken控制台的安全功能体验
  • 强化学习在GeoAgent定位优化中的实践与突破
  • 企业培训采购策略:如何构建一个高效的AI培训供应商评估体系
  • MoE架构大语言模型安全漏洞分析与GateBreaker测试框架
  • PHP开发者必看的AI架构升级路线图(Laravel 12深度适配版):基于真实SaaS项目压测数据——推理延迟降低68%,内存占用下降41%
  • 终极iOS微信抢红包插件:毫秒级响应与后台运行完整指南
  • 三步搞定B站视频下载:告别在线限制,打造个人离线视频库
  • Onekey免费Steam游戏清单下载器:3分钟极速上手教程
  • 管理员端界面设计与分析
  • 计算机硬件常见问题及维护手册:从故障诊断到日常保养的完整指南
  • GPT-Image-2 Prompt 亲测模板,直接抄作业(喂饭版)
  • B站缓存视频无损转换完全指南:5秒完成m4s到MP4格式转换
  • BilibiliDown音频提取全攻略:从视频到高品质音频的一站式解决方案
  • 如何快速掌握硬件信息修改:技术爱好者的终极教程
  • 【自适应天线与相控阵技术】用于评估自适应相控阵的聚焦近场技术
  • CXL设备复位、初始化与管理:从PCIe老司机到CXL新手的避坑指南