跳转至

vLLM 本地部署配置

高吞吐量的 LLM 推理引擎,支持连续批处理和 PagedAttention,适合生产环境


系统要求

项目 最低要求 推荐
Python 3.8+ 3.10+
GPU NVIDIA (CUDA 11.6+) NVIDIA A100/H100/RTX 4090
GPU 显存 16 GB 24 GB+
CUDA 11.6+ 12.x
操作系统 Linux Ubuntu 22.04

⚠️ vLLM 目前仅支持 NVIDIA GPU,不支持纯 CPU 推理


安装

pip 安装

Bash
1
2
3
4
5
# 基础安装
pip install vllm

# 指定 CUDA 版本
pip install vllm --extra-index-url https://download.pytorch.org/whl/cu121

从源码安装

Bash
1
2
3
git clone https://github.com/vllm-project/vllm
cd vllm
pip install -e .

Docker

Bash
# 基础镜像
docker run --runtime=nvidia --gpus all \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  -p 8000:8000 \
  --ipc=host \
  vllm/vllm-openai:latest \
  --model Qwen/Qwen2.5-7B-Instruct

# 自定义构建
docker build -f Dockerfile -t vllm:custom .

Python API 使用

离线批量推理

Python
from vllm import LLM, SamplingParams

# 初始化模型
llm = LLM(
    model="Qwen/Qwen2.5-7B-Instruct",
    tensor_parallel_size=1,  # GPU 数量
    gpu_memory_utilization=0.9,
    max_model_len=4096,
)

# 采样参数
params = SamplingParams(
    temperature=0.7,
    top_p=0.9,
    max_tokens=512,
    stop=["<|im_end|>"],
)

# 批量生成
prompts = [
    "你好,请自我介绍",
    "用 Python 写一个快排",
    "解释什么是 Transformer",
]
outputs = llm.generate(prompts, sampling_params=params)

for output in outputs:
    print(f"Prompt: {output.prompt!r}")
    print(f"Output: {output.outputs[0].text!r}")
    print()

Chat 接口

Python
from vllm import LLM, SamplingParams

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

# Chat 格式
from vllm.entrypoints.openai.protocol import ChatCompletionRequest
conversation = [
    {"role": "system", "content": "你是Python助手"},
    {"role": "user", "content": "写一个快排"},
]

params = SamplingParams(temperature=0.7, max_tokens=512)
outputs = llm.chat(messages=conversation, sampling_params=params)
print(outputs[0].outputs[0].text)

OpenAI 兼容 API 服务

启动服务

Bash
1
2
3
4
5
6
7
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-7B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.9 \
  --max-model-len 4096 \
  --dtype auto

关键启动参数

参数 说明 默认值 建议值
--model 模型名称或路径 必填
--host 监听地址 127.0.0.1 0.0.0.0
--port 端口 8000
--gpu-memory-utilization GPU 显存利用率 0.9 0.85~0.95
--max-model-len 最大上下文长度 模型默认 按需设小省显存
--dtype 数据类型 auto auto / float16 / bfloat16
--quantization 量化方法 awq / gptq / fp8 / bitsandbytes
--tensor-parallel-size 张量并行 GPU 数 1 按 GPU 数
--pipeline-parallel-size 流水线并行数 1 多机部署
--enable-prefix-caching 前缀缓存 false 开启可加速
--enable-chunked-prefill 分块预填充 false 开启提升吞吐
--swap-space CPU swap 空间(GB) 4 4~16
--served-model-name 服务模型名 原模型名 自定义
--chat-template 聊天模板路径 自动检测 自定义时指定

API 调用示例

Bash
# Chat Completions
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen/Qwen2.5-7B-Instruct",
    "messages": [
      {"role": "system", "content": "你是Python助手"},
      {"role": "user", "content": "写一个快排"}
    ],
    "temperature": 0.7,
    "max_tokens": 1024,
    "stream": true
  }'

# Completions
curl http://localhost:8000/v1/completions -d '{
  "model": "Qwen/Qwen2.5-7B-Instruct",
  "prompt": "Python快排:",
  "max_tokens": 512
}'

