视频加载失败

1.2 vLLM 快速入门

3412 字
17 分钟
1.2 vLLM 快速入门

1. 什么是 vLLM#

当你要把一个大语言模型”搬上线”提供服务时,最头疼的问题是什么?——显存不够用,吞吐上不去。传统的推理方式就像一个餐厅里每桌客人都被分配了一间独立包房,不管来了几个人,房间全部占满,后面的客人只能干等。vLLM 的出现就是为了解决这个”包房浪费”问题。

vLLM 是由 UC Berkeley Sky Computing Lab 开发的高吞吐、低延迟 LLM 推理与服务引擎。截至 v0.19.0(2026 年 4 月),项目在 GitHub 上已获得超过 76,000 星标,拥有 2,000+ 贡献者,是当前最主流的开源 LLM 推理框架之一。

1.1 vLLM 的核心优势#

🏷️ 特性📝 说明
PagedAttention借鉴操作系统虚拟内存分页思想管理 KV Cache,显存利用率接近最优
Continuous Batching动态地将新请求插入正在处理的批次,而非等一批全部完成再开始下一批
OpenAI 兼容 API直接替换 OpenAI 客户端的 base_url,无需修改业务代码
200+ 模型支持覆盖 Llama、Qwen、Mistral、DeepSeek 等主流架构,含 MoE 和多模态模型
多硬件支持NVIDIA GPU、AMD GPU、Google TPU、Intel Gaudi、CPU 等
丰富的量化方案FP8、INT8、INT4、GPTQ、AWQ、GGUF 等开箱即用

1.2 vLLM 在推理生态中的定位#

用户请求

vLLM 推理引擎

PagedAttention

KV Cache 管理

Continuous Batching

动态批处理

模型执行

CUDA Kernels

高显存利用率

高吞吐量

低延迟

用户请求

vLLM 推理引擎

PagedAttention

KV Cache 管理

Continuous Batching

动态批处理

模型执行

CUDA Kernels

高显存利用率

高吞吐量

低延迟

2. 核心原理:PagedAttention#

在深入使用之前,先理解 vLLM 为什么快——这能帮你在后续调参时做出更好的决策。

2.1 传统 KV Cache 的问题#

LLM 推理的 Decode 阶段需要缓存之前所有 token 的 Key 和 Value 向量(即 KV Cache),以避免重复计算。传统做法是为每个请求预分配一块连续的显存空间,大小按模型支持的最大序列长度计算。

这就带来了三个问题:

  • 内部碎片:大多数请求用不到最大长度,预留空间大量浪费
  • 外部碎片:请求结束后释放的空间大小不一,难以被新请求复用
  • 无法共享:Beam Search 等场景中,多个候选序列共享前缀部分的 KV Cache,但连续内存布局无法实现共享

💡 提示:对于一个 13B 参数的模型,单个请求的 KV Cache 在最大序列长度下可能占用数 GB 显存。如果同时处理几十个请求,显存瓶颈会比模型权重本身更严重。

2.2 PagedAttention 的解决方案#

PagedAttention 的核心思想非常直观——把操作系统管理内存的方式搬到 KV Cache 管理上来:

🖥️ 操作系统概念🤖 PagedAttention 对应
虚拟内存页(Page)KV Block(固定大小的 KV Cache 块)
页表(Page Table)Block Table(逻辑块到物理块的映射)
按需分页Token 生成时才分配新的 KV Block
写时复制(Copy-on-Write)Beam Search 场景共享前缀 KV Block

具体工作方式:

  1. 分块存储:KV Cache 不再要求连续内存,而是被切分成固定大小的 Block(如 16 个 token 为一个 Block)
  2. 按需分配:每生成一个 token,只在当前 Block 未满时追加,填满后才分配新的 Block
  3. 映射表管理:每个请求维护一个 Block Table,记录自己的逻辑 Block 到物理 Block 的映射关系
  4. 内存共享:多个请求如果有相同的前缀(如 System Prompt),可以共享同一组物理 Block,大幅节省显存

⚠️ 注意:PagedAttention 的分块存储意味着 KV Cache 在物理上是不连续的,vLLM 需要专门的 CUDA Kernel 来高效地从分散的 Block 中读取数据进行 Attention 计算。

3. 安装与环境准备#

3.1 系统要求#

📊 项目📝 要求
操作系统Linux(推荐 Ubuntu 20.04+)
Python3.10 ~ 3.13
CUDA12.x(NVIDIA GPU)
GPUCompute Capability 7.0+(Volta 及以上)

3.2 使用 uv 安装(推荐)#

uv 是 Rust 编写的高速 Python 包管理器,vLLM 官方推荐使用它来安装,能自动检测 CUDA 版本并选择匹配的 PyTorch:

