直接用 HuggingFace transformers 跑 LLM 推理性能很差:
batch 1 时 GPU 利用率 30-50%,多并发请求时显存碎片化 OOM。
vLLM 是伯克利出的高性能 LLM 推理引擎,核心技术是 PagedAttention
(像 OS 分页一样管理 KV cache),加上 continuous batching,
比 transformers 直接推理快 5-24 倍。
安装
uv add vllm
# 需要 CUDA 11.8+ 或 12.x,PyTorch 2.x
命令行起服务
uv run vllm serve Qwen/Qwen2.5-7B-Instruct \
--tensor-parallel-size 1 \
--max-model-len 8192 \
--gpu-memory-utilization 0.85 \
--port 8000
第一次启动会从 HuggingFace 下载模型(~15GB)。
启动后默认 OpenAI 兼容 API。
调用
curl http://localhost:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "Qwen/Qwen2.5-7B-Instruct",
"messages": [{"role": "user", "content": "你好"}],
"max_tokens": 200
}'
或 Python:
from openai import OpenAI
client = OpenAI(base_url='http://localhost:8000/v1', api_key='dummy')
resp = client.chat.completions.create(
model='Qwen/Qwen2.5-7B-Instruct',
messages=[{'role': 'user', 'content': '你好'}],
max_tokens=200,
)
print(resp.choices[0].message.content)
关键参数
--max-model-len:上下文最大长度(影响 KV cache 大小)--gpu-memory-utilization:用多少显存(0-1,默认 0.9)--tensor-parallel-size:多 GPU 时拆 tensor 并行(4 卡设 4)--quantization awq/gptq/fp8:量化加速--enable-prefix-caching:相同前缀的请求复用 KV cache(系统 prompt 共享场景大幅加速)
Python 直接调用(不走 HTTP)
from vllm import LLM, SamplingParams
llm = LLM(model='Qwen/Qwen2.5-7B-Instruct', gpu_memory_utilization=0.85)
prompts = [
'介绍一下 RAG',
'解释 PagedAttention',
'写一个 Python 二分查找',
]
params = SamplingParams(temperature=0.3, max_tokens=300)
outputs = llm.generate(prompts, params)
for out in outputs:
print('---')
print(out.outputs[0].text)
vLLM 自动 batch 这 3 个 prompt 一起跑,单次 forward 处理多个序列。
continuous batching 的含义
传统推理:
batch 1: [seq A 100 tokens, seq B 80 tokens, seq C 60 tokens]
等三个序列都完成才能下一个 batch
continuous batching:
任意时刻一个请求结束就立刻让出位置给新请求
GPU 持续吃满,无 idle
这是 vLLM 高吞吐的核心,比"动态 batch"更激进。
benchmark:vs 直接 transformers
# 100 个并发请求,每个生成 200 token
# vLLM
ab -n 100 -c 16 -p body.json -T application/json \
http://localhost:8000/v1/chat/completions
# 通常:3000-8000 tokens/s 吞吐
# transformers + 简单 FastAPI 包装
# 通常:300-800 tokens/s
10x 量级的吞吐差距。
多卡:tensor parallelism
70B 模型单卡装不下,4 张 A100 拆开:
uv run vllm serve meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 4 \
--max-model-len 8192
vLLM 自动用 NCCL 在 4 卡间分配 attention head / FFN 矩阵。
量化:让更大模型跑在更小显卡
# AWQ 4-bit
uv run vllm serve TheBloke/Llama-3.1-70B-AWQ \
--quantization awq
# 4 bit 量化的 70B 大约 40GB 显存(不量化要 140GB)
# FP8 (需要 H100)
uv run vllm serve meta-llama/Llama-3.1-70B-Instruct \
--quantization fp8
长上下文
# 32k 上下文
uv run vllm serve Qwen/Qwen2.5-7B-Instruct \
--max-model-len 32768
但 KV cache 占显存 = batch_size × max_seq_len × 每层 KV size。
32k context + 100 batch ≈ 显存吃 50%+,要 trade off。
与 Hugging Face 模型生态
vLLM 支持的 model:Llama / Mistral / Qwen / Mixtral / Gemma /
Yi / DeepSeek / Phi / Baichuan / ChatGLM 等几乎全部主流开源 LLM。
官方维护清单看 vLLM docs。
与 sglang / lmdeploy 对比
| 引擎 | 优势 | 劣势 |
|---|---|---|
| vLLM | 生态最大、模型最多 | 长上下文性能一般 |
| TGI (HF) | HF 官方、生产稳 | 吞吐略低于 vLLM |
| sglang | 结构化生成(JSON / regex)极快 | 模型支持稍少 |
| lmdeploy | 国内(商汤)、TurboMind 后端快 | 文档不全 |
通用选 vLLM;要求 JSON 严格输出选 sglang。
prefix caching:相同系统 prompt 复用
uv run vllm serve qwen2.5:7b --enable-prefix-caching
所有请求都用 "You are a helpful assistant..." 起头的话,
prefix 这部分的 KV cache 只算一次,10k token 系统 prompt 几乎免费。
生产部署清单
- 用 systemd 起 vLLM service
- 前面套 nginx 反代(限流 + auth)
- Prometheus 抓 vLLM 内置的
/metrics - health check:
/health - 多模型用多个 vLLM 进程,每个绑不同 GPU
踩过的坑
- 启动时 "out of memory":
--gpu-memory-utilization调小,
或减--max-model-len。 - 模型权重 download 慢:用 HuggingFace mirror 或预先下载,
HF_HUB_OFFLINE=1让 vLLM 不再尝试下载。 - TP > 1 时 NCCL 卡死:检查机器内 GPU 互联(PCIe / NVLink);
设NCCL_P2P_DISABLE=1排查。 - vLLM 0.5+ 跟 PyTorch 2.4+ 紧耦合,旧 PyTorch 装不上。
uv自动解析
依赖一般没问题,手动 pip 时容易翻车。
登录后参与评论。