vLLM Docker 本地部署小模型笔记

1. 目标

使用 Docker + vLLM 在本地服务器部署 Hugging Face 模型,并通过 OpenAI 兼容接口访问。

示例模型:

Qwen/Qwen3.6-27B

本地模型目录:

/data/models/Qwen3.6-27B

服务端口:

8000

模型服务名:

qwen3.6-27b

2. 创建模型目录

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

检查目录:

ls -ld /data/models/Qwen3.6-27B

3. 下载 Hugging Face 模型

推荐使用新版 hf 命令:

hf download Qwen/Qwen3.6-27B \
  --local-dir /data/models/Qwen3.6-27B

旧版也可以使用:

huggingface-cli download \
  Qwen/Qwen3.6-27B \
  --local-dir /data/models/Qwen3.6-27B

如果下载过程中出现权限或缓存问题,可以清理:

sudo rm -rf /data/models/Qwen3.6-27B/.cache
sudo chown -R opsadmin:opsadmin /data/models/Qwen3.6-27B

重新下载:

hf download Qwen/Qwen3.6-27B \
  --local-dir /data/models/Qwen3.6-27B

检查模型配置是否存在:

ls -lh /data/models/Qwen3.6-27B/config.json

还可以检查模型权重:

ls -lh /data/models/Qwen3.6-27B

4. 最简单的 vLLM Docker 部署

单卡部署:

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

这里最核心的是:

宿主机模型目录
/data/models/Qwen3.6-27B

↓

映射到容器

/models/Qwen3.6-27B

因此 vLLM 启动时指定:

/models/Qwen3.6-27B

而不是宿主机路径。

5. 多 GPU 部署

如果模型需要多卡运行,可以调整:

--tensor-parallel-size

例如两张 GPU:

--tensor-parallel-size 2

8 张 GPU:

--tensor-parallel-size 8

完整示例:

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

注意:

tensor-parallel-size <= 实际可用 GPU 数量

例如服务器只有两张卡,则不能配置:

--tensor-parallel-size 8

6. 推荐生产参数

在基础配置上,可以增加一些常用优化参数:

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

参数说明:

--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,可以增加:

--reasoning-parser qwen3

例如:

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

如果启动时报:

invalid choice
unknown reasoning parser

说明当前 vLLM 版本和模型的 parser 不匹配,可以先删除该参数。

8. Docker 镜像版本

不推荐长期直接使用:

vllm/vllm-openai:latest

因为 latest 会随着官方更新变化,同一条命令以后可能得到不同运行结果。

建议锁定版本:

vllm/vllm-openai:v0.25.1

生产环境原则:

模型版本固定
+
vLLM 版本固定
+
CUDA/Driver 环境固定

这样更容易复现和排查问题。

9. 查看容器状态

查看运行中的容器:

docker ps

查看所有容器:

docker ps -a

查看指定容器:

docker ps -a | grep qwen36-27b

10. 查看启动日志

部署后第一件事建议查看日志:

docker logs -f qwen36-27b

查看最后 200 行:

docker logs --tail 200 qwen36-27b

常见需要关注的信息:

模型是否成功识别
GPU 数量
tensor parallel size
模型 dtype
最大上下文长度
KV Cache 大小
HTTP server 是否启动
是否出现 CUDA OOM

当看到类似:

Uvicorn running on http://0.0.0.0:8000

通常说明服务已经启动。

11. 测试模型列表接口

本机测试:

curl http://127.0.0.1:8000/v1/models

详细请求信息:

curl -v http://127.0.0.1:8000/v1/models

正常情况下应该返回类似:

{
  "object": "list",
  "data": [
    {
      "id": "qwen3.6-27b",
      "object": "model"
    }
  ]
}

其中:

id = --served-model-name

12. 测试 Chat Completion

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:

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 为:

47.95.251.8

可以测试:

curl http://47.95.251.8:8000/v1/models

如果本机可以访问:

curl http://127.0.0.1:8000/v1/models

但外网访问失败,优先检查:

