技术博客

vLLM 2026 生产部署指南:PagedAttention、连续批处理与高并发推理实战

vLLM 已成为 2026 年开源 LLM 推理的事实标准,支持 Llama、Qwen、DeepSeek 等主流模型,单 GPU 吞吐量比朴素实现高出数倍。本文从生产角度讲解 vLLM 的核心技术原理(PagedAttention / 连续批处理)、完整的部署配置(单 GPU / 多 GPU 张量并行)、关键参数调优、监控指标采集,以及在 Kubernetes 上的容器化部署方案。

vLLMLLM推理部署PagedAttentionGPUAI基础设施Kubernetes大模型

如果你要在自己的服务器上部署一个大语言模型并提供 API 服务,2026 年的标准答案是 vLLM

vLLM 是加州大学伯克利分校发起的开源项目,目前由活跃的社区维护。它解决了朴素推理实现中最核心的性能问题,在高并发场景下吞吐量通常比 HuggingFace Transformers 的 generate() 高出 10-24 倍。


核心技术:为什么 vLLM 快

PagedAttention

LLM 推理的内存瓶颈在于 KV Cache(Key-Value Cache)——模型在生成每个 token 时,需要保存之前所有 token 的 K、V 矩阵。

传统实现的问题:
  为每个请求预分配最大序列长度的连续内存
  一个请求实际生成 200 tokens,但预分配了 4096 tokens 的空间
  → 内存碎片化,GPU 利用率低
  → 并发请求数少(因为内存被浪费了)

PagedAttention 的解法:
  借鉴操作系统的虚拟内存分页思想
  KV Cache 被切分成固定大小的 Block(默认 16 tokens/block)
  按需分配 Block,不浪费
  不同请求的 Block 可以物理不连续,但逻辑上连续
  → GPU 显存利用率提升 40-60%
  → 相同显存下,并发请求数翻倍

连续批处理(Continuous Batching)

传统静态批处理:
  等待一批请求凑齐 → 一起处理 → 等待全部完成 → 才接受新请求
  问题:早完成的请求要等慢请求,GPU 空转

连续批处理:
  请求完成一个,立刻把新请求插入 batch
  每个 decode step,batch 里的请求数量动态变化
  → GPU 始终保持高利用率
  → 时延和吞吐量都更好

安装和基础部署

环境要求

最低要求:
  NVIDIA GPU,显存 >= 16GB(7B 模型 FP16)
  CUDA >= 11.8
  Python >= 3.9
  Linux(Ubuntu 22.04 / CentOS 8+)

推荐配置:
  A100 40GB:可运行 13B FP16 或 7B FP16(量化运行 34B)
  A100 80GB:可运行 34B FP16 或 70B(需要多 GPU)
  RTX 4090 24GB:7B FP16,适合开发测试

没有物理 GPU?
  AutoDL(国内):按小时租 A100/4090,价格合理
  阿里云 GPU 实例:生产环境推荐

安装

# 创建虚拟环境(推荐)
python3 -m venv vllm-env
source vllm-env/bin/activate

# 安装 vLLM(包含 CUDA 依赖)
pip install vllm

# 验证安装
python -c "import vllm; print(vllm.__version__)"

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

启动推理服务

# 基础启动:Qwen2.5-7B-Instruct
python -m vllm.entrypoints.openai.server \
    --model Qwen/Qwen2.5-7B-Instruct \
    --host 0.0.0.0 \
    --port 8000

# 常用参数说明:
# --max-model-len       最大序列长度(默认从模型配置读取)
# --gpu-memory-utilization  GPU 显存使用比例(默认 0.9,即 90%)
# --max-num-seqs        最大并发请求数(默认 256)
# --dtype               模型精度(auto/float16/bfloat16)
# --tensor-parallel-size  张量并行 GPU 数量(多 GPU 时使用)

# 生产推荐启动参数
python -m vllm.entrypoints.openai.server \
    --model Qwen/Qwen2.5-7B-Instruct \
    --host 0.0.0.0 \
    --port 8000 \
    --dtype bfloat16 \
    --max-model-len 8192 \
    --gpu-memory-utilization 0.85 \
    --max-num-seqs 128 \
    --disable-log-requests                # 生产环境减少日志噪音

多 GPU 张量并行部署(70B 模型)

# 4 张 A100 80GB 运行 Llama 3.1 70B
python -m vllm.entrypoints.openai.server \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 4 \
    --dtype bfloat16 \
    --gpu-memory-utilization 0.90 \
    --max-model-len 8192

# 确认多 GPU 被使用
nvidia-smi  # 确认 4 块 GPU 都有显存占用

量化部署(显存不足时)

# AWQ 量化版本(精度损失小,显存减半)
# 以 Qwen2.5-7B-Instruct-AWQ 为例

python -m vllm.entrypoints.openai.server \
    --model Qwen/Qwen2.5-7B-Instruct-AWQ \
    --quantization awq \
    --dtype auto \
    --gpu-memory-utilization 0.85

# 显存对比:
# Qwen2.5-7B FP16:约 14GB
# Qwen2.5-7B AWQ:约 6GB(使用 4bit 量化)
# → 一张 RTX 4090 可以同时加载 3 个量化 7B 模型

