引言

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 CachePagedAttention提升
内存利用率60-80%96%++20-36%
最大并发请求32256+8x
吞吐量1x14-24x14-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 等量化格式

安装与快速启动

环境要求

组件最低要求推荐
GPUCUDA 12.0+A100/H100
Python3.9+3.11
CUDA12.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_utilizationGPU 内存利用率0.9生产环境设 0.85-0.9
max_model_len最大上下文长度模型默认按需调小以省内存
tensor_parallel_size张量并行度1= GPU 数量
enable_prefix_caching前缀缓存FalseRAG 场景必开
swap_spaceCPU 交换空间(GB)4高并发时增大
max_num_seqs最大并发序列256按 GPU 容量调整
enforce_eager禁用 CUDA GraphFalse调试时设 True

性能基准测试

测试环境:4×A100 80GB,Llama-3.3-70B,输入 512 tokens,输出 256 tokens:

并发数吞吐量平均延迟P99 延迟GPU 利用率
1455.76.125%
82807.39.265%
328509.714.388%
64120013.522.194%
128140018.235.697%

吞吐量单位: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_percGPU 缓存使用率> 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论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。