1. 云服务器安全组是否开放 8000
2. Linux 防火墙是否开放 8000
3. Docker 是否正确映射 -p 8000:8000
4. vLLM 是否使用 --host 0.0.0.0
5. 是否经过 Nginx 反向代理

15. 如果通过 Nginx 暴露服务

生产环境一般不建议直接暴露:

公网IP:8000

更推荐:

Client
  ↓
Nginx
  ↓
127.0.0.1:8000
  ↓
vLLM

例如:

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;
}

之后:

curl http://47.95.251.8/v1/models

16. 更新模型后的重新部署

先停止旧容器:

docker stop qwen36-27b

删除旧容器:

docker rm qwen36-27b

或者一步:

docker rm -f qwen36-27b

再执行新的 docker run

注意,同一个 Docker container name 不能重复创建。

如果看到:

Conflict. The container name "/qwen36-27b" is already in use

执行:

docker rm -f qwen36-27b

然后重新启动。

17. 模型目录整体挂载与单模型挂载

有两种方式。

方式一:挂载整个模型目录:

-v /data/models:/models

启动:

/models/Qwen3.6-27B

优点:

一个 Docker 容器可以访问 /data/models 下所有模型。

缺点:

容器可以看到所有模型目录,权限范围较大。

方式二:只挂载单个模型:

-v /data/models/Qwen3.6-27B:/models/Qwen3.6-27B:ro

优点:

权限更清晰
更适合生产
避免误操作其他模型

因此更推荐:

-v /data/models/Qwen3.6-27B:/models/Qwen3.6-27B:ro

其中:

:ro

表示容器只读访问模型文件。

18. tensor-parallel-size 如何选择

一般按照模型大小和 GPU 显存决定。

例如:

单张大显存 GPU
--tensor-parallel-size 1

两张 GPU
--tensor-parallel-size 2

四张 GPU
--tensor-parallel-size 4

八张 GPU
--tensor-parallel-size 8

不是 GPU 越多就一定越快。

小模型如果单卡已经能放下,使用:

--tensor-parallel-size 1

通常通信开销更低。

模型无法单卡放下时,再使用多卡 Tensor Parallel。

19. max-model-len 不要盲目调大

例如:

--max-model-len 32768

会影响 KV Cache 显存需求。

上下文越长:

KV Cache 越大
显存占用越高
并发能力越低

如果业务实际只需要 8K,可以设置:

--max-model-len 8192

如果需要 16K:

--max-model-len 16384

不要因为模型支持 32K,就一定部署 32K。

对于生产服务,应该根据实际业务选择:

模型能力
+
最大输入长度
+
最大输出长度
+
并发量
+
显存大小

共同确定。

20. 显存不足时的调整顺序

如果出现:

CUDA out of memory

可以按照下面顺序降低压力。

首先降低并发:

--max-num-seqs 4

然后降低最大上下文:

--max-model-len 16384

再降低 GPU 内存利用率:

--gpu-memory-utilization 0.85

或者增加 GPU 数量:

--tensor-parallel-size 2

对于模型本身太大的情况,则需要考虑:

量化模型
AWQ
GPTQ
FP8
更多 GPU
更大显存 GPU

21. 推荐部署模板

以后部署普通 Hugging Face 小模型,可以直接基于下面模板修改:

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

只需要修改:

MODEL_CONTAINER_NAME
MODEL_NAME
SERVED_MODEL_NAME
tensor-parallel-size
max-model-len

即可快速部署新模型。

22. Qwen3.6-27B 当前部署示例

最终可以整理成:

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

启动后:

docker logs -f qwen36-27b

服务正常后测试:

curl http://127.0.0.1:8000/v1/models

再测试实际推理:

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. 整体部署流程

整个过程可以概括为:

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

实际工作中,只要记住四个核心步骤:

1. 下载模型
2. 挂载模型目录
3. docker run 启动 vLLM
4. curl /v1/models 验证服务

之后所有 Python、LangChain、Agent、Workflow 服务都可以按照 OpenAI API 的方式调用该本地模型。

更多推荐