vLLM Docker 本地部署小模型笔记
1. 目标
使用 Docker + vLLM 在本地服务器部署 Hugging Face 模型,并通过 OpenAI 兼容接口访问。
示例模型:
text
Qwen/Qwen3.6-27B
本地模型目录:
text
/data/models/Qwen3.6-27B
服务端口:
text
8000
模型服务名:
text
qwen3.6-27b
2. 创建模型目录
bash
sudo mkdir -p /data/models/Qwen3.6-27B
sudo chown -R opsadmin:opsadmin /data/models/Qwen3.6-27B
sudo chmod -R u+rwX /data/models/Qwen3.6-27B
检查目录:
bash
ls -ld /data/models/Qwen3.6-27B
3. 下载 Hugging Face 模型
推荐使用新版 hf 命令:
bash
hf download Qwen/Qwen3.6-27B \
--local-dir /data/models/Qwen3.6-27B
旧版也可以使用:
bash
huggingface-cli download \
Qwen/Qwen3.6-27B \
--local-dir /data/models/Qwen3.6-27B
如果下载过程中出现权限或缓存问题,可以清理:
bash
sudo rm -rf /data/models/Qwen3.6-27B/.cache
sudo chown -R opsadmin:opsadmin /data/models/Qwen3.6-27B
重新下载:
bash
hf download Qwen/Qwen3.6-27B \
--local-dir /data/models/Qwen3.6-27B
检查模型配置是否存在:
bash
ls -lh /data/models/Qwen3.6-27B/config.json
还可以检查模型权重:
bash
ls -lh /data/models/Qwen3.6-27B
4. 最简单的 vLLM Docker 部署
单卡部署:
bash
docker run -d \
--name qwen36-27b \
--gpus all \
--ipc=host \
--restart unless-stopped \
-p 8000:8000 \
-v /data/models/Qwen3.6-27B:/models/Qwen3.6-27B:ro \
vllm/vllm-openai:v0.25.1 \
/models/Qwen3.6-27B \
--host 0.0.0.0 \
--port 8000 \
--served-model-name qwen3.6-27b \
--tensor-parallel-size 1 \
--max-model-len 32768
这里最核心的是:
text
宿主机模型目录
/data/models/Qwen3.6-27B
↓
映射到容器
/models/Qwen3.6-27B
因此 vLLM 启动时指定:
bash
/models/Qwen3.6-27B
而不是宿主机路径。
5. 多 GPU 部署
如果模型需要多卡运行,可以调整:
bash
--tensor-parallel-size
例如两张 GPU:
bash
--tensor-parallel-size 2
8 张 GPU:
bash
--tensor-parallel-size 8
完整示例:
bash
docker run -d \
--name qwen36-27b \
--gpus all \
--ipc=host \
--restart unless-stopped \
-p 8000:8000 \
-v /data/models/Qwen3.6-27B:/models/Qwen3.6-27B:ro \
vllm/vllm-openai:v0.25.1 \
/models/Qwen3.6-27B \
--host 0.0.0.0 \
--port 8000 \
--served-model-name qwen3.6-27b \
--tensor-parallel-size 2 \
--max-model-len 32768
注意:
text
tensor-parallel-size <= 实际可用 GPU 数量
例如服务器只有两张卡,则不能配置:
bash
--tensor-parallel-size 8
6. 推荐生产参数
在基础配置上,可以增加一些常用优化参数:
bash
docker run -d \
--name qwen36-27b \
--gpus all \
--ipc=host \
--restart unless-stopped \
-p 8000:8000 \
-v /data/models/Qwen3.6-27B:/models/Qwen3.6-27B:ro \
-v ~/.cache/huggingface:/root/.cache/huggingface \
vllm/vllm-openai:v0.25.1 \
/models/Qwen3.6-27B \
--served-model-name qwen3.6-27b \
--host 0.0.0.0 \
--port 8000 \
--tensor-parallel-size 2 \
--dtype bfloat16 \
--max-model-len 32768 \
--gpu-memory-utilization 0.90 \
--max-num-seqs 8 \
--enable-prefix-caching \
--enable-chunked-prefill
参数说明:
text
--dtype bfloat16
模型使用 BF16 推理。
--max-model-len 32768
最大上下文长度 32768 token。
--gpu-memory-utilization 0.90
允许 vLLM 使用约 90% GPU 显存。
--max-num-seqs 8
最多同时处理 8 个 sequence。
--enable-prefix-caching
开启前缀缓存,相同 system prompt 或长公共上下文场景下可以提高性能。
--enable-chunked-prefill
长文本 Prefill 分块处理,降低一次性显存压力。
7. reasoning-parser
如果模型支持 reasoning 输出,并且当前 vLLM 版本支持对应 parser,可以增加:
bash
--reasoning-parser qwen3
例如:
bash
docker run -d \
--name qwen36-27b \
--gpus all \
--ipc=host \
--restart unless-stopped \
-p 8000:8000 \
-v /data/models/Qwen3.6-27B:/models/Qwen3.6-27B:ro \
vllm/vllm-openai:v0.25.1 \
/models/Qwen3.6-27B \
--served-model-name qwen3.6-27b \
--host 0.0.0.0 \
--port 8000 \
--tensor-parallel-size 2 \
--dtype bfloat16 \
--max-model-len 32768 \
--gpu-memory-utilization 0.90 \
--max-num-seqs 8 \
--enable-prefix-caching \
--enable-chunked-prefill \
--reasoning-parser qwen3
如果启动时报:
text
invalid choice
unknown reasoning parser
说明当前 vLLM 版本和模型的 parser 不匹配,可以先删除该参数。
8. Docker 镜像版本
不推荐长期直接使用:
bash
vllm/vllm-openai:latest
因为 latest 会随着官方更新变化,同一条命令以后可能得到不同运行结果。
建议锁定版本:
bash
vllm/vllm-openai:v0.25.1
生产环境原则:
text
模型版本固定
+
vLLM 版本固定
+
CUDA/Driver 环境固定
这样更容易复现和排查问题。
9. 查看容器状态
查看运行中的容器:
bash
docker ps
查看所有容器:
bash
docker ps -a
查看指定容器:
bash
docker ps -a | grep qwen36-27b
10. 查看启动日志
部署后第一件事建议查看日志:
bash
docker logs -f qwen36-27b
查看最后 200 行:
bash
docker logs --tail 200 qwen36-27b
常见需要关注的信息:
text
模型是否成功识别
GPU 数量
tensor parallel size
模型 dtype
最大上下文长度
KV Cache 大小
HTTP server 是否启动
是否出现 CUDA OOM
当看到类似:
text
Uvicorn running on http://0.0.0.0:8000
通常说明服务已经启动。
11. 测试模型列表接口
本机测试:
bash
curl http://127.0.0.1:8000/v1/models
详细请求信息:
bash
curl -v http://127.0.0.1:8000/v1/models
正常情况下应该返回类似:
json
{
"object": "list",
"data": [
{
"id": "qwen3.6-27b",
"object": "model"
}
]
}
其中:
text
id = --served-model-name
12. 测试 Chat Completion
bash
curl http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.6-27b",
"messages": [
{
"role": "user",
"content": "你好,请介绍一下你自己"
}
],
"temperature": 0.7,
"max_tokens": 512
}'
13. Python 调用
因为 vLLM 提供 OpenAI 兼容接口,可以直接使用 OpenAI Python SDK:
python
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:8000/v1",
api_key="EMPTY",
)
response = client.chat.completions.create(
model="qwen3.6-27b",
messages=[
{
"role": "user",
"content": "你好,请介绍一下你自己",
}
],
temperature=0.7,
max_tokens=512,
)
print(response.choices[0].message.content)
14. 外网访问测试
如果服务器 IP 为:
text
47.95.251.8
可以测试:
bash
curl http://47.95.251.8:8000/v1/models
如果本机可以访问:
bash
curl http://127.0.0.1:8000/v1/models
但外网访问失败,优先检查:
text
1. 云服务器安全组是否开放 8000
2. Linux 防火墙是否开放 8000
3. Docker 是否正确映射 -p 8000:8000
4. vLLM 是否使用 --host 0.0.0.0
5. 是否经过 Nginx 反向代理
15. 如果通过 Nginx 暴露服务
生产环境一般不建议直接暴露:
text
公网IP:8000
更推荐:
text
Client
↓
Nginx
↓
127.0.0.1:8000
↓
vLLM
例如:
nginx
location /v1/ {
proxy_pass http://127.0.0.1:8000/v1/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
之后:
bash
curl http://47.95.251.8/v1/models
16. 更新模型后的重新部署
先停止旧容器:
bash
docker stop qwen36-27b
删除旧容器:
bash
docker rm qwen36-27b
或者一步:
bash
docker rm -f qwen36-27b
再执行新的 docker run。
注意,同一个 Docker container name 不能重复创建。
如果看到:
text
Conflict. The container name "/qwen36-27b" is already in use
执行:
bash
docker rm -f qwen36-27b
然后重新启动。
17. 模型目录整体挂载与单模型挂载
有两种方式。
方式一:挂载整个模型目录:
bash
-v /data/models:/models
启动:
bash
/models/Qwen3.6-27B
优点:
text
一个 Docker 容器可以访问 /data/models 下所有模型。
缺点:
text
容器可以看到所有模型目录,权限范围较大。
方式二:只挂载单个模型:
bash
-v /data/models/Qwen3.6-27B:/models/Qwen3.6-27B:ro
优点:
text
权限更清晰
更适合生产
避免误操作其他模型
因此更推荐:
bash
-v /data/models/Qwen3.6-27B:/models/Qwen3.6-27B:ro
其中:
text
:ro
表示容器只读访问模型文件。
18. tensor-parallel-size 如何选择
一般按照模型大小和 GPU 显存决定。
例如:
text
单张大显存 GPU
--tensor-parallel-size 1
两张 GPU
--tensor-parallel-size 2
四张 GPU
--tensor-parallel-size 4
八张 GPU
--tensor-parallel-size 8
不是 GPU 越多就一定越快。
小模型如果单卡已经能放下,使用:
bash
--tensor-parallel-size 1
通常通信开销更低。
模型无法单卡放下时,再使用多卡 Tensor Parallel。
19. max-model-len 不要盲目调大
例如:
bash
--max-model-len 32768
会影响 KV Cache 显存需求。
上下文越长:
text
KV Cache 越大
显存占用越高
并发能力越低
如果业务实际只需要 8K,可以设置:
bash
--max-model-len 8192
如果需要 16K:
bash
--max-model-len 16384
不要因为模型支持 32K,就一定部署 32K。
对于生产服务,应该根据实际业务选择:
text
模型能力
+
最大输入长度
+
最大输出长度
+
并发量
+
显存大小
共同确定。
20. 显存不足时的调整顺序
如果出现:
text
CUDA out of memory
可以按照下面顺序降低压力。
首先降低并发:
bash
--max-num-seqs 4
然后降低最大上下文:
bash
--max-model-len 16384
再降低 GPU 内存利用率:
bash
--gpu-memory-utilization 0.85
或者增加 GPU 数量:
bash
--tensor-parallel-size 2
对于模型本身太大的情况,则需要考虑:
text
量化模型
AWQ
GPTQ
FP8
更多 GPU
更大显存 GPU
21. 推荐部署模板
以后部署普通 Hugging Face 小模型,可以直接基于下面模板修改:
bash
docker run -d \
--name MODEL_CONTAINER_NAME \
--gpus all \
--ipc=host \
--restart unless-stopped \
-p 8000:8000 \
-v /data/models/MODEL_NAME:/models/MODEL_NAME:ro \
vllm/vllm-openai:v0.25.1 \
/models/MODEL_NAME \
--host 0.0.0.0 \
--port 8000 \
--served-model-name SERVED_MODEL_NAME \
--tensor-parallel-size 1 \
--dtype bfloat16 \
--max-model-len 32768 \
--gpu-memory-utilization 0.90 \
--max-num-seqs 8 \
--enable-prefix-caching \
--enable-chunked-prefill
只需要修改:
text
MODEL_CONTAINER_NAME
MODEL_NAME
SERVED_MODEL_NAME
tensor-parallel-size
max-model-len
即可快速部署新模型。
22. Qwen3.6-27B 当前部署示例
最终可以整理成:
bash
docker rm -f qwen36-27b 2>/dev/null || true
docker run -d \
--name qwen36-27b \
--gpus all \
--ipc=host \
--restart unless-stopped \
-p 8000:8000 \
-v /data/models/Qwen3.6-27B:/models/Qwen3.6-27B:ro \
vllm/vllm-openai:v0.25.1 \
/models/Qwen3.6-27B \
--host 0.0.0.0 \
--port 8000 \
--served-model-name qwen3.6-27b \
--tensor-parallel-size 1 \
--dtype bfloat16 \
--max-model-len 32768 \
--gpu-memory-utilization 0.90 \
--max-num-seqs 8 \
--enable-prefix-caching \
--enable-chunked-prefill
启动后:
bash
docker logs -f qwen36-27b
服务正常后测试:
bash
curl http://127.0.0.1:8000/v1/models
再测试实际推理:
bash
curl http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.6-27b",
"messages": [
{
"role": "user",
"content": "你好"
}
],
"max_tokens": 256
}'
23. 整体部署流程
整个过程可以概括为:
text
Hugging Face
↓
下载模型
↓
/data/models/Qwen3.6-27B
↓
Docker Volume
↓
/models/Qwen3.6-27B
↓
vLLM
↓
OpenAI Compatible API
↓
http://127.0.0.1:8000/v1
↓
FastAPI / LangChain / Agent / Workflow
实际工作中,只要记住四个核心步骤:
text
1. 下载模型
2. 挂载模型目录
3. docker run 启动 vLLM
4. curl /v1/models 验证服务
之后所有 Python、LangChain、Agent、Workflow 服务都可以按照 OpenAI API 的方式调用该本地模型。