vLLM:高性能LLM推理引擎

vLLM是2026年最流行的开源LLM推理引擎,以其PagedAttention技术和连续批处理实现了极高的推理吞吐量。Docker部署是vLLM最常见的生产部署方式。

基础部署

Docker Compose

# docker-compose.yml
version: '3.8'

services:
  vllm:
    image: vllm/vllm-openai:latest
    container_name: vllm-server
    runtime: nvidia
    ports:
      - "8000:8000"
    volumes:
      - ./models:/app/models          # 模型存储
      - ./config:/app/config          # 配置文件
      - vllm_cache:/root/.cache       # 缓存
    environment:
      - HUGGING_FACE_HUB_TOKEN=${HF_TOKEN}
    command: >
      --model /app/models/Qwen-3-32B
      --served-model-name qwen3-32b
      --tensor-parallel-size 2
      --gpu-memory-utilization 0.90
      --max-model-len 32768
      --max-num-seqs 256
      --quantization awq
      --dtype float16
      --trust-remote-code
      --api-key ${VLLM_API_KEY}
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 2
              capabilities: [gpu]
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  vllm_cache:

启动服务

# 创建环境变量
echo "HF_TOKEN=your_hf_token" > .env
echo "VLLM_API_KEY=your_api_key" >> .env

# 启动
docker compose up -d

# 查看日志
docker compose logs -f vllm

# 健康检查
curl http://localhost:8000/health

关键参数详解

模型加载参数

vllm serve /app/models/model_name \
  --model /app/models/Qwen-3-32B \
  # 模型路径,支持HuggingFace格式

  --served-model-name qwen3-32b \
  # API中使用的模型名称

  --tokenizer /app/models/Qwen-3-32B \
  # 分词器路径(默认与模型相同)

  --trust-remote-code \
  # 信任远程代码(自定义模型结构需要)

  --dtype float16 \
  # 数据类型:auto/float16/bfloat16/float32

  --quantization awq
  # 量化方式:awq/gptq/squeezellm/None

并行与显存参数

  --tensor-parallel-size 2 \
  # 张量并行度(通常等于GPU数)

  --pipeline-parallel-size 1 \
  # 流水线并行度

  --gpu-memory-utilization 0.90 \
  # GPU显存利用率上限(0-1)

  --swap-space 4 \
  # CPU交换空间大小(GB)

  --kv-cache-dtype auto \
  # KV Cache精度:auto/fp8/int8

批处理参数

  --max-model-len 32768 \
  # 最大序列长度

  --max-num-seqs 256 \
  # 最大并发序列数

  --max-num-batched-tokens 8192 \
  # 单次批处理的最大token数

  --enable-chunked-prefill \
  # 启用分块预填充

  --max-num-partial-tokens 8192
  # 分块预填充的块大小

高级配置

多模型服务

# docker-compose-multi.yml
version: '3.8'

services:
  vllm-model-a:
    image: vllm/vllm-openai:latest
    runtime: nvidia
    ports:
      - "8001:8000"
    command: >
      --model /models/Qwen-3-7B
      --served-model-name qwen3-7b
      --tensor-parallel-size 1
      --gpu-memory-utilization 0.45
      --max-model-len 8192
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ['0']
              capabilities: [gpu]

  vllm-model-b:
    image: vllm/vllm-openai:latest
    runtime: nvidia
    ports:
      - "8002:8000"
    command: >
      --model /models/Qwen-3-32B
      --served-model-name qwen3-32b
      --tensor-parallel-size 1
      --gpu-memory-utilization 0.45
      --quantization awq
      --max-model-len 16384
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ['1']
              capabilities: [gpu]

  # API网关
  nginx:
    image: nginx:alpine
    ports:
      - "8000:8000"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - vllm-model-a
      - vllm-model-b

Nginx路由配置

# nginx.conf
upstream model_a {
    server vllm-model-a:8000;
}

