从零部署千问模型(二):使用vLLM部署高性能推理服务

前言

上一篇中,我们完成了 Qwen 模型的环境搭建和基础验证。虽然 Transformers 库可以运行推理,但它的吞吐量低、不支持并发,无法满足生产环境需求。本文将使用 vLLM 框架部署高性能推理服务,它通过 PagedAttention、连续批处理等技术,将推理性能提升到原生 Transformers 的 数倍甚至数十倍

一、vLLM 简介

1.1 为什么选择 vLLM

  • PagedAttention:类似操作系统的虚拟内存管理,高效管理 KV Cache,减少显存碎片
  • 连续批处理(Continuous Batching):动态插入新请求,无需等待整个 batch 完成
  • 高吞吐量:单卡吞吐量可达 Transformers 的 10-24 倍
  • OpenAI 兼容 API:开箱即用,无需修改客户端代码
  • 支持量化:AWQ、GPTQ、INT8 等多种量化方案
  • 分布式推理:支持张量并行(Tensor Parallelism),多卡协同

1.2 vLLM vs 其他推理框架对比

特性vLLMText Generation InferenceOllamaTransformers
吞吐量⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
部署复杂度
OpenAI API 兼容
多卡支持
量化支持AWQ/GPTQ/INT8AWQ/GPTQ/EETQGGUF有限
适合场景生产环境生产环境个人/开发实验/测试

二、安装 vLLM

继续使用上一篇创建的 conda 环境:

conda activate qwen

# 安装 vLLM(推荐通过 pip 安装)
pip install vllm

# 验证安装
python -c "import vllm; print(f'vLLM version: {vllm.__version__}')"

如果遇到依赖冲突,可以创建全新的环境:

conda create -n vllm python=3.11 -y
conda activate vllm
pip install vllm

2.1 安装 AWQ 量化版模型(可选)

如果显存有限,可以下载 AWQ 量化版模型,显存占用减少约 60%:

# 下载 AWQ 量化版(以 Qwen3-8B-AWQ 为例)
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download Qwen/Qwen3-8B-AWQ --local-dir ./models/Qwen3-8B-AWQ

# 或者从 ModelScope 下载
modelscope download --model Qwen/Qwen3-8B-AWQ --local-dir ./models/Qwen3-8B-AWQ

三、启动推理服务

3.1 基本启动命令

python -m vllm.entrypoints.openai.api_server \
  --model ./models/Qwen3-8B \
  --served-model-name qwen3-8b \
  --host 0.0.0.0 \
  --port 8000 \
  --trust-remote-code \
  --gpu-memory-utilization 0.9 \
  --max-model-len 32768

参数说明:

  • --model:模型路径,可以是本地路径或 HuggingFace 模型 ID
  • --served-model-name:API 中使用的模型名称,客户端请求时用这个名字
  • --host 0.0.0.0:监听所有网卡,允许外部访问
  • --port 8000:服务端口
  • --gpu-memory-utilization 0.9:GPU 显存利用率上限,建议 0.85-0.95
  • --max-model-len 32768:最大上下文长度,按需调整,越大越占显存
  • --trust-remote-code:信任远程代码(Qwen 模型需要)

3.2 使用量化模型启动

python -m vllm.entrypoints.openai.api_server \
  --model ./models/Qwen3-8B-AWQ \
  --served-model-name qwen3-8b-awq \
  --host 0.0.0.0 \
  --port 8000 \
  --trust-remote-code \
  --quantization awq \
  --gpu-memory-utilization 0.9 \
  --max-model-len 32768

3.3 多卡张量并行

如果有多个 GPU,可以通过张量并行加速:

python -m vllm.entrypoints.openai.api_server \
  --model ./models/Qwen3-72B \
  --served-model-name qwen3-72b \
  --host 0.0.0.0 \
  --port 8000 \
  --trust-remote-code \
  --tensor-parallel-size 2 \
  --gpu-memory-utilization 0.9 \
  --max-model-len 32768

--tensor-parallel-size 2 表示使用 2 张 GPU 进行张量并行。注意 GPU 数量必须能被该值整除。

四、测试 API 服务

4.1 Chat Completions(对话补全)

curl -s http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-8b",
    "messages": [
      {"role": "system", "content": "你是一个运维专家。"},
      {"role": "user", "content": "如何查看 Linux 系统的内存使用情况?"}
    ],
    "temperature": 0.7,
    "max_tokens": 1024
  }' | python3 -m json.tool

预期输出:

{
  "id": "chat-abc123",
  "object": "chat.completion",
  "created": 1719500000,
  "model": "qwen3-8b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "在Linux系统中,有多种方式可以查看内存使用情况...\n\n1. free命令\n2. top/htop命令\n3. /proc/meminfo\n..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 25,
    "completion_tokens": 180,
    "total_tokens": 205
  }
}