# Embeddings
curl http://localhost:8000/v1/embeddings -d '{
  "model": "Qwen/Qwen2.5-7B-Instruct",
  "input": "你好世界"
}'

Python SDK 调用

Python
import openai

client = openai.OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="EMPTY"
)

# 流式对话
stream = client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct",
    messages=[{"role": "user", "content": "你好"}],
    stream=True
)
for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

量化模型部署

AWQ 量化

Bash
1
2
3
4
5
# 启动 AWQ 量化模型
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-7B-Instruct-AWQ \
  --quantization awq \
  --gpu-memory-utilization 0.9

GPTQ 量化

Bash
1
2
3
4
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 \
  --quantization gptq \
  --gpu-memory-utilization 0.9

FP8 量化

Bash
1
2
3
4
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-7B-Instruct \
  --quantization fp8 \
  --gpu-memory-utilization 0.9

BitsAndBytes (NF4)

Bash
1
2
3
4
5
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-7B-Instruct \
  --quantization bitsandbytes \
  --load-format bitsandbytes \
  --gpu-memory-utilization 0.9

多 GPU 部署

张量并行(单机多卡)

Bash
# 2 GPU
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-72B-Instruct \
  --tensor-parallel-size 2 \
  --gpu-memory-utilization 0.9

# 4 GPU
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-72B-Instruct \
  --tensor-parallel-size 4

流水线并行(多机部署)

Bash
# 节点 0(主节点)
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-72B-Instruct \
  --tensor-parallel-size 2 \
  --pipeline-parallel-size 2 \
  --distributed-executor-backend ray

# 节点 1(工作节点)
python -m vllm.worker.worker \
  --model Qwen/Qwen2.5-72B-Instruct \
  --tensor-parallel-size 2 \
  --pipeline-parallel-size 2

性能优化

关键优化选项

选项 说明 效果
--enable-prefix-caching 自动缓存相同前缀 重复 Prompt 大幅加速
--enable-chunked-prefill 分块预填充 提升首 Token 速度
--speculative-decoding 投机解码 小模型+大模型加速
--swap-space 16 CPU swap 超出显存时不 OOM

Speculative Decoding 配置

Bash
1
2
3
4
5
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-14B-Instruct \
  --speculative-model Qwen/Qwen2.5-7B-Instruct \
  --num-speculative-tokens 5 \
  --speculative-max-tokens 32

Benchmark

Bash
# vLLM 自带 benchmark
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-7B-Instruct --port 8000 &

# 使用 benchmark 脚本
python benchmarks/benchmark_serving.py \
  --backend vllm \
  --model Qwen/Qwen2.5-7B-Instruct \
  --dataset-name sharegpt \
  --num-prompts 100

自定义聊天模板

Bash
1
2
3
4
# 指定 chat template 文件
python -m vllm.entrypoints.openai.api_server \
  --model /path/to/model \
  --chat-template /path/to/chat_template.jinja

chat_template.jinja 示例(Qwen 格式):

Django/Jinja
1
2
3
4
5
6
{% for message in messages %}
{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}
{% endfor %}
{% if add_generation_prompt %}
{{ '<|im_start|>assistant\n' }}
{% endif %}

常见问题

Q: CUDA Out of Memory?

  • 降低 --gpu-memory-utilization(如 0.8)
  • 减小 --max-model-len(如 2048)
  • 使用量化模型(AWQ/GPTQ)
  • 增大 --swap-space(CPU swap 兜底)
  • 使用张量并行分到多卡

Q: 首次加载很慢?

首次需要下载模型并加载到 GPU,后续请求会很快。使用 --enable-prefix-caching 可缓存系统 Prompt。

Q: 如何限制并发?

--max-num-seqs 控制最大并发序列数。


练习清单

  • pip 安装 vLLM,启动 OpenAI 兼容服务
  • 用 OpenAI Python SDK 调用,实现流式对话
  • 部署 AWQ 量化模型,对比精度和速度
  • 配置前缀缓存,测试重复 Prompt 加速效果
  • 使用 Speculative Decoding 加速
  • 用 vLLM 自带 benchmark 测试吞吐量
  • 双 GPU 张量并行部署大模型