Terminal window
# 创建虚拟环境
uv venv --python 3.12 --seed
source .venv/bin/activate
# 安装 vLLM(自动检测 CUDA 版本)
uv pip install vllm --torch-backend=auto

--torch-backend=auto 会根据系统 CUDA 驱动自动选择合适的 PyTorch 版本。也可以显式指定后端,如 --torch-backend=cu126。

3.3 使用 conda + pip 安装#

Terminal window
conda create -n vllm-env python=3.12 -y
conda activate vllm-env
pip install --upgrade uv
uv pip install vllm --torch-backend=auto

3.4 AMD ROCm 环境#

Terminal window
uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm --extra-index-url https://wheels.vllm.ai/rocm/

目前 ROCm 支持 Python 3.12、ROCm 7.0,要求 glibc >= 2.35。

3.5 验证安装#

Terminal window
python -c "import vllm; print(vllm.__version__)"

4. 离线批量推理#

离线推理适合不需要实时响应的场景,如批量文本生成、数据标注、评测跑分等。vLLM 提供 LLM 类作为离线推理的主入口。

4.1 基础用法#

from vllm import LLM, SamplingParams
# 定义采样参数
sampling_params = SamplingParams(
temperature=0.8,
top_p=0.95,
max_tokens=256,
)
# 加载模型(自动下载 HuggingFace 模型)
llm = LLM(model="Qwen/Qwen2.5-7B-Instruct")
# 批量生成
prompts = [
"请用一句话解释什么是 Transformer:",
"Python 和 C++ 的主要区别是什么?",
"推荐三本深度学习入门书籍:",
]
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
prompt = output.prompt
generated = output.outputs[0].text
print(f"Prompt: {prompt}")
print(f"Generated: {generated}\n")

📌 关键点:LLM 构造时会一次性将模型加载到 GPU 显存中。默认情况下 vLLM 会使用 90% 的可用 GPU 显存(模型权重 + KV Cache),可通过 gpu_memory_utilization 参数调整。

4.2 Chat 模式推理#

对于 Instruct/Chat 模型,需要正确应用 Chat Template。vLLM 提供了两种方式:

方式一:使用 llm.chat(推荐)

from vllm import LLM, SamplingParams
llm = LLM(model="Qwen/Qwen2.5-7B-Instruct")
sampling_params = SamplingParams(temperature=0.7, max_tokens=512)
messages_list = [
[
{"role": "system", "content": "你是一个 AI Infra 专家。"},
{"role": "user", "content": "解释什么是张量并行?"},
],
[
{"role": "user", "content": "vLLM 和 TensorRT-LLM 有什么区别?"},
],
]
outputs = llm.chat(messages_list, sampling_params)
for output in outputs:
print(output.outputs[0].text)

方式二:手动应用模板

from transformers import AutoTokenizer
from vllm import LLM, SamplingParams
model_name = "Qwen/Qwen2.5-7B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_name)
llm = LLM(model=model_name)
messages_list = [
[{"role": "user", "content": "什么是 KV Cache?"}],
]
# 手动应用 chat template
texts = tokenizer.apply_chat_template(
messages_list,
tokenize=False,
add_generation_prompt=True,
)
outputs = llm.generate(texts, SamplingParams(temperature=0.7))

⚠️ 注意:llm.generate 不会自动应用 Chat Template。如果直接传入裸文本给 Chat 模型,输出质量可能很差甚至乱码。务必使用 llm.chat 或手动调用 apply_chat_template。

4.3 HuggingFace generation_config 的影响#

vLLM 默认会读取模型仓库中的 generation_config.json(如果存在),并用其中的参数覆盖 vLLM 的默认值。如果你想使用 vLLM 自身的默认采样配置,需要显式设置:

llm = LLM(model="Qwen/Qwen2.5-7B-Instruct", generation_config="vllm")

5. 在线服务部署#

在线服务是 vLLM 最常用的部署方式——启动一个 HTTP 服务器,暴露 OpenAI 兼容的 API,业务端只需修改 base_url 即可无缝切换。

5.1 启动服务器#

Terminal window
vllm serve Qwen/Qwen2.5-7B-Instruct

默认监听 http://localhost:8000,可通过 --host 和 --port 自定义:

Terminal window
vllm serve Qwen/Qwen2.5-7B-Instruct \
--host 0.0.0.0 \
--port 8080 \
--tensor-parallel-size 2

💡 提示:同样可以通过 --generation-config vllm 来禁用 HuggingFace 默认的 generation_config。

5.2 Chat Completions API#

这是最常用的接口,对标 OpenAI 的 v1/chat/completions:

使用 curl:

Terminal window
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-7B-Instruct",
"messages": [
{"role": "system", "content": "你是一个有帮助的助手。"},
{"role": "user", "content": "什么是 PagedAttention?"}
],
"temperature": 0.7,
"max_tokens": 512
}'

