06 推理优化与 vLLM
学习理念:训练完的模型要部署到线上,推理速度和吞吐是关键。vLLM 的核心创新是 Continuous Batching(连续批处理)和 Block-based KV Cache(分块 KV 缓存),前者让 GPU 在等待生成时也能处理新请求,后者把 KV Cache 的碎片利用率从 ~20% 提到 ~90%。
海外对标:vLLM(UC Berkeley)、TensorRT-LLM(NVIDIA)、SGLang
本节 AI 替代率:~75% | 人工干预率:~25%
| 角色 | 能力范围 |
|---|---|
| 🤖 AI 擅长 | 解释 vLLM 架构、对比 Static vs Continuous Batching |
| 👤 人类需理解 | Prefill/Decode 分离的动机、Block-based KV Cache 为什么能减少碎片 |
📌 来源说明:以下内容提取自原始笔记第13章(vLLM + Continuous Batching + Block-based KV Cache),代码来自
09_vllm_demo.py。
📖 阅读优先级
| 等级 | 章节 | 说明 |
|---|---|---|
| 🔴 必须深入 | 二、Continuous Batching | 理解 Static vs Dynamic Batching 差异——决定你的 Agent 服务吞吐量 |
| 🟡 理解即可 | 三、Block-based KV Cache | 知道分块能减少显存碎片即可 |
| 🟢 直接跳过 | 四、vLLM 调用 | 使用时查 OpenAI 兼容 API 文档 |
一、为什么需要推理服务?
模型训练完后,直接用 model.generate() 跑推理的问题是:
| 问题 | 分析 |
|---|---|
| 显存利用率低 | 不同请求序列长度不同,Static Batching 必须按最长序列 padding |
| KV Cache 碎片化 | 每个请求独占连续显存,但请求长度不同,产生大量空洞 |
| GPU 利用率低 | 生成阶段(Decode)计算量小,GPU 利用率不到 20% |
vLLM 通过两个核心设计解决这些问题:Continuous Batching 和 Block-based KV Cache。
二、Continuous Batching(连续批处理)
2.1 Static Batching vs Continuous Batching
Static Batching(传统): Continuous Batching(vLLM):
请求A ──────┐ 请求A ──────┐
请求B ──────┤ 请求B ────┐ │
请求C ──────┤ 请求C ──┐ │ │
↓ 批处理 ↓ ↓ ↓ 动态加入/退出
A B C 同时完成 各请求独立完成核心差异:
| 维度 | Static Batching | Continuous Batching |
|---|---|---|
| 批处理方式 | 固定 batch,所有请求一起开始一起结束 | 动态——任何时刻可以加入/退出 |
| 等待延迟 | 所有请求等最慢的完成 | 每个请求独立完成 |
| GPU 利用率 | 低(Decode 阶段计算稀疏) | 高(不断有新请求的 Prefill 填充) |
| 实现复杂度 | 低 | 高 |

2.2 请求生命周期
请求到达 → Scheduler 入队 → 等待资源 → 执行 Decode → 完成
↓
每个 step:
1. 当前 running 的请求做一次 Decode
2. 如果有新请求,做一次 Prefill
3. 完成的请求离开,释放 KV Cache block三、Block-based KV Cache
3.1 问题:传统 KV Cache
传统实现为每个请求分配连续显存块:
请求A (128 tokens): [████████████████░░░░░░░░░░░░] ← 浪费 50%
请求B (256 tokens): [████████████████████████████] ← 用完
请求C (64 tokens): [████████░░░░░░░░░░░░░░░░░░░░] ← 浪费 75%问题:每个请求必须按最大可能长度预留显存,但实际长度可能远小于预留。
3.2 解决方案:分块(Block-based)
将 KV Cache 切分成固定大小的 Block(如 16×128 float),按需分配:
Block 表:
┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┐
│ B0 │ B1 │ B2 │ B3 │ B4 │ B5 │ B6 │ B7 │
├──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┤
│A:0-15│A:16-31│A:32-47│B:0-15│B:16-31│C:0-15│ free │ free │
└──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┘
↑ ↑
请求A: 3 blocks 请求B: 2 blocks优势:
- ✅ 按需分配,不预占
- ✅ 无碎片——Block 大小固定,可以复用
- ✅ 支持内存交换——Block 可自动换出到 CPU
四、vLLM 调用
4.1 启动服务
bash
# 启动 vLLM 推理服务
python -m vllm.entrypoints.openai.api_server \
--model Qwen3-0.6B \
--port 80004.2 OpenAI 兼容调用
python
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1/",
api_key="none",
)
response = client.chat.completions.create(
model="Qwen3-0.6B",
messages=[{"role": "user", "content": "什么是LangChain?"}],
)
print(response.choices[0].message.content)4.3 LangChain 调用
python
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="Qwen3-0.6B",
base_url="http://localhost:8000/v1/",
api_key="none",
temperature=0,
)
response = llm.invoke("LangChain如何调用OpenAI风格的大模型?")
print(response.content)
五、技术栈健康度
| 技术 | 健康度 | 说明 |
|---|---|---|
| vLLM | 🔥 巅峰 | LLM 推理部署事实标准 |
| Continuous Batching | 🔥 巅峰 | 推理框架标准设计 |
| Block-based KV Cache | 🔥 巅峰 | 显存管理标准方案 |
| Static Batching | ⚠️ 衰退 | 已被 Continuous Batching 取代 |
六、本阶段文件索引
| 优先级 | 文件 | 路径 |
|---|---|---|
| 🟡 P1 | 09_vllm_demo.py | 3.代码/fine_tune_proj/09_vllm_demo.py |