4.2 流式输出(Streaming)

curl -s http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-8b",
    "messages": [
      {"role": "user", "content": "写一首关于运维的诗"}
    ],
    "stream": true,
    "max_tokens": 256
  }'

4.3 Function Calling(函数调用)

curl -s http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-8b",
    "messages": [
      {"role": "user", "content": "北京今天天气怎么样?"}
    ],
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "获取指定城市的天气",
          "parameters": {
            "type": "object",
            "properties": {
              "city": {"type": "string", "description": "城市名称"}
            },
            "required": ["city"]
          }
        }
      }
    ]
  }' | python3 -m json.tool

4.4 查看可用模型列表

curl -s http://localhost:8000/v1/models | python3 -m json.tool

五、生产环境配置

5.1 使用 Systemd 管理服务

sudo tee /etc/systemd/system/vllm-qwen.service > /dev/null << 'EOF'
[Unit]
Description=vLLM Qwen3-8B Inference Server
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/root
Environment="PATH=/root/miniconda3/envs/qwen/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
ExecStart=/root/miniconda3/envs/qwen/bin/python -m vllm.entrypoints.openai.api_server \
    --model /root/models/Qwen3-8B \
    --served-model-name qwen3-8b \
    --host 0.0.0.0 \
    --port 8000 \
    --trust-remote-code \
    --gpu-memory-utilization 0.9 \
    --max-model-len 32768
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable vllm-qwen
sudo systemctl start vllm-qwen

# 查看状态
sudo systemctl status vllm-qwen

# 查看日志
sudo journalctl -u vllm-qwen -f

5.2 Nginx 反向代理

sudo tee /etc/nginx/sites-available/vllm-api > /dev/null << 'EOF'
server {
    listen 80;
    server_name api.example.com;

    # 代理 vLLM API
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # SSE 流式输出支持
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 300s;
    }
}
EOF

sudo ln -s /etc/nginx/sites-available/vllm-api /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

5.3 Docker 部署

# 使用官方镜像
docker run -d \
  --name vllm-qwen \
  --gpus all \
  --ipc=host \
  -v /root/models/Qwen3-8B:/models/Qwen3-8B \
  -p 8000:8000 \
  vllm/vllm-openai:latest \
  --model /models/Qwen3-8B \
  --served-model-name qwen3-8b \
  --host 0.0.0.0 \
  --port 8000 \
  --trust-remote-code \
  --gpu-memory-utilization 0.9 \
  --max-model-len 32768

5.4 性能调优参数

参数说明推荐值
--gpu-memory-utilizationGPU 显存利用率上限0.85-0.95
--max-model-len最大上下文长度32768(按需)
--max-num-seqs最大并发序列数256(按 GPU 调整)
--tensor-parallel-size张量并行数GPU 数量
--swap-spaceCPU 交换空间(GB)4
--enforce-eager禁用 CUDA Graph(调试用)不加

六、性能基准测试

使用 vLLM 自带的基准测试工具评估性能:

# 在线服务基准测试
python -m vllm.entrypoints.openai.api_server \
  --model ./models/Qwen3-8B \
  --served-model-name qwen3-8b \
  --trust-remote-code &

# 等待服务启动后运行测试
benchmark_serving.py \
  --backend vllm \
  --base-url http://localhost:8000 \
  --model qwen3-8b \
  --dataset-name random \
  --num-prompts 1000 \
  --request-rate 10

典型 RTX 4090 + Qwen3-8B 性能参考:

指标TransformersvLLM提升倍数
吞吐量 (tokens/s)~50~200040x
首 token 延迟~200ms~50ms4x
并发支持1256+256x
显存利用率~60%~90%-

七、常见问题排查

7.1 OOM(显存不足)

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

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

# 减少并发数
--max-num-seqs 64

# 使用量化模型
--quantization awq

7.2 启动报错:模型不支持

# 确保添加 trust-remote-code 参数
--trust-remote-code

# 更新 vLLM 到最新版本
pip install vllm --upgrade

7.3 流式输出中断

如果通过 Nginx 代理出现流式输出中断,确保 Nginx 配置中关闭了缓冲:

proxy_buffering off;
proxy_cache off;
chunked_transfer_encoding on;

八、总结

本文使用 vLLM 部署了高性能 Qwen 推理服务,关键收获:

  • ✅ vLLM 相比 Transformers 吞吐量提升数十倍
  • ✅ 支持 OpenAI 兼容 API,客户端可无缝切换
  • ✅ 支持流式输出、Function Calling 等高级功能
  • ✅ 通过 Systemd/Nginx/Docker 实现生产级部署
  • ✅ 多卡张量并行支持大模型部署

下一篇将介绍使用 Ollama 快速部署千问模型——更简单的部署方式,适合个人开发和小规模使用场景。

参考资料

发表回复

后才能评论