使用 Python openai 客户端:

from openai import OpenAI
# 只需修改 base_url,其他代码完全不变
client = OpenAI(
api_key="EMPTY", # vLLM 默认不需要认证
base_url="http://localhost:8000/v1",
)
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[
{"role": "system", "content": "你是一个 AI 基础设施专家。"},
{"role": "user", "content": "解释 Continuous Batching 的工作原理。"},
],
temperature=0.7,
max_tokens=512,
)
print(response.choices[0].message.content)

5.3 Completions API#

对标 OpenAI 的 v1/completions,适用于文本补全场景:

from openai import OpenAI
client = OpenAI(api_key="EMPTY", base_url="http://localhost:8000/v1")
completion = client.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
prompt="LLM 推理优化的三个核心方向是",
max_tokens=256,
temperature=0.8,
)
print(completion.choices[0].text)

5.4 API 认证#

生产环境中建议开启 API Key 认证:

Terminal window
vllm serve Qwen/Qwen2.5-7B-Instruct --api-key my-secret-key

也可以通过环境变量设置:

Terminal window
export VLLM_API_KEY=my-secret-key
vllm serve Qwen/Qwen2.5-7B-Instruct

客户端调用时传入对应的 api_key:

client = OpenAI(api_key="my-secret-key", base_url="http://localhost:8000/v1")

5.5 支持的 API 端点#

📡 端点📝 说明
GET /v1/models列出可用模型
POST /v1/completions文本补全
POST /v1/chat/completions对话补全
GET /health健康检查

6. 关键参数调优#

6.1 采样参数(SamplingParams)#

📊 参数📝 说明默认值
temperature控制随机性,越高越随机1.0
top_p核采样,只从累计概率前 p 的 token 中采样1.0
top_k只从概率最高的 k 个 token 中采样-1(不限制)
max_tokens最大生成 token 数16
repetition_penalty重复惩罚系数,>1 减少重复1.0
stop遇到指定字符串时停止生成None
n为每个 prompt 生成的序列数1
seed随机种子,设置后可复现结果None

💡 提示:对于大多数生产场景,推荐 temperature=0.7, top_p=0.9 作为起点。追求确定性输出时设 temperature=0。

6.2 引擎关键参数#

⚙️ 参数📝 说明推荐值
--modelHuggingFace 模型标识-
--tensor-parallel-size张量并行 GPU 数根据模型大小决定
--gpu-memory-utilizationGPU 显存使用比例0.9(默认)
--max-model-len模型最大序列长度按需设置
--dtype模型权重精度auto
--quantization量化方式None
--max-num-seqs最大并发序列数256
--enforce-eager禁用 CUDA Graph调试时使用

6.3 显存估算与 gpu-memory-utilization#

vLLM 启动时会按照以下方式分配显存:

总 GPU 显存 × gpu_memory_utilization = 模型权重 + KV Cache + 临时缓冲区

KV Cache 可用空间 = 总配额 - 模型权重 - 固定开销。KV Cache 越大,能同时处理的请求越多,吞吐就越高。

Terminal window
# 如果显存紧张,适当降低利用率
vllm serve Qwen/Qwen2.5-7B-Instruct --gpu-memory-utilization 0.85
# 如果需要限制最大序列长度来节省 KV Cache 空间
vllm serve Qwen/Qwen2.5-7B-Instruct --max-model-len 4096

⚠️ 注意:如果模型加载后启动报错 OOM,通常需要降低 --gpu-memory-utilization 或 --max-model-len,或者增加 --tensor-parallel-size 分摊到多卡。

6.4 Attention Backend 选择#

vLLM 会自动选择当前平台上性能最优的 Attention 后端,也可以手动指定:

Terminal window
# 使用 FlashAttention
vllm serve Qwen/Qwen2.5-7B-Instruct --attention-backend FLASH_ATTN
# 使用 FlashInfer
vllm serve Qwen/Qwen2.5-7B-Instruct --attention-backend FLASHINFER
🖥️ 平台📝 可用后端
NVIDIA CUDAFLASH_ATTN、FLASHINFER
AMD ROCmTRITON_ATTN、ROCM_ATTN 等

7. 多 GPU 推理与张量并行#

当单卡显存装不下模型时,需要使用张量并行(Tensor Parallelism)将模型切分到多张 GPU 上。

7.1 基础用法#

Terminal window
# 2 卡张量并行
vllm serve Qwen/Qwen2.5-72B-Instruct --tensor-parallel-size 2
# 4 卡张量并行(适合 70B+ 模型)
vllm serve Qwen/Qwen2.5-72B-Instruct --tensor-parallel-size 4

