vLLM 部署大模型推理服务完全教程:吞吐量是 Ollama 的 10 倍,生产环境首选

一、vLLM vs Ollama vs TGI:生产推理服务选型决策树

先搞清楚选型,避免选错工具走弯路:

对比维度 Ollama vLLM TGI(HuggingFace)
定位 个人/开发体验 生产高并发 生产标准,功能全
并发吞吐 低(串行处理) 极高(连续批处理)
显存利用率 低(固定分配) 高(PagedAttention) 中高
OpenAI 兼容
多 GPU ⚠️ 有限 ✅ 原生支持
量化支持 GGUF AWQ / GPTQ / FP8 AWQ / GPTQ
部署复杂度 ⭐ 极简 ⭐⭐⭐ 中等 ⭐⭐⭐⭐ 较复杂
适合场景 本地开发、RAG原型 API 服务、高并发生产 企业级、需要精细控制

选型结论

  • 自己电脑体验 / RAG 原型开发 → Ollama
  • 对外提供 API 服务 / 企业内部推理服务 → vLLM
  • 需要精细控制 + 企业 SLA → TGI

二、PagedAttention 原理:为什么 vLLM 吞吐量远超传统框架

传统推理框架的显存浪费问题:

bash 复制代码
传统方式(静态 KV Cache 分配):
请求A:分配 2GB 显存(但实际只用了 500MB,剩余闲置)
请求B:分配 2GB 显存(等待中,因为显存不够了)

vLLM PagedAttention:
将 KV Cache 分成固定大小的 "Page"(类似操作系统内存分页)
请求A:按需分配 Page,用多少占多少
请求B:可以和请求A共享空闲 Page,无需等待

结果:同样的显存,vLLM 可以处理 3-10 倍的并发请求

同时,vLLM 使用 Continuous Batching(连续批处理):

bash 复制代码
传统批处理:等一批请求都准备好,一起处理
→ 短请求等长请求,资源浪费

连续批处理:请求完成即退出,新请求立即加入
→ GPU 利用率接近 100%

三、环境安装

3.1 硬件要求

模型 最低显存 推荐显存 推荐 GPU
Qwen3-7B(FP16) 16GB 24GB RTX 4090 / A100 40G
Qwen3-14B(FP16) 30GB 40GB A100 80G
DeepSeek V4-Flash(量化) 24GB 48GB A100 80G × 2
DeepSeek V4-Pro(量化) 80GB+ 160GB+ A100 80G × 4

3.2 安装 vLLM

bash 复制代码
# 创建虚拟环境
conda create -n vllm python=3.11
conda activate vllm

# 安装 vLLM(CUDA 12.1)
pip install vllm

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

# 验证 GPU 识别
python -c "import torch; print(torch.cuda.get_device_name(0))"
bash 复制代码
# 如果 pip 安装失败(网络问题),使用国内镜像
pip install vllm -i https://pypi.tuna.tsinghua.edu.cn/simple

四、启动 Qwen3 / DeepSeek V4 推理服务

4.1 基础启动命令

bash 复制代码
# 启动 Qwen3-7B 推理服务(OpenAI 兼容格式)
python -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen3-7B-Instruct \
    --served-model-name qwen3-7b \
    --host 0.0.0.0 \
    --port 8000 \
    --max-model-len 32768 \
    --tensor-parallel-size 1      # GPU 数量

# 启动后测试
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-7b",
    "messages": [{"role": "user", "content": "你好"}]
  }'

4.2 生产级启动配置

bash 复制代码
# 生产环境推荐配置(单 A100 80G)
python -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen3-14B-Instruct \
    --served-model-name qwen3-14b \
    --host 0.0.0.0 \
    --port 8000 \
    \
    # 显存与性能
    --max-model-len 65536 \              # 最大上下文长度
    --gpu-memory-utilization 0.90 \      # 显存利用率(留 10% 余量)
    --max-num-seqs 256 \                 # 最大并发序列数
    --max-num-batched-tokens 32768 \     # 最大批处理 token
    \
    # 量化(减少显存占用)
    --quantization awq \                 # AWQ 量化(精度损失小)
    \
    # 多 GPU
    --tensor-parallel-size 2 \           # 2 块 GPU 张量并行
    \
    # 其他
    --trust-remote-code \
    --disable-log-requests               # 生产环境关闭请求日志(减少IO)

4.3 多 GPU 张量并行

bash 复制代码
# 2 块 GPU 部署 Qwen3-32B
CUDA_VISIBLE_DEVICES=0,1 python -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen3-32B-Instruct \
    --tensor-parallel-size 2 \
    --gpu-memory-utilization 0.92

