环境:Ubuntu 22.04 / 2× RTX 4090 48G / Docker / vLLM latest
模型:Qwen/Qwen3.8-27B-FP8(ModelScope 源)
目标:单节点 TP2 部署,开启 MTP Speculative Decoding,推理速度提升约 5 倍
一、前置:磁盘空间排查与清理
部署大模型前,先确保根分区有足够空间。本次根分区 /dev/sda2 一度达到 97%,需先定位并清理。
1.1 定位大目录
# 查看根目录下各一级目录占用
sudo du -sh /* 2>/dev/null | sort -rh | head -20
# 进一步定位
sudo du -sh /var/lib/* 2>/dev/null | sort -rh | head -20
发现:
/var/lib/containerd占用 215G/var/lib/docker占用 34G
1.2 清理 Docker 镜像
# 查看镜像占用
docker system df -v
# 删除悬空镜像/容器/缓存
docker system prune -a --volumes
# 手动删除不需要的大镜像(示例)
docker rmi lmsysorg/sglang:nightly-dev-cu13-20260321-94194537
docker rmi xprobe/xinference:latest
1.3 清理 containerd
# 查看镜像与容器
sudo ctr -n k8s.io image ls
sudo ctr containers ls
# 清理未使用镜像
sudo ctr image prune
# 如果用 Kubernetes,推荐用 crictl
sudo crictl rmi --prune
清理后效果:根分区从 97% 降至 72%,释放约 120G 空间。
二、Docker 环境准备:国内镜像加速
拉取 vllm/vllm-openai:latest 时,国内直连 Docker Hub 速度极慢,需配置加速器。
2.1 配置加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://mirror.ccs.tencentyun.com",
"https://dockerhub.icu",
"https://docker.1panel.live"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
阿里云用户建议登录 容器镜像服务 获取专属加速器地址,速度更快。
2.2 拉取镜像
docker pull vllm/vllm-openai:latest
三、模型下载(ModelScope)
Qwen3.8-27B-FP8 权重约 28GB,推荐下载到数据盘(如 /mnt/mydata)。
# 安装 modelscope
pip install modelscope
# 下载模型
modelscope download --model Qwen/Qwen3.8-27B-FP8 --local_dir /mnt/mydata/models/Qwen3.8-27B-FP8
验证:
ls /mnt/mydata/models/Qwen3.8-27B-FP8/config.json
四、vLLM 部署
4.1 最小可用启动命令(保底)
如果追求最快启动、不开启 MTP,可用以下命令:
sudo docker run -d \
--name vllm-qwen38-27b \
--gpus all \
--ipc=host \
-v /mnt/mydata/models/Qwen3.8-27B-FP8:/models \
-p 8099:8099 \
--env "VLLM_USE_MODELSCOPE=true" \
vllm/vllm-openai:latest \
--model /models \
--tensor-parallel-size 2 \
--max-model-len 262144 \
--kv-cache-dtype fp8 \
--gpu-memory-utilization 0.92 \
--served-model-name qwen3.8-27b-fp8 \
--port 8099 \
--enable-prefix-caching
4.2 生产级推荐启动命令(含 MTP 加速)
这是最终验证通过的配置,推理速度提升约 5 倍:
sudo docker run -d \
--name vllm-qwen38-27b \
--gpus all \
--ipc=host \
-v /mnt/mydata/models/Qwen3.8-27B-FP8:/models \
-v /mnt/mydata/.vllm_cache:/root/.cache/vllm \
-p 8099:8099 \
--env "VLLM_USE_MODELSCOPE=true" \
vllm/vllm-openai:latest \
--model /models \
--tensor-parallel-size 2 \
--max-model-len 262144 \
--kv-cache-dtype fp8 \
--reasoning-parser qwen3 \
--enable-auto-tool-choice \
--tool-call-parser qwen3_coder \
--gpu-memory-utilization 0.92 \
--served-model-name qwen3.8-27b-fp8 \
--port 8099 \
--enable-prefix-caching \
--enable-chunked-prefill \
--speculative-config '{"method":"mtp","num_speculative_tokens":3}'
关键参数说明:
| 参数 | 说明 |
|---|---|
--tensor-parallel-size 2 |
2 卡张量并行 |
--kv-cache-dtype fp8 |
KV Cache 使用 FP8,显著降低显存占用 |
--reasoning-parser qwen3 |
解析<think/> 标签,分离 reasoning_content |
--enable-auto-tool-choice |
自动工具选择 |
--tool-call-parser qwen3_coder |
Qwen3 工具调用解析器 |
--enable-prefix-caching |
前缀缓存,RAG/多轮场景复用系统提示 |
--enable-chunked-prefill |
长输入拆分与 decode 交错,降低排队 |
--speculative-config |
MTP 推测解码,利用模型自带的 MTP head 加速生成 |
-v /mnt/mydata/.vllm_cache:/root/.cache/vllm |
持久化 Triton 编译缓存,避免每次重启都重新编译 |
五、踩坑与解决
5.1 错误:unrecognized arguments: serve /models
原因:vllm/vllm-openai:latest 镜像的 ENTRYPOINT 本身就是 api_server,不需要再写 vllm serve。
错误写法:
vllm/vllm-openai:latest vllm serve /models ... # ❌ 错误
正确写法:
vllm/vllm-openai:latest --model /models ... # ✅ 正确
5.2 错误:unrecognized arguments: --num-scheduler-steps 8
原因:当前镜像版本不支持该参数。
解决:去掉 --num-scheduler-steps。
5.3 首次启动极慢(3-5 分钟)
现象:容器启动后 curl localhost:8099/v1/models 长时间无响应,日志卡在 torch.compile 或 shm_broadcast。
原因:vLLM 首次启动时需要为 4090 + FP8 + MTP 组合编译 Triton CUDA kernel(torch.compile 耗时约 140 秒)。
日志表现:
(Worker_TP0 pid=817) INFO ... torch.compile took 141.25 s in total
(EngineCore pid=708) INFO ... No available shared memory broadcast block found in 60 seconds.
解决:
- 耐心等待 —— 这是正常现象,编译完成后服务即可使用。
- 持久化缓存 —— 挂载
-v /mnt/mydata/.vllm_cache:/root/.cache/vllm,下次启动秒开。
5.4 显存占用看起来"不对"
TP2 下每卡显存约 16GB 是正常的:
- FP8 权重 ≈ 14GB/GPU
- 加上 embedding 层和 KV Cache 预留
并非显存泄漏,而是权重加载正确。
六、验证服务
6.1 查看模型列表
curl -s http://localhost:8099/v1/models | jq
6.2 基础对话(Thinking 模式,默认开启)
from openai import OpenAI
client = OpenAI(api_key="EMPTY", base_url="http://localhost:8099/v1")
resp = client.chat.completions.create(
model="qwen3.8-27b-fp8",
messages=[{"role": "user", "content": "用 Python 写个快速排序"}],
temperature=1.0,
top_p=0.95,
max_tokens=4096,
stream=True,
)
for chunk in resp:
if chunk.choices:
delta = chunk.choices[0].delta
if hasattr(delta, "reasoning_content") and delta.reasoning_content:
print(f"\033[90m{delta.reasoning_content}\033[0m", end="")
if delta.content:
print(delta.content, end="", flush=True)
6.3 关闭 Thinking(直接回答)
resp = client.chat.completions.create(
model="qwen3.8-27b-fp8",
messages=[{"role": "user", "content": "1+1=?"}],
temperature=0.7,
top_p=0.8,
extra_body={
"chat_template_kwargs": {"enable_thinking": False},
},
)
6.4 调整推理深度
extra_body={
"chat_template_kwargs": {
"enable_thinking": True,
"reasoning_effort": "low", # xhigh / medium / low
},
}
6.5 工具调用(自动)
启动参数已开启 --enable-auto-tool-choice,请求时:
resp = client.chat.completions.create(
model="qwen3.8-27b-fp8",
messages=[...],
tools=[...],
tool_choice="auto",
temperature=0.25,
max_tokens=4096,
extra_body={
"chat_template_kwargs": {"enable_thinking": False},
},
)
七、性能参考
| 指标 | 数值 |
|---|---|
| 硬件 | 2× RTX 4090 48G |
| 并行 | TP2 |
| 权重精度 | FP8 (block-wise, 128) |
| KV Cache | FP8 |
| 加速技术 | MTP Speculative Decoding (3 tokens) |
| 推理速度提升 | 约 5 倍(相比无 MTP) |
| 10K-20K 输入首 token 延迟 | 约 8-12 秒(4090 物理上限) |
| 每卡显存占用 | ~16 GB |
| 原生上下文长度 | 262,144 tokens |
八、附录:常用运维命令
# 查看容器日志
docker logs -f vllm-qwen38-27b
# 查看容器状态
docker ps -a | grep vllm
# 查看 GPU 占用
watch -n 1 nvidia-smi
# 停止服务
docker stop vllm-qwen38-27b
# 删除容器(保留镜像)
docker rm -f vllm-qwen38-27b
# 查看端口映射
docker port vllm-qwen38-27b
总结:Qwen3.8-27B-FP8 在 4090 TP2 上部署完全可行,核心在于开启 FP8 KV Cache + MTP Speculative Decoding,并注意首次启动的 Triton 编译耗时。通过挂载缓存目录,可实现后续秒级启动。