vLLM 部署大模型服务实操:从 0 到 1 搭建 OpenAI 兼容 API
搞大模型部署的人大概都踩过这个坑:模型加载慢、推理吞吐上不去、想接 LangChain 还得自己写适配层。vLLM 这个库说白了就是来解决这些问题的------它把推理引擎和 OpenAI 兼容 API 打包好了,一条命令就能起服务。
本文以部署 Sinong1.0-8B(基于 Qwen3-8B 微调的农业大模型)为例,把完整的部署流程、API 调用、避坑经验都捋一遍。
一、vLLM 到底解决了什么问题
先说结论:如果你需要把一个开源大模型部署成 API 服务给别人用,vLLM 基本是目前最省心的选择。
它干了几件事:
- PagedAttention:显存管理从"一次性分配"变成"按需分页",同样的卡能跑更大的 batch
- 连续批处理:不用等一个请求处理完再接下一个,吞吐量直接翻倍
- OpenAI 兼容 API :
/v1/chat/completions接口和 OpenAI 一模一样,LangChain、前端直接对接,不用改代码 - 流式输出:原生支持 SSE 流式响应,前端做打字机效果很自然
对比自己用 FastAPI 包一层 transformers 的方案,vLLM 的推理速度快 5-10 倍是正常的。
二、环境要求
| 组件 | 最低版本 | 推荐版本 | 说明 |
|---|---|---|---|
| NVIDIA 驱动 | 525+ | 535+ | nvidia-smi 确认 |
| CUDA | 11.8 | 12.1+ | nvcc --version 确认 |
| Python | 3.9 | 3.10/3.11 | 3.12 可能有兼容问题 |
| vLLM | 0.8.5 | 0.8.5+ | 支持 Qwen3ForCausalLM 架构 |
| GPU 显存 | 16GB | 24GB+ | 8B 模型 bfloat16 至少 16GB |
🔴 重点 :vLLM 版本很重要。0.8.5 以下对 Qwen3 架构支持不完整,会报 trust_remote_code 相关错误。
三、安装
bash
# 创建虚拟环境(推荐)
conda create -n vllm python=3.10 -y
conda activate vllm
# 安装 vLLM
pip install vllm>=0.8.5
# 如果需要本地加载模型,也装上 transformers
pip install transformers>=4.51.0 safetensors>=0.4.0 accelerate>=0.27.0
验证安装:
bash
python -c "import vllm; print(vllm.__version__)"
✅ 成功标志:输出版本号,无报错。
四、启动服务
4.1 最简启动
bash
vllm serve /path/to/your/model
就这么简单。服务默认监听 http://localhost:8000,实现了 OpenAI 兼容的 API。
4.2 生产环境推荐配置
bash
vllm serve /data/models/Sinong1.0-8B \
--host 0.0.0.0 \
--port 8000 \
--gpu-memory-utilization 0.9 \
--max-model-len 40960 \
--dtype bfloat16 \
--trust-remote-code \
--enable-reasoning \
--reasoning-parser deepseek_r1
参数拆解:
| 参数 | 作用 | 建议值 |
|---|---|---|
--host 0.0.0.0 |
允许外部访问 | 生产环境必加 |
--gpu-memory-utilization |
显存利用率 | 0.85-0.9,留点余量 |
--max-model-len |
最大上下文长度 | 根据模型和显存定,40960 是 Qwen3 默认 |
--dtype bfloat16 |
数据类型 | A100/4090 用 bfloat16,V100 用 float16 |
--trust-remote-code |
允许自定义代码 | 微调模型通常需要 |
--enable-reasoning |
启用推理模式 | Qwen3 默认开启,可输出思考过程 |
--reasoning-parser |
推理解析器 | Qwen3 用 deepseek_r1 |
⚠️ 注意 :--max-model-len 不能超过模型 config.json 中的 max_position_embeddings。Sinong1.0-8B 这个值是 40960,设大了会报错。
4.3 多卡部署
2 张卡做张量并行:
bash
vllm serve /data/models/Sinong1.0-8B \
--tensor-parallel-size 2 \
--host 0.0.0.0 \
--port 8000
✅ 成功标志:日志中看到 Tensor Parallel size: 2,两张卡的显存都被占用。
4.4 Docker 部署
写个 Dockerfile:
dockerfile
FROM vllm/vllm-openai:latest
# 复制启动脚本
COPY start_vllm.sh /app/
RUN chmod +x /app/start_vllm.sh
# 模型通过 volume 挂载,不打包进镜像
VOLUME ["/app/models"]
EXPOSE 8000
ENTRYPOINT ["/app/start_vllm.sh"]
启动脚本 start_vllm.sh:
bash
#!/bin/bash
MODEL_PATH="${1:-/app/models/Sinong1.0-8B}"
PORT="${2:-8000}"
TP_SIZE="${3:-1}"
vllm serve "${MODEL_PATH}" \
--host 0.0.0.0 \
--port "${PORT}" \
--tensor-parallel-size "${TP_SIZE}" \
--gpu-memory-utilization 0.9 \
--max-model-len 40960 \
--dtype bfloat16 \
--trust-remote-code \
--enable-reasoning \
--reasoning-parser deepseek_r1
docker-compose.yml:
yaml
version: "3.8"
services:
sinong-vllm:
build: .
container_name: sinong-vllm
ports:
- "8000:8000"
volumes:
- /data/models/Sinong1.0-8B:/app/models/Sinong1.0-8B:ro
command: ["/app/models/Sinong1.0-8B", "8000", "1"]
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
restart: unless-stopped
bash
docker compose up -d --build
五、API 接口
服务起来之后,能用的接口就这几个:
5.1 健康检查
bash
curl http://localhost:8000/health
5.2 列出模型
bash
curl http://localhost:8000/v1/models
5.3 聊天补全(非流式)
bash
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Sinong1.0-8B",
"messages": [
{"role": "system", "content": "你是农业智能助手"},
{"role": "user", "content": "小麦赤霉病怎么防治?"}
],
"max_tokens": 512,
"temperature": 0.6
}'
5.4 聊天补全(流式)
bash
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Sinong1.0-8B",
"messages": [{"role": "user", "content": "介绍水稻种植流程"}],
"stream": true
}'
流式响应是 SSE 格式,每行一个 data: 块,最后以 data: [DONE] 结束。
5.5 关闭思考模式
Qwen3 系列默认开启推理模式(thinking),会先输出一段思考过程再给答案。如果不需要,可以在 system prompt 里加 /no_think:
json
{
"messages": [
{"role": "system", "content": "你是农业智能助手。/no_think"},
{"role": "user", "content": "你好"}
]
}
六、LangChain / LangGraph 集成
vLLM 的 API 和 OpenAI 完全兼容,所以直接用 ChatOpenAI 就行:
python
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="Sinong1.0-8B",
base_url="http://localhost:8000/v1",
api_key="not-needed", # 没设 --api-key 就随便填
temperature=0.6,
max_tokens=2048,
streaming=True,
)
# 直接调用
response = llm.invoke("小麦赤霉病怎么防治?")
print(response.content)
# 流式调用
for chunk in llm.stream("介绍水稻种植流程"):
print(chunk.content, end="", flush=True)
接入 LangGraph 也一样,把 ChatOpenAI 实例传给 create_react_agent 就完事了。
七、常见问题排查
7.1 显存不足 (CUDA out of memory)
现象 :启动时报 CUDA out of memory 或推理时 OOM。
原因 :--gpu-memory-utilization 设太高,或者 --max-model-len 超出显存承受范围。
解决:
bash
# 降低显存利用率
vllm serve /path/to/model --gpu-memory-utilization 0.8
# 减少上下文长度
vllm serve /path/to/model --max-model-len 16384
7.2 模型加载卡住不动
现象 :日志停在 Loading model... 不动了。
原因:模型文件太大,首次加载需要时间;或者网络问题导致权重下载中断。
解决:
- ��地模型确认文件完整:
ls -la /path/to/model/*.safetensors - HuggingFace 模型确认网络通畅
- 大模型(70B+)加载可能需要 5-10 分钟,耐心等
7.3 端口被占用
现象 :Address already in use。
解决:
bash
# 找到占用端口的进程
lsof -i :8000
# 终止它
kill -9 <PID>
# 或者换个端口
vllm serve /path/to/model --port 8001
7.4 trust_remote_code 报错
现象 :ValueError: ... requires you to execute the configuration file ...
原因:微调模型通常有自定义代码,需要显式允许。
解决 :加上 --trust-remote-code 参数。
7.5 流式响应前端收不到
现象:curl 测试正常,但前端收不到流式数据。
原因:Nginx 或反向代理默认会缓冲响应。
解决:Nginx 配置加上:
nginx
location /v1/ {
proxy_buffering off;
proxy_cache off;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
}
八、总结
几条核心经验:
- vLLM 版本要够新:Qwen3 架构至少 0.8.5
- 显存留余量 :
gpu-memory-utilization别拉满,0.85-0.9 比较稳 --trust-remote-code几乎必加:微调模型基本都需要- Docker 部署最省心:模型挂载 volume,镜像只装推理引擎
- 流式输出注意代理配置:Nginx 要关 buffer
验证清单
-
nvidia-smi正常显示 GPU -
python -c "import vllm"无报错 -
curl http://localhost:8000/health返回正常 -
curl http://localhost:8000/v1/models列出模型 - 非流式请求返回完整回复
- 流式请求逐 chunk 返回
- LangChain
ChatOpenAI能正常调用