# 4 块 GPU 部署 DeepSeek V4-Flash 量化版
CUDA_VISIBLE_DEVICES=0,1,2,3 python -m vllm.entrypoints.openai.api_server \
    --model deepseek-ai/DeepSeek-V4-Flash \
    --tensor-parallel-size 4 \
    --quantization fp8 \
    --gpu-memory-utilization 0.88

五、量化选型:AWQ / GPTQ / FP8 / GGUF 对比

python 复制代码
# 各量化方案的显存节省与质量损失(以 Qwen3-14B 为基准)

量化方案对比 = {
    "FP16(原始)": {"显存": "28GB", "质量损失": "0%",  "速度": "基准"},
    "FP8":         {"显存": "14GB", "质量损失": "<1%", "速度": "快 20%"},
    "AWQ(INT4)": {"显存": "8GB",  "质量损失": "2-3%","速度": "快 30%"},
    "GPTQ(INT4)":{"显存": "8GB",  "质量损失": "3-5%","速度": "快 25%"},
}
bash 复制代码
# 使用 AWQ 量化模型(推荐)
# 1. 安装量化工具
pip install autoawq

# 2. 量化脚本
python -c "
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer

model_path = 'Qwen/Qwen3-14B-Instruct'
quant_path = './qwen3-14b-awq'

tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoAWQForCausalLM.from_pretrained(model_path)

quant_config = {
    'zero_point': True,
    'q_group_size': 128,
    'w_bit': 4,
    'version': 'GEMM'
}
model.quantize(tokenizer, quant_config=quant_config)
model.save_quantized(quant_path)
tokenizer.save_pretrained(quant_path)
print('量化完成!')
"

# 3. 启动量化模型
python -m vllm.entrypoints.openai.api_server \
    --model ./qwen3-14b-awq \
    --quantization awq \
    --gpu-memory-utilization 0.90

六、并发压测:用 locust 验证吞吐量

python 复制代码
# locustfile.py
from locust import HttpUser, task, between
import json, random

PROMPTS = [
    "用 Python 实现一个快速排序算法,带注释。",
    "解释什么是 Spring Boot 的自动装配原理。",
    "MySQL 索引的底层数据结构是什么?",
]

class LLMUser(HttpUser):
    wait_time = between(0.1, 0.5)

    @task
    def chat(self):
        payload = {
            "model": "qwen3-7b",
            "messages": [
                {"role": "user", "content": random.choice(PROMPTS)}
            ],
            "max_tokens": 512,
            "stream": False
        }
        with self.client.post(
            "/v1/chat/completions",
            json=payload,
            catch_response=True
        ) as resp:
            if resp.status_code == 200:
                data = resp.json()
                tokens = data["usage"]["completion_tokens"]
                resp.success()
            else:
                resp.failure(f"HTTP {resp.status_code}")
bash 复制代码
# 运行压测(100并发,持续60秒)
locust -f locustfile.py \
    --host http://localhost:8000 \
    --users 100 \
    --spawn-rate 10 \
    --run-time 60s \
    --headless \
    --csv results

# 查看结果
cat results_stats.csv

压测参考数据(RTX 4090,Qwen3-7B-AWQ):

并发数 平均延迟(TTFT) 吞吐(tokens/s) GPU 利用率
1 280ms 45 35%
10 350ms 380 78%
50 520ms 1850 94%
100 780ms 3200 98%

对比 Ollama 单并发约 45 tokens/s,vLLM 100 并发达到 3200 tokens/s,吞吐提升约 70 倍


七、Docker + K8s 部署

7.1 Dockerfile

dockerfile 复制代码
FROM nvidia/cuda:12.1-devel-ubuntu22.04

RUN apt-get update && apt-get install -y python3.11 python3-pip git && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app
RUN pip install vllm --no-cache-dir

# 启动脚本
COPY start.sh /app/start.sh
RUN chmod +x /app/start.sh

EXPOSE 8000
CMD ["/app/start.sh"]
bash 复制代码
# start.sh
#!/bin/bash
python -m vllm.entrypoints.openai.api_server \
    --model ${MODEL_NAME:-"Qwen/Qwen3-7B-Instruct"} \
    --served-model-name ${SERVED_MODEL_NAME:-"qwen3"} \
    --host 0.0.0.0 \
    --port 8000 \
    --gpu-memory-utilization ${GPU_MEMORY_UTIL:-0.90} \
    --max-model-len ${MAX_MODEL_LEN:-32768} \
    --tensor-parallel-size ${TENSOR_PARALLEL:-1}

7.2 K8s Deployment(含 GPU 资源限制)

yaml 复制代码
# vllm-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-qwen3
  namespace: ai-inference