在离线推理中同样支持:

from vllm import LLM, SamplingParams
llm = LLM(
model="Qwen/Qwen2.5-72B-Instruct",
tensor_parallel_size=4,
)
outputs = llm.generate(["解释 vLLM 的架构"], SamplingParams(max_tokens=256))

7.2 模型大小与 GPU 数量参考#

以下是常见模型大小在 FP16 精度下的显存需求估算:

🤖 模型规模💾 权重大小 (FP16)📝 推荐最小 GPU 配置
7B~14 GB1× A100 80G / 1× L40S 48G
13B~26 GB1× A100 80G
34B~68 GB1× A100 80G(需降低 max_model_len)或 2× A100
70B~140 GB2× A100 80G
405B~810 GB16× A100 80G 或 8× H100 80G

💡 提示:实际所需显存 = 模型权重 + KV Cache + 运行时开销。使用量化(如 AWQ INT4)可以将权重大小缩减约 4 倍,从而用更少的 GPU 服务更大的模型。

7.3 vLLM 支持的并行方式#

vLLM 支持五种并行策略:

  • 张量并行(Tensor Parallelism):将模型的各层权重矩阵按列/行切分到多张 GPU
  • 流水线并行(Pipeline Parallelism):将模型的不同层分配到不同 GPU
  • 数据并行(Data Parallelism):多个副本独立处理不同请求
  • 专家并行(Expert Parallelism):MoE 模型中将不同专家分配到不同 GPU
  • 上下文并行(Context Parallelism):将长序列的上下文分散到多张 GPU

对于大部分场景,张量并行是首选,配置最简单且效果最好。

8. 常见问题与排错#

8.1 启动时 OOM#

torch.cuda.OutOfMemoryError: CUDA out of memory.

✅ 解决方案:

Terminal window
# 方法一:降低显存利用率
vllm serve model_name --gpu-memory-utilization 0.8
# 方法二:缩短最大序列长度
vllm serve model_name --max-model-len 2048
# 方法三:增加张量并行
vllm serve model_name --tensor-parallel-size 2
# 方法四:使用量化模型
vllm serve model_name --quantization awq

8.2 Chat 模型输出乱码#

如果使用 llm.generate 直接传入文本给 Chat 模型,输出可能不符合预期。

✅ 解决方案:改用 llm.chat 方法或手动调用 tokenizer.apply_chat_template,确保输入格式符合模型的 Chat Template。

8.3 ModelScope 下载模型#

国内环境下载 HuggingFace 模型较慢,可以切换到 ModelScope:

Terminal window
export VLLM_USE_MODELSCOPE=True
vllm serve Qwen/Qwen2.5-7B-Instruct

8.4 指定信任远程代码#

部分模型需要执行自定义代码:

Terminal window
vllm serve model_name --trust-remote-code

📝 总结#

vLLM 通过 PagedAttention 和 Continuous Batching 两大核心技术,将 LLM 推理的显存利用率和吞吐量提升到新的水平。本文覆盖了从零开始使用 vLLM 的完整路径:

  1. 理解原理:PagedAttention 将 KV Cache 分块管理,借鉴 OS 虚拟内存分页的思想解决显存碎片问题
  2. 离线推理:通过 LLM 类和 SamplingParams 快速完成批量文本生成
  3. 在线部署:一行命令启动 OpenAI 兼容 API 服务器,业务端零成本迁移
  4. 调优实践:掌握 gpu-memory-utilization、max-model-len、tensor-parallel-size 等关键参数
  5. 多 GPU 扩展:通过张量并行轻松服务 70B+ 大模型

🎯 自我检验清单#

  • 能解释 PagedAttention 的核心思想及其解决的显存碎片问题
  • 能使用 LLM 和 SamplingParams 完成离线批量推理
  • 能正确使用 llm.chat 进行 Chat 模式推理,理解 Chat Template 的重要性
  • 能用 vllm serve 启动 OpenAI 兼容的在线推理服务
  • 能使用 Python openai 客户端调用 vLLM 服务
  • 能根据模型大小和 GPU 显存选择合适的 tensor-parallel-size
  • 能通过调整 gpu-memory-utilization 和 max-model-len 解决 OOM 问题
  • 能说出 vLLM 与传统推理方式在显存管理上的核心区别

📚 参考资料#


内容来源

本文整理自开源项目 AIInfraGuide 的《vLLM 快速入门》(原文),内容版权归原作者所有。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Profile Image of the Author
Hyflu
专注 AI Infra 与 Agent 技术分享
公告
博客搭建中,将分享 AI Infra 与 Agent 相关技术文章。
分类
标签
最新动态
站点统计
文章
12
分类
3
标签
27
总字数
45,635
运行时长
0 天
最后活动
0 天前
文章目录