# GPTQ 量化版本(社区量化模型多)
python -m vllm.entrypoints.openai.server \
    --model TheBloke/Llama-2-7B-Chat-GPTQ \
    --quantization gptq \
    --dtype float16

API 调用(OpenAI 兼容)

vLLM 暴露的 API 与 OpenAI API 完全兼容,原本调用 OpenAI 的代码只需改 base_url

from openai import OpenAI

# 指向本地 vLLM 服务
client = OpenAI(
    api_key="no-key",           # vLLM 默认不需要 key
    base_url="http://localhost:8000/v1"
)

# 普通对话
response = client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct",
    messages=[
        {"role": "system", "content": "你是一个运维专家"},
        {"role": "user", "content": "Docker 容器 OOM 如何排查?"}
    ],
    max_tokens=512,
    temperature=0.7
)
print(response.choices[0].message.content)

# 流式输出(打字机效果)
stream = client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct",
    messages=[{"role": "user", "content": "解释 K8s 调度器原理"}],
    stream=True
)
for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

关键性能参数调优

# 参数调优参考表

--max-num-seqs 256
  # 最大并发序列数,增大可提高吞吐但增加显存占用
  # 建议:根据 GPU 显存和请求平均长度调整

--max-model-len 4096
  # 最大处理的 token 数(prompt + response)
  # 越大占显存越多,不需要长上下文时建议缩小

--gpu-memory-utilization 0.85
  # GPU 显存使用比例,留 10-15% 给系统
  # 设太高可能 OOM,设太低浪费显存

--swap-space 4
  # 当 GPU KV Cache 不足时,换到 CPU 内存(GB)
  # 会降低速度,但防止 OOM 拒绝请求
  # 生产建议:给 8-16GB

--block-size 16
  # PagedAttention Block 大小(tokens/block)
  # 通常不需要修改,16 是大多数场景的最优值

--scheduling-policy fcfs
  # 调度策略:fcfs(先到先服务)或 priority
  # priority 需要在请求中设置优先级字段

压力测试

# 安装 vLLM 自带的压测工具
pip install vllm[benchmarks]

# 模拟 100 并发,每个请求生成 200 tokens
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-7B-Instruct &

python benchmarks/benchmark_serving.py \
    --backend openai-chat \
    --base-url http://localhost:8000 \
    --model Qwen/Qwen2.5-7B-Instruct \
    --num-prompts 200 \
    --request-rate 10 \
    --max-tokens 200

# 关注指标:
# Throughput: X requests/s       → 整体吞吐量
# TTFT (Time to First Token): Xms → 首 token 延迟(影响体验感)
# TPS (Tokens Per Second): X      → 生成速度

在 Kubernetes 上部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-server
  namespace: ai-inference
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm-server
  template:
    metadata:
      labels:
        app: vllm-server
    spec:
      containers:
      - name: vllm
        image: vllm/vllm-openai:latest
        args:
        - --model
        - Qwen/Qwen2.5-7B-Instruct-AWQ
        - --quantization
        - awq
        - --gpu-memory-utilization
        - "0.85"
        - --max-model-len
        - "8192"
        ports:
        - containerPort: 8000
        resources:
          limits:
            nvidia.com/gpu: "1"     # 申请 1 张 GPU
        volumeMounts:
        - name: model-cache
          mountPath: /root/.cache/huggingface
        env:
        - name: HF_ENDPOINT
          value: "https://hf-mirror.com"    # 国内镜像加速
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 120   # 模型加载需要时间
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 120
      volumes:
      - name: model-cache
        persistentVolumeClaim:
          claimName: model-cache-pvc  # 持久化模型缓存,避免每次重启重新下载

---
apiVersion: v1
kind: Service
metadata:
  name: vllm-service
  namespace: ai-inference
spec:
  selector:
    app: vllm-server
  ports:
  - port: 80
    targetPort: 8000
  type: ClusterIP

监控指标

vLLM 内置 Prometheus 指标,路径 /metrics

# 查看可用指标
curl http://localhost:8000/metrics | grep "^vllm"
关键指标(Grafana 面板推荐):

vllm:num_requests_running          # 当前运行中的请求数
vllm:num_requests_waiting          # 等待队列中的请求数
vllm:gpu_cache_usage_perc          # GPU KV Cache 使用率(关键!)
vllm:cpu_cache_usage_perc          # CPU Swap 使用率

vllm:time_to_first_token_seconds   # TTFT 分布(histogram)
vllm:time_per_output_token_seconds # 每个 token 生成时间

vllm:prompt_tokens_total           # 累计 prompt tokens
vllm:generation_tokens_total       # 累计生成 tokens

告警建议:
  gpu_cache_usage_perc > 0.95 → 告警(接近 OOM)
  num_requests_waiting > 50   → 告警(处理能力不足,考虑扩容)
  time_to_first_token > 5s    → 告警(响应过慢)

小结

vLLM 的核心价值是把 GPU 的推理能力尽可能地榨干——PagedAttention 解决显存碎片,连续批处理解决 GPU 空转。对于有自建推理服务需求的团队,vLLM 目前是工程完成度和社区活跃度最高的选择。

从单机部署到 Kubernetes 集群,vLLM 都有比较完善的支持。配合量化技术(AWQ/GPTQ),即便是消费级 GPU 也可以跑起实用的 7B 模型,覆盖大多数企业内部应用场景。