spec:
  replicas: 2
  selector:
    matchLabels:
      app: vllm-qwen3
  template:
    metadata:
      labels:
        app: vllm-qwen3
    spec:
      containers:
      - name: vllm
        image: your-registry/vllm:latest
        ports:
        - containerPort: 8000
        env:
        - name: MODEL_NAME
          value: "Qwen/Qwen3-7B-Instruct"
        - name: GPU_MEMORY_UTIL
          value: "0.90"
        resources:
          limits:
            nvidia.com/gpu: 1           # 每个 Pod 使用 1 块 GPU
            memory: "32Gi"
          requests:
            nvidia.com/gpu: 1
            memory: "24Gi"
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 120      # 模型加载需要时间
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: /v1/models
            port: 8000
          initialDelaySeconds: 90
          periodSeconds: 10
      nodeSelector:
        accelerator: nvidia-gpu        # 只调度到 GPU 节点
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-service
  namespace: ai-inference
spec:
  selector:
    app: vllm-qwen3
  ports:
  - port: 80
    targetPort: 8000
  type: ClusterIP
---
# HPA:按 GPU 利用率自动扩缩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: vllm-hpa
  namespace: ai-inference
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-qwen3
  minReplicas: 1
  maxReplicas: 4
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

八、Prometheus 监控接入

vLLM 内置 Prometheus 指标端点(/metrics):

bash 复制代码
# vLLM 启动时开启 metrics
python -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen3-7B-Instruct \
    --port 8000 \
    --enable-metrics                   # 开启 /metrics 端点
yaml 复制代码
# prometheus 抓取配置
scrape_configs:
  - job_name: 'vllm'
    static_configs:
      - targets: ['vllm-service:8000']
    metrics_path: /metrics
yaml 复制代码
# Grafana 告警规则(alertmanager)
groups:
- name: vllm_alerts
  rules:
  - alert: VLLMHighLatency
    expr: vllm:e2e_request_latency_seconds_p99 > 5
    for: 2m
    annotations:
      summary: "vLLM P99 延迟超过 5 秒"

  - alert: VLLMQueueFull
    expr: vllm:num_requests_waiting > 100
    for: 1m
    annotations:
      summary: "vLLM 请求队列积压超过 100 个"

  - alert: VLLMGPUOOMRisk
    expr: vllm:gpu_cache_usage_perc > 95
    for: 30s
    annotations:
      summary: "GPU KV Cache 使用率超过 95%,有 OOM 风险"

关键监控指标说明:

指标名 含义 告警阈值建议
vllm:e2e_request_latency_seconds 端到端请求延迟 P99 > 5s 告警
vllm:num_requests_running 正在处理的请求数 > max_num_seqs * 0.9
vllm:num_requests_waiting 排队等待的请求数 > 50 告警,> 200 紧急
vllm:gpu_cache_usage_perc GPU KV Cache 使用率 > 90% 告警
vllm:tokens_per_second 推理吞吐 低于基准 50% 告警

总结

vLLM 是目前生产环境大模型推理的最优解,核心优势在于 PagedAttention + Continuous Batching 的组合,将 GPU 利用率从 Ollama 的 30-40% 提升到 95%+。

部署建议:

  1. 显存 < 24GB:使用 AWQ 量化,节省 50% 显存
  2. 多 GPU--tensor-parallel-size 设置等于 GPU 数量
  3. K8s 部署initialDelaySeconds 必须设够,模型加载慢
  4. 监控:GPU Cache 使用率是最关键指标,超过 90% 必须扩容
相关推荐
liuyunshengsir11 小时前
LMCache + vLLM 部署指南(以 Qwen3-0.6B 为例)
vllm
诸葛老刘12 小时前
在PC机上 使用docker vLLM镜像部署Qwen3-1.7B
docker·vllm
Soonyang Zhang2 天前
vllm分析(二)——http request的入口处理
人工智能·vllm·推理框架
xyhshen2 天前
如何两台atlas-a2服务器物理机,基于vllm-ascend部署qwen3.5 397b-w8a8-mtp大模型
vllm
zadyd2 天前
vLLM Linux 双卡部署大模型服务器指南
linux·人工智能·python·机器学习·vllm
是Dream呀9 天前
从零到一:Triton实现CELU激活函数优化之路
ai·vllm·openclaw
花间相见9 天前
【大模型推理01】—— 初探VLLM:高性能LLM推理引擎,让开源模型跑起来更快更省
开源·vllm
Flying pigs~~10 天前
大模型训练框架 ➕ 推理部署框架
模型训练·deepspeed·vllm·模型推理·zero·pageattention