upstream model_b {
    server vllm-model-b:8000;
}

server {
    listen 8000;
    
    # 按模型名称路由
    location /v1/chat/completions {
        # 读取请求体中的model字段
        set $upstream "";
        
        if ($request_body ~* '"model"\s*:\s*"qwen3-7b"') {
            set $upstream model_a;
        }
        if ($request_body ~* '"model"\s*:\s*"qwen3-32b"') {
            set $upstream model_b;
        }
        
        proxy_pass http://$upstream;
        proxy_set_header Host $host;
        proxy_buffering off;
        proxy_read_timeout 300s;
    }
    
    # 健康检查
    location /health {
        return 200 "OK";
    }
}

性能优化

分块预填充

vllm serve model \
  --enable-chunked-prefill \
  --max-num-batched-tokens 8192 \
  # 预填充和生成可以混合批处理
  # 避免长prompt阻塞短prompt的生成

前缀缓存

vllm serve model \
  --enable-prefix-caching \
  # 自动缓存相同前缀的KV Cache
  # 对系统提示词重复的场景大幅加速

推测解码

vllm serve model \
  --speculative-model /models/draft-model \
  --num-speculative-tokens 5 \
  # 使用小模型加速大模型推理

客户端调用

Python SDK

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="your_api_key"
)

# 对话
response = client.chat.completions.create(
    model="qwen3-32b",
    messages=[
        {"role": "system", "content": "你是一个专业助手"},
        {"role": "user", "content": "解释MoE架构"}
    ],
    max_tokens=2048,
    temperature=0.7,
    stream=True
)

for chunk in response:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

异步批量请求

import asyncio
from openai import AsyncOpenAI

async def batch_chat():
    client = AsyncOpenAI(
        base_url="http://localhost:8000/v1",
        api_key="your_api_key"
    )
    
    tasks = [
        client.chat.completions.create(
            model="qwen3-32b",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=512
        )
        for prompt in prompts
    ]
    
    results = await asyncio.gather(*tasks)
    return [r.choices[0].message.content for r in results]

监控

Prometheus指标

vLLM内置Prometheus指标导出:

# 指标端点
# http://localhost:8000/metrics

# 关键指标
"""
vllm:num_requests_running      正在运行的请求数
vllm:num_requests_waiting      等待中的请求数
vllm:gpu_cache_usage_perc      KV Cache使用率
vllm:time_to_first_token       首token延迟
vllm:time_per_output_token     每token生成时间
vllm:e2e_request_latency       端到端请求延迟
"""

Grafana仪表板

{
  "dashboard": {
    "title": "vLLM Monitor",
    "panels": [
      {
        "title": "Requests Running/Waiting",
        "query": "vllm:num_requests_running",
        "type": "graph"
      },
      {
        "title": "GPU Cache Usage",
        "query": "vllm:gpu_cache_usage_perc",
        "type": "gauge"
      },
      {
        "title": "TTFT (ms)",
        "query": "histogram_quantile(0.95, vllm:time_to_first_token_bucket)",
        "type": "graph"
      }
    ]
  }
}

故障排除

OOM(显存不足)

# 降低显存利用率
--gpu-memory-utilization 0.85

# 减少最大序列数
--max-num-seqs 128

# 减少最大长度
--max-model-len 16384

# 使用量化
--quantization awq

首Token延迟高

# 启用分块预填充
--enable-chunked-prefill

# 减少批处理大小(减少排队)
--max-num-seqs 64

吞吐量低

# 增加并发
--max-num-seqs 512

# 启用前缀缓存
--enable-prefix-caching

# 使用更激进的量化
--quantization gptq --dtype float16

结语

vLLM Docker部署是生产环境中最常见的方案。合理配置并行度、显存利用率和批处理参数,可以让vLLM发挥出极高的推理性能。配合监控和负载均衡,可以构建支持高并发的LLM服务。

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

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