vLLM 部署一个高吞吐量 LLM 推理服务(PagedAttention)

直接用 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 几乎免费。

生产部署清单

  1. 用 systemd 起 vLLM service
  2. 前面套 nginx 反代(限流 + auth)
  3. Prometheus 抓 vLLM 内置的 /metrics
  4. health check:/health
  5. 多模型用多个 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 时容易翻车。
精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。