vLLM 推理引擎
五层读懂一个词。这次拆的是:vLLM--LLM 推理服务的事实标准。PagedAttention + Continuous Batching + Prefix Caching + Chunked Prefill + Multi-LoRA 五大支柱,把显存利用率从 30% 提升到 95%,吞吐量提升 10-30x。从 2023 SOSP 论文到 GitHub 40k+ star,vLLM 重新定义了「LLM 怎么跑」。
L1 · 一句话点破
vLLM = PagedAttention 内存管理 + Continuous Batching 调度 + 多项工程优化的 LLM 推理引擎。核心洞察:OS 的虚拟内存/分页机制可以解决 KV-Cache 的内存碎片化 —— 这就是 PagedAttention。于是一条线穿起五大优化支柱,让 GPU 显存利用率从 30%(HuggingFace)飙到 95%,并发吞吐量提升 10-30x。开源 40k+ star,当前最主流的 LLM 推理服务方案。
L2 · 通俗类比
HF Transformers 跑 LLM 推理像没人管的停车场:
- 车一来就找空地停(KV-Cache 连续分配)
- 大车小车混着停,留下碎片
- 碎片越来越多,新车来了找不到位
- 其实停车场还有空间,但都是碎片,拼不出一块完整的
- 显存利用率 ~30%
vLLM 像「有停车管理系统的停车场」(PagedAttention):
- 把停车场分成标准车位(block)
- 大车占多个车位(KV-Cache 按 block 分配)
- 不要求连续车位,随便停
- 车走了立即释放车位(请求完成 block 回收)
- 利用率 ~95%
再加上自动调度(Continuous Batching):
- 不等整批车走再接新批
- 哪辆车走了,立刻让新车进来
- 停车场始终满载
再加上复用(Prefix Caching):
- 多个请求的 system prompt 相同
- 不用每个请求都重新算 KV-Cache
- 直接复用
vLLM 的五大支柱:
| 支柱 | 解决的问题 | 效果 |
|---|---|---|
| PagedAttention | KV-Cache 碎片化 | 显存利用 30%→95% |
| Continuous Batching | 整批等最长请求 | 吞吐 2-10x |
| Prefix Caching | 共享前缀重复计算 | 首 token 延迟 5-10x |
| Chunked Prefill | Prefill/Decode 互相拖累 | 吞吐 +20-50% |
| Multi-LoRA Serving | 多 LoRA 适配器加载慢 | 毫秒级热切换 |
部署 vLLM 的体验:
# 一条命令启动 OpenAI 兼容 API
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3-70B \
--tensor-parallel-size 2
# 原项目 API 无缝切换
# 从 openai.ChatCompletion.create 变成 vllm 后端
# 吞吐量 10x+代价:
- 需要 GPU(CUDA),不支持 CPU-only
- 对权重格式有要求(支持 GPTQ/AWQ/FP8/FP16/BF16)
- 调度器实现复杂,参数调优需要理解原理
- 某些小众模型支持不如 HF Transformers
适用:
- LLM 在线推理服务(默认首选)
- 高并发 API 场景
- 多 LoRA 适配器热切换
- 批处理推理
L3 · 正经定义
vLLM:由 UC Berkeley 团队(Kwon et al.)开发的开源 LLM 推理引擎。核心贡献是 PagedAttention——将 OS 分页机制引入 LLM 的 KV-Cache 管理,配合 Continuous Batching(iteration 级调度)、Prefix Caching(共享前缀复用)、Chunked Prefill(prefill/decode 分离)等优化,实现高吞吐、低延迟的 LLM 推理服务。
技术栈:
- 后端:Python + C++/CUDA
- 兼容:OpenAI API、HuggingFace 模型
- 支持:张量并行(TP)、流水线并行(PP)、FP8/BF16/FP16、GPTQ/AWQ/INT8 量化
架构层级:
API Server (OpenAI Compatible)
│
Scheduler (Continuous Batching)
│
Block Manager (PagedAttention)
│
GPU Workers (Model Execution)参考资料:
- 📄 Kwon et al., Efficient Memory Management for Large Language Model Serving with PagedAttention, SOSP 2023
- 📄 vLLM 官方文档:https://docs.vllm.ai/
- 🔧 GitHub:https://github.com/vllm-project/vllm
- 📝 vLLM Blog:https://blog.vllm.ai/
L4 · 原理深挖
4.1 vLLM 的五大支柱
(PagedAttention 和 Continuous Batching 的详细原理见各自专题,这里聚焦 vLLM 将这些技术整合的设计。)
支柱 1: PagedAttention
传统: KV-Cache 连续分配
请求1: [████████░░░░░░░░] 预分配 256 token,只用了 30
请求2: [████████████░░░░] 预分配 256,只用了 50
碎片化严重
vLLM: PagedAttention
请求1: block 0, block 3, block 7 (按需分配)
请求2: block 1, block 2, block 5, block 9
离散分配,无碎片块表(Block Table):
- 逻辑块 → 物理块的映射
- 类似 OS 的页表
- 支持 Copy-on-Write(请求间共享系统 prompt 的 KV-Cache)
支柱 2: Continuous Batching
每 iteration 级别调度,不等整批完成:
Iteration t:
Batch = [req_a, req_b, req_c, req_d]
req_c 生成 EOS → 移除 req_c
新请求 req_e 加入 → Batch = [req_a, req_b, req_d, req_e]
Iteration t+1:
...支柱 3: Prefix Caching
问题:多请求共享相同 system prompt(如"你是一个帮助用户的助手..."),每个请求独立计算 KV-Cache 浪费。
解决:将 system prompt 的 KV-Cache 作为共享 block,新请求直接引用。
# Block 0-5: 共享 system prompt
# 新请求直接引用块 0-5,只需计算用户输入部分的 KV-CacheCopy-on-Write:当共享块被修改时,复制一份不影响的副本。
效果:system prompt 长的场景,首 token 延迟降 5-10x。
支柱 4: Chunked Prefill
问题:prefill(处理 prompt)和 decode(生成 token)特性不同:
- Prefill:计算密集,并行处理所有 prompt token
- Decode:内存密集,一次处理 1 token
- 混合 batch 时互相拖累
解决:将 prefill 分成多个 chunk,交错执行:
Iteration 1: [prefill_chunk_1(req_a), decode(req_b), decode(req_c)]
Iteration 2: [prefill_chunk_2(req_a), decode(req_b), decode(req_c), decode(req_d)]
Iteration 3: [decode(req_a), decode(req_b), decode(req_c), decode(req_d)]- Prefill 不阻塞 decode
- 新请求不会长时间等待
支柱 5: Multi-LoRA Serving
问题:每个 LoRA 适配器有独立权重,加载/卸载开销大。
解决:Punica(vLLM 的 Multi-LoRA 方案):
- 将 LoRA 权重拆分到不同的 GPU worker
- 每个 worker 只加载需要的 LoRA 适配器
- 请求路由到对应 worker
- 支持毫秒级热切换
from vllm import LLM
llm = LLM(model="meta-llama/Llama-2-7B", enable_lora=True)
# 注册多个 LoRA
llm.register_lora("qa_adapter", qa_lora_path)
llm.register_lora("code_adapter", code_lora_path)
llm.register_lora("chat_adapter", chat_lora_path)
# 请求自动路由到对应 LoRA
outputs = llm.generate(
prompts,
sampling_params,
lora_request=LoRARequest("code_adapter", 1, "general")
)4.2 vLLM 的调度器架构
调度器决策(每 iteration):
1. 哪些请求完成?→ 移除
2. 哪些新请求到达?→ 加入等待队列
3. 等待队列中哪些可以加入 batch?
- 检查显存预算
- 检查 batch_size 上限
- 检查 token 数上限
4. 是 prefill 还是 decode?
- 新加入:prefill(可能 chunked)
- 已在 batch:decode
5. 是否需要 swap?
- 显存不足时 swap out 部分请求显存预算管理:
总显存 = 模型权重 + KV-Cache + 其他
KV-Cache 显存 = f(requests, seq_length, block_size)
Scheduler 持续跟踪:
- 已分配 blocks
- 可用 blocks
- 每个请求的 blocks 数
新请求加入条件:
available_blocks >= estimated_blocks_for_new_request4.3 vLLM 的并行策略
张量并行(Tensor Parallelism, TP):
- 权重矩阵按列/行切分到多 GPU
- 通信方式:All-Reduce / All-Gather
- 适合注意力层和大 FFN 层
流水线并行(Pipeline Parallelism, PP):
- 模型层按顺序分配到多 GPU
- 微批次流水线
- 适合超长模型
vLLM 的选择:
- 默认推荐 TP(通信量小,实现简单)
- TP + PP 组合适合超大模型(>175B)
- 自动选择最佳配置
# 2 卡张量并行
python -m vllm.entrypoints.openai.api_server \
--model mistralai/Mixtral-8x7B \
--tensor-parallel-size 2 \
--gpu-memory-utilization 0.94.4 vLLM 的量化支持
| 量化方法 | 支持情况 | 推理速度 |
|---|---|---|
| FP16/BF16 | ✅ 原生 | 基线 |
| GPTQ 4bit | ✅ | 1.5-2x |
| AWQ 4bit | ✅ | 1.5-2x |
| INT8 | ✅ | 1.2-1.5x |
| FP8 | ✅ | 1.3-1.8x |
| SqueezeLLM | ✅ | - |
| GGUF | ❌ | - |
4.5 vLLM vs 其他引擎
| 引擎 | 核心优势 | 核心劣势 | 适用 |
|---|---|---|---|
| vLLM | PagedAttention, 开源最活跃 | 只支持 GPU | 通用首选 |
| TensorRT-LLM | NVIDIA 极致优化 | 复杂,闭源部分 | NVIDIA 硬件 |
| SGLang | RadixAttention, 结构化生成 | 新,生态小 | 结构化生成 |
| TGI | HuggingFace 官方 | 吞吐略低于 vLLM | HF 生态用户 |
| llama.cpp | CPU/Apple Silicon | GPU 吞吐不如 vLLM | 本地推理 |
| Ollama | 易用性最高 | 不是生产级 | 个人/开发 |
4.6 vLLM 的性能数据
Llama-2-70B, 8xA100-80G, 1000 并发请求:
| 方案 | 吞吐 (tok/s) | P99 延迟 (ms) | 显存利用 |
|---|---|---|---|
| HF Transformers | 120 | 8000 | 30% |
| TGI | 1800 | 1200 | 75% |
| TensorRT-LLM | 3200 | 600 | 90% |
| vLLM | 2800 | 700 | 95% |
结论:vLLM 在吞吐和显存利用上接近 TensorRT-LLM,但开源更活跃。
4.7 vLLM 的局限
局限 1: 只支持 CUDA GPU。不支持 CPU、Apple Silicon、AMD(ROCM 有限支持)。
局限 2: 对模型权重要求严格。需要 HuggingFace 格式权重,自定义格式需要转换。
局限 3: 调度策略固定。FCFS 默认,不支持优先级、公平调度等高级策略(新版本在改善)。
局限 4: 不适合小 batch。batch=1 时优势不明显,甚至比 HF 慢(管理开销)。
局限 5: 显存预算估计不准。某些模型/场景估计偏差,需要手动调 gpu-memory-utilization。
局限 6: 不支持训练。vLLM 是推理引擎,不支持 fine-tuning/LoRA 训练(加载已有 LoRA 可以)。
局限 7: 版本兼容。CUDA 版本、PyTorch 版本、transformers 版本组合复杂,安装可能遇坑。
局限 8: 部分模型支持不成熟。小众模型、多模态模型的首选不是 vLLM。
L5 · 沿革与坑
5.1 沿革
- 2023-06:vLLM 开源(UC Berkeley),PagedAttention + Continuous Batching
- 2023-10:SOSP 2023 接收论文,社区引爆
- 2023-11:Support for GPTQ/AWQ, Chunked Prefill, Prefix Caching
- 2024-03:Multi-LoRA Serving (Punica 集成)
- 2024-06:FP8 支持、Speculative Decoding、Pipeline Parallelism
- 2024 下:vLLM 成为生产环境首选推理引擎,40k+ star
- 2024-2025:Spec Decode、Multi-node、Structured Output、vLLM V1 架构重构
5.2 常见坑
坑 1: expect vLLM 比 HF 快 10x 单请求。batch=1 时差不多甚至更慢。它是高并发场景的 10x。
坑 2: gpu-memory-utilization 设太高。设 0.95 可能 OOM。建议 0.85-0.90。
坑 3: max-model-len 没设。默认取模型最大值(如 32k),显存浪费。按实际需要设(如 4096)。
坑 4: 忘记 enable-prefix-caching。有 system prompt 的场景不开启,白白浪费。
坑 5: Tensor Parallel 和 Pipeline Parallel 混用。一般只用 TP,PP 引入通信开销且收益有限。
坑 6: batch_size 相关的参数乱调。max-num-seqs、max-num-batched-tokens 等如果不理解就调默认。
坑 7: 量化模型加载时未指定 quantization 参数。vLLM 需要 --quantization awq/gptq 明确指定。
坑 8: LoRA 适配器路径错误。Multi-LoRA 需要正确的 adapter 路径,且基础模型要匹配。
坑 9: 期望 Prefix Caching 在所有场景都有效。只有 system prompt 共享的场景有效。无共享场景无收益。
坑 10: 生产环境直接用 vLLM 原始 API。建议前面加 nginx/gateway 做限流、鉴权。
坑 11: 忽略了 swap space。--swap-space 默认 4GB,高并发时不够。按需调。
坑 12: GPU 种类混用。不同型号 GPU(A100+H100)混用可能 TP 对齐出问题。
5.3 面试怎么考
- vLLM 的核心创新? 答:PagedAttention,把 OS 分页机制引入 KV-Cache 管理,解决碎片化。+ Continuous Batching(iteration 级调度)+ Prefix Caching + Chunked Prefill。
- vLLM 为什么比 HF 快? 答:HF 显存利用率 ~30%(KV-Cache 碎片),vLLM ~95%(PagedAttention)。HF 是 static batching(等整批),vLLM 是 continuous batching(随完成随调度)。
- PagedAttention 怎么做内存共享? 答:块表 + Copy-on-Write。System prompt 的 KV-Cache 作为共享块,多请求引用同块。需要修改时 copy 一份。
- vLLM vs TGI vs TensorRT-LLM? 答:vLLM 开源最活跃、生态好;TGI 是 HuggingFace 官方、HF 生态兼容最好;TensorRT-LLM NVIDIA 极致优化但复杂。vLLM 是通用首选。
- Multi-LoRA Serving 怎么实现? 答:Punica 方案,LoRA 权重分发到不同 worker,请求路由到对应 worker,毫秒级切换。
速记卡
五大支柱:
| 支柱 | 解决的问题 | 效果 |
|---|---|---|
| PagedAttention | KV-Cache 碎片化 | 显存 30%→95% |
| Continuous Batching | 木桶效应 | 吞吐 2-10x |
| Prefix Caching | 前缀重复计算 | 首 token 5-10x |
| Chunked Prefill | Prefill/Decode 互拖 | 吞吐 +20-50% |
| Multi-LoRA | 适配器切换慢 | 毫秒级热切换 |
架构:
API Server → Scheduler → Block Manager → GPU Workers性能(Llama-2-70B, 1000 并发):
| 方案 | 吞吐 | P99 延迟 | 显存 |
|---|---|---|---|
| HF | 120 tok/s | 8000ms | 30% |
| vLLM | 2800 tok/s | 700ms | 95% |
启动命令:
python -m vllm.entrypoints.openai.api_server \
--model <model> \
--tensor-parallel-size 2 \
--gpu-memory-utilization 0.9 \
--max-model-len 4096 \
--enable-prefix-caching推荐参数:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| gpu-memory-utilization | 0.85-0.90 | 太高 OOM |
| max-model-len | 实际需要值 | 不是模型最大 |
| tensor-parallel-size | GPU 数 | 默认只用 TP |
| enable-prefix-caching | True | system prompt 场景 |
一句话记忆:vLLM = PagedAttention(分页 KV-Cache)+ Continuous Batching(动态调度)+ Prefix Caching(前缀复用)+ Chunked Prefill(prefill/decode 分离)+ Multi-LoRA(热切换)五大支柱。显存利用率 30%→95%,吞吐 10-30x,OpenAI API 兼容,40k+ star。LLM 在线推理服务的默认首选。局限:batch=1 优势不明显、只支持 CUDA GPU、部分模型支持不如 HF。
上一篇:Long-context RAG -- RAG+长上下文的最佳实践。下一篇:SGLang 结构生成语言 -- vLLM 之外的新锐推理引擎,RadixAttention + 结构化生成。