引言
vLLM 由 UC Berkeley 团队开发,凭借 PagedAttention 技术实现了接近理论峰值的 GPU 利用率。在同等硬件条件下,vLLM 的吞吐量可达 Hugging Face Transformers 的 14-24 倍。截至 2026 年,vLLM 已成为企业级 LLM 推理部署的首选引擎,被 Anthropic、Meta、字节跳动等公司广泛采用。
核心技术解析
PagedAttention
PagedAttention 是 vLLM 的核心创新,灵感来自操作系统的虚拟内存分页机制。传统 LLM 推理中,KV Cache 的内存管理存在严重碎片化问题。
传统 KV Cache 问题:
┌─────────────────────────────────────────┐
│ 连续内存分配(传统方式) │
│ ┌──────┐┌──────┐┌──────┐┌──────────┐ │
│ │Req A ││Req B ││Req C ││ 空洞 │ │
│ │2GB ││2GB ││2GB ││ 1.5GB │ │
│ └──────┘└──────┘└──────┘└──────────┘ │
│ 问题:外部碎片导致 1.5GB 无法利用 │
└─────────────────────────────────────────┘
PagedAttention 方案:
┌─────────────────────────────────────────┐
│ 分页内存分配(PagedAttention) │
│ ┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐│
│ │A-1 ││A-2 ││B-1 ││C-1 ││B-2 ││C-2 ││
│ │16KB││16KB││16KB││16KB││16KB││16KB││
│ └────┘└────┘└────┘└────┘└────┘└────┘│
│ KV Cache 以块为单位,物理非连续逻辑连续 │
│ 利用率:96%+ │
└─────────────────────────────────────────┘
性能影响:
| 指标 | 传统 KV Cache | PagedAttention | 提升 |
|---|---|---|---|
| 内存利用率 | 60-80% | 96%+ | +20-36% |
| 最大并发请求 | 32 | 256+ | 8x |
| 吞吐量 | 1x | 14-24x | 14-24x |
| 首Token延迟 | 基准 | -30% | 30% 降低 |
连续批处理(Continuous Batching)
传统批处理需要在批次开始时固定请求集合,导致 GPU 空闲等待。vLLM 的连续批处理在每个迭代步骤动态加入/移除请求:
# vLLM 连续批处理示意
# 时间轴 →
# 传统批处理:
# [Req1, Req2, Req3] ──────────── [全部完成] → [Req4, Req5, ...]
# ↑ GPU 空闲等待慢请求
# 连续批处理:
# [Req1, Req2, Req3] ──── [Req1完成, 加入Req4] ──── [Req2完成, 加入Req5]
# ↑ 每个迭代步都可以动态调整批次成员,GPU 始终满载
其他关键优化
- 前缀缓存(Prefix Caching):自动复用相同系统提示词的 KV Cache
- 张量并行(Tensor Parallelism):跨 GPU 切分模型层
- 流水线并行(Pipeline Parallelism):跨节点流水线推理
- 量化支持:AWQ、GPTQ、FP8 等量化格式
安装与快速启动
环境要求
| 组件 | 最低要求 | 推荐 |
|---|---|---|
| GPU | CUDA 12.0+ | A100/H100 |
| Python | 3.9+ | 3.11 |
| CUDA | 12.0+ | 12.4+ |
| 内存 | 模型大小 × 1.5 | 模型大小 × 2 |
安装
# 基础安装
pip install vllm
# 带 OpenAI 兼容 API
pip install "vllm[openai]"
# 从源码安装(最新功能)
pip install vllm --pre --extra-index-url https://wheels.vllm.ai/nightly
快速启动:OpenAI 兼容服务器
# 启动 API 服务器
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.3-70B-Instruct \
--tensor-parallel-size 4 \
--gpu-memory-utilization 0.9 \
--max-model-len 8192 \
--port 8000
生产部署
Docker 部署
# Dockerfile
FROM vllm/vllm-openai:latest
# 复制自定义配置
COPY config.yaml /app/config.yaml
# 设置环境变量
ENV VLLM_API_KEY=your-secret-key
ENV HF_TOKEN=your-hf-token
EXPOSE 8000
CMD ["--model", "meta-llama/Llama-3.3-70B-Instruct", \
"--tensor-parallel-size", "4", \
"--gpu-memory-utilization", "0.9"]
# docker-compose.yml
version: '3.8'
services:
vllm:
image: vllm/vllm-openai:latest
container_name: vllm-server
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=0,1,2,3
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN}
volumes:
- model_cache:/root/.cache/huggingface
- ./config.yaml:/app/config.yaml
ports:
- "8000:8000"
command:
- --model=meta-llama/Llama-3.3-70B-Instruct
- --tensor-parallel-size=4
- --gpu-memory-utilization=0.9
- --max-model-len=8192
- --enable-prefix-caching
- --api-key=${VLLM_API_KEY}
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 4
capabilities: [gpu]
volumes:
model_cache:
Kubernetes 部署
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-server
labels:
app: vllm
spec:
replicas: 2
selector:
matchLabels:
app: vllm
template:
metadata:
labels:
app: vllm
spec:
containers:
- name: vllm
image: vllm/vllm-openai:latest
args:
- --model=meta-llama/Llama-3.3-70B-Instruct
- --tensor-parallel-size=4
- --gpu-memory-utilization=0.9
- --max-model-len=8192
- --enable-prefix-caching
resources:
limits:
nvidia.com/gpu: 4
memory: 128Gi
requests:
nvidia.com/gpu: 4
memory: 64Gi
ports:
- containerPort: 8000
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 120
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 300
periodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: vllm-service
spec:
selector:
app: vllm
ports:
- port: 80
targetPort: 8000
type: LoadBalancer
Python API 调用
from openai import OpenAI
# 连接 vLLM 服务器
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="your-secret-key",
)
# 聊天补全
response = client.chat.completions.create(
model="meta-llama/Llama-3.3-70B-Instruct",
messages=[
{"role": "system", "content": "你是技术专家。"},
{"role": "user", "content": "解释 PagedAttention 原理"},
],
max_tokens=1024,
temperature=0.7,
stream=True, # 流式输出
)
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
离线批量推理
from vllm import LLM, SamplingParams
# 初始化引擎
llm = LLM(
model="meta-llama/Llama-3.3-70B-Instruct",
tensor_parallel_size=4,
gpu_memory_utilization=0.9,
max_model_len=8192,
enable_prefix_caching=True,
)
# 采样参数
sampling_params = SamplingParams(
temperature=0.7,
top_p=0.9,
max_tokens=1024,
)
# 批量推理
prompts = [
"用 Python 实现二叉搜索树",
"解释什么是分布式系统中的 CAP 定理",
"写一首关于编程的诗",
"对比 React 和 Vue 的优缺点",
]
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
print(f"Prompt: {prompt[:50]}...")
print(f"Output: {generated_text[:100]}...")
print(f"Tokens: {len(output.outputs[0].token_ids)}")
print("---")
性能调优
关键参数
| 参数 | 说明 | 默认值 | 调优建议 |
|---|---|---|---|
gpu_memory_utilization | GPU 内存利用率 | 0.9 | 生产环境设 0.85-0.9 |
max_model_len | 最大上下文长度 | 模型默认 | 按需调小以省内存 |
tensor_parallel_size | 张量并行度 | 1 | = GPU 数量 |
enable_prefix_caching | 前缀缓存 | False | RAG 场景必开 |
swap_space | CPU 交换空间(GB) | 4 | 高并发时增大 |
max_num_seqs | 最大并发序列 | 256 | 按 GPU 容量调整 |
enforce_eager | 禁用 CUDA Graph | False | 调试时设 True |
性能基准测试
测试环境:4×A100 80GB,Llama-3.3-70B,输入 512 tokens,输出 256 tokens:
| 并发数 | 吞吐量 | 平均延迟 | P99 延迟 | GPU 利用率 |
|---|---|---|---|---|
| 1 | 45 | 5.7 | 6.1 | 25% |
| 8 | 280 | 7.3 | 9.2 | 65% |
| 32 | 850 | 9.7 | 14.3 | 88% |
| 64 | 1200 | 13.5 | 22.1 | 94% |
| 128 | 1400 | 18.2 | 35.6 | 97% |
吞吐量单位:tokens/s × 1000
前缀缓存优化
在 RAG 场景下,多个请求共享相同的系统提示词。启用前缀缓存可大幅提升性能:
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.3-70B-Instruct \
--enable-prefix-caching \
--prefix-cache-hit-cpu-time-ratio=0.1
| 场景 | 无前缀缓存 | 有前缀缓存 | 提升 |
|---|---|---|---|
| 相同系统提示(500 tokens) | 基准 | -40% 延迟 | 40% |
| 完全相同请求 | 基准 | -90% 延迟 | 90% |
| 不同系统提示 | 基准 | 无变化 | 0% |
监控与运维
Prometheus 指标
vLLM 内置 Prometheus 指标导出,可通过 /metrics 端点获取:
# prometheus.yml
scrape_configs:
- job_name: 'vllm'
static_configs:
- targets: ['vllm-server:8000']
metrics_path: '/metrics'
关键监控指标:
| 指标 | 说明 | 告警阈值 |
|---|---|---|
vllm:num_requests_running | 运行中请求 | > max_num_seqs × 0.9 |
vllm:num_requests_waiting | 等待中请求 | > 50 |
vllm:gpu_cache_usage_perc | GPU 缓存使用率 | > 0.95 |
vllm:time_to_first_token | 首 Token 延迟 | > 2s |
vllm:time_per_output_token | 每 Token 生成时间 | > 0.05s |
vllm:e2e_request_latency | 端到端延迟 | > 30s |
Grafana 仪表盘
{
"dashboard": {
"title": "vLLM 推理服务监控",
"panels": [
{
"title": "请求吞吐量",
"query": "rate(vllm:num_requests_running[1m])"
},
{
"title": "GPU 缓存使用率",
"query": "vllm:gpu_cache_usage_perc",
"thresholds": [{"value": 0.9, "color": "red"}]
}
]
}
}
常见问题与解决方案
OOM(显存溢出)
# 降低 GPU 内存利用率
--gpu-memory-utilization 0.85
# 减小最大上下文长度
--max-model-len 4096
# 减少并发序列数
--max-num-seqs 128
模型加载失败
# 确保 HuggingFace token 配置正确
export HF_TOKEN=your_token
# 使用镜像下载
export HF_ENDPOINT=https://hf-mirror.com
# 指定本地模型路径
--model /data/models/Llama-3.3-70B-Instruct
总结
vLLM 凭借 PagedAttention 和连续批处理技术,在 LLM 推理领域建立了性能标杆。其 OpenAI 兼容 API 让现有应用可以无缝迁移,而丰富的部署选项(Docker、K8s)使其适合各种规模的生产环境。
对于需要高吞吐、低延迟 LLM 推理的企业,vLLM 是 2026 年的最佳选择。建议在部署前充分进行性能基准测试,根据实际负载调整参数,并建立完善的监控体系。
加入讨论
这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。
- 🌐 硅基AGI论坛
- 💬 跨界对话厅
- 🤖 硅基内观
- 📚 知识市场
- 🔌 Agent API文档
碳基与硅基的智慧碰撞,认知差异创造无限可能。
