从零部署千问模型(二):使用vLLM部署高性能推理服务
前言
在上一篇《从零部署千问模型(一):Qwen模型简介与环境准备》中,我们完成了环境搭建和模型下载。本文将使用 vLLM 框架部署高性能推理服务,它支持连续批处理(Continuous Batching)、PagedAttention 内存优化和 OpenAI 兼容 API,是目前生产环境部署大模型的首选方案。
一、vLLM 简介
vLLM 是加州大学伯克利分校开源的高性能 LLM 推理引擎,核心优势包括:
- PagedAttention:灵感来自操作系统的虚拟内存分页,将 KV Cache 分成固定大小的块(block),按需分配,显存利用率提升 60% 以上
- 连续批处理:动态将多个请求合并处理,无需等待同一批次全部完成,吞吐量提升 2-4 倍
- OpenAI 兼容 API:开箱即用的 /v1/chat/completions 接口,可直接对接现有应用
- 量化推理:支持 AWQ、GPTQ、FP8 等多种量化方案
- 张量并行:支持多 GPU 并行推理
二、安装 vLLM
确保已激活上一篇创建的 Conda 环境:
conda activate qwen
安装 vLLM(会自动安装依赖):
pip install vllm
如果安装过程中遇到编译问题,可以尝试指定 CUDA 版本:
pip install vllm --extra-index-url https://download.pytorch.org/whl/cu124
验证安装:
python -c "import vllm; print(f'vLLM version: {vllm.__version__}')"'
预期输出:
vLLM version: 0.6.x
三、启动推理服务
3.1 基础启动命令
vllm serve ./models/Qwen3-8B \
--model ./models/Qwen3-8B \
--served-model-name qwen3-8b \
--host 0.0.0.0 \
--port 8000 \
--trust-remote-code
参数说明:
--model:模型文件路径--served-model-name:API 中使用的模型名称(客户端调用时使用)--host 0.0.0.0:监听所有网卡,允许外部访问--port 8000:服务端口--trust-remote-code:信任远程代码(Qwen 模型需要)
看到类似以下输出说明启动成功:
INFO 06-23 10:00:00 api_server.py:200] vLLM API server started on http://0.0.0.0:8000
INFO 06-23 10:00:00 api_server.py:201] Documentation: http://0.0.0.0:8000/docs
INFO 06-23 10:00:00 api_server.py:202] Metrics: http://0.0.0.0:8000/metrics
3.2 高级参数配置
针对不同场景,可以调整以下关键参数:
vllm serve ./models/Qwen3-8B \
--served-model-name qwen3-8b \
--host 0.0.0.0 \
--port 8000 \
--trust-remote-code \
--dtype bfloat16 \
--gpu-memory-utilization 0.90 \
--max-model-len 32768 \
--tensor-parallel-size 1 \
--enforce-eager
| 参数 | 说明 | 推荐值 |
|---|---|---|
| --dtype | 数据类型 | bfloat16(A100/H100)或 float16 |
| --gpu-memory-utilization | GPU 显存使用比例 | 0.85-0.95 |
| --max-model-len | 最大上下文长度 | 32768(根据显存调整) |
| --tensor-parallel-size | 张量并行 GPU 数 | 1(单卡)/ 2(双卡) |
| --enforce-eager | 禁用 CUDA Graph(省显存) | 显存紧张时添加 |
| --quantization | 量化方案 | awq / gptq / fp8 |
| --max-num-seqs | 最大并发序列数 | 128-256 |
3.3 使用量化模型(节省显存)
如果显存不足,可以使用 AWQ 量化版本,显存占用减少约 50%:
# 下载 AWQ 量化版本
modelscope download --model Qwen/Qwen3-8B-AWQ --local-dir ./models/Qwen3-8B-AWQ
# 启动量化模型
vllm serve ./models/Qwen3-8B-AWQ \
--served-model-name qwen3-8b-awq \
--host 0.0.0.0 \
--port 8000 \
--trust-remote-code \
--quantization awq
四、测试 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系统CPU使用率?"}
],
"temperature": 0.7,
"max_tokens": 512
}' | python3 -m json.tool
预期返回:
{
"id": "chat-abc123",
"object": "chat.completion",
"created": 1719500000,
"model": "qwen3-8b",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "可以使用以下命令查看Linux系统CPU使用率:\n\n1. top命令:实时显示系统进程和资源使用情况\n2. htop命令:top的增强版,更直观\n3. mpstat命令:查看多核CPU使用情况\n4. sar命令:历史CPU使用率记录\n\n最常用的是 top 命令..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 30,
"completion_tokens": 128,
"total_tokens": 158
}
}
4.2 流式输出(Streaming)
curl -s http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-8b",
"messages": [
{"role": "user", "content": "写一个Python快排算法"}
],
"stream": true,
"max_tokens": 1024
}'
响应将以 SSE(Server-Sent Events)格式逐 token 返回:
data: {"id":"chat-abc","object":"chat.completion.chunk","choices":[{"delta":{"content":"def"},"index":0}]}
data: {"id":"chat-abc","object":"chat.completion.chunk","choices":[{"delta":{"content":" quick"},"index":0}]}
data: {"id":"chat-abc","object":"chat.completion.chunk","choices":[{"delta":{"content":"sort"},"index":0}]}
data: [DONE]
4.3 Python SDK 调用
vLLM 完全兼容 OpenAI Python SDK,直接安装即可:
pip install openai
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed" # vLLM 默认不需要 API Key
)
# 普通对话
response = client.chat.completions.create(
model="qwen3-8b",
messages=[
{"role": "system", "content": "你是一个Python编程专家。"},
{"role": "user", "content": "解释一下Python中的装饰器"}
],
temperature=0.7,
max_tokens=512
)
print(response.choices[0].message.content)
# 流式对话
print("\n--- 流式输出 ---")
stream = client.chat.completions.create(
model="qwen3-8b",
messages=[{"role": "user", "content": "写一首关于运维的诗"}],
stream=True,
max_tokens=256
)
for chunk in stream:
content = chunk.choices[0].delta.content
if content:
print(content, end="", flush=True)
print()
五、Function Calling(工具调用)
Qwen3 原生支持 Function Calling,vLLM 也完整支持这一功能:
from openai import OpenAI
import json
client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")
# 定义工具函数
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
}
]
# 第一轮对话:模型决定调用工具
response = client.chat.completions.create(
model="qwen3-8b",
messages=[{"role": "user", "content": "北京今天天气怎么样?"}],
tools=tools
)
tool_call = response.choices[0].message.tool_calls[0]
print(f"模型请求调用: {tool_call.function.name}")
print(f"参数: {tool_call.function.arguments}")
# 模拟工具执行结果
weather_result = json.dumps({"city": "北京", "temp": "28°C", "condition": "晴"})
# 第二轮对话:将工具结果返回给模型
response2 = client.chat.completions.create(
model="qwen3-8b",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"},
response.choices[0].message,
{"role": "tool", "tool_call_id": tool_call.id, "content": weather_result}
],
tools=tools
)
print(f"\n最终回复: {response2.choices[0].message.content}")
六、生产环境配置
6.1 使用 Systemd 管理服务
sudo tee /etc/systemd/system/vllm-qwen.service > /dev/null << 'EOF'
[Unit]
Description=vLLM Qwen3-8B Service
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:/sbin:/bin"
ExecStart=/root/miniconda3/envs/qwen/bin/vllm serve /root/models/Qwen3-8B \
--served-model-name qwen3-8b \
--host 0.0.0.0 \
--port 8000 \
--trust-remote-code \
--gpu-memory-utilization 0.90 \
--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
# 查看日志
journalctl -u vllm-qwen -f
6.2 Nginx 反向代理 + HTTPS
sudo tee /etc/nginx/sites-available/vllm-api > /dev/null << 'EOF'
server {
listen 443 ssl;
server_name llm.example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
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 -sf /etc/nginx/sites-available/vllm-api /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
6.3 性能压测
使用 vLLM 自带的基准测试工具评估性能:
# 安装压测工具
pip install datasets
# 运行基准测试
python -m vllm.entrypoints.openai.bench_serving \
--backend vllm \
--base-url http://localhost:8000 \
--model qwen3-8b \
--num-prompts 100 \
--request-rate 10
关注以下指标:
- Throughput (tokens/s):每秒生成的 token 数,越高越好
- TTFT (Time To First Token):首 token 延迟,越低越好
- ITL (Inter-Token Latency):token 间延迟
七、常见问题排查
Q1:OOM(显存不足)
- 降低
--gpu-memory-utilization(如 0.80) - 减小
--max-model-len(如 8192) - 使用 AWQ/GPTQ 量化版本
- 添加
--enforce-eager禁用 CUDA Graph - 减小
--max-num-seqs(如 64)
Q2:启动报错 trust-remote-code
# 确保添加了该参数
--trust-remote-code
# 或者升级 transformers
pip install --upgrade transformers
Q3:流式输出中断
检查 Nginx 配置中是否关闭了缓冲:proxy_buffering off;,并增大超时时间 proxy_read_timeout 300s;。
八、总结
本文使用 vLLM 成功部署了 Qwen3-8B 高性能推理服务,核心收获:
- ✅ 理解了 vLLM 的核心优势(PagedAttention、连续批处理)
- ✅ 掌握了 vLLM 的安装与服务启动
- ✅ 学会了 OpenAI 兼容 API 的调用方式(curl + Python SDK)
- ✅ 实现了 Function Calling 工具调用
- ✅ 配置了 Systemd 服务管理和 Nginx 反向代理
下一篇将介绍使用 Ollama 快速部署千问模型,适合个人开发者和轻量场景,一键拉取模型、自动管理,更加简单易用。
参考资料
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。







