环境: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.

解决:

  1. 耐心等待 —— 这是正常现象,编译完成后服务即可使用。
  2. 持久化缓存 —— 挂载 -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 编译耗时。通过挂载缓存目录,可实现后续秒级启动。