本文整理一套 vLLM 模型服务上线前的最小压测检查。场景是:GPU 服务器上跑 vllm/vllm-openai,对外提供 OpenAI-compatible API,准备接内部知识库、代码助手或 Agent 网关。单人 Demo 正常,但上线前需要确认镜像、GPU runtime、模型缓存、冷启动和并发基线。

1. 示例环境

组件 示例
OS Ubuntu 22.04 / Debian 12 / Rocky Linux 9
容器运行时 Docker Engine
GPU 组件 NVIDIA Driver + NVIDIA Container Toolkit
推理服务 vllm/vllm-openai:latest
模型目录 /mnt/models/Qwen3-32B
缓存目录 /data/vllm-cache
压测工具 k6

先记录环境信息:

uname -a
cat /etc/os-release
docker version
nvidia-smi
nvidia-smi --query-gpu=name,driver_version,memory.total --format=csv

2. Docker 镜像单独验证

不要直接 docker compose up。先把镜像拉取和服务启动拆开。

docker pull vllm/vllm-openai:latest
docker image inspect vllm/vllm-openai:latest --format '{{.Id}} {{.Size}}'
docker image inspect vllm/vllm-openai:latest --format '{{json .RepoDigests}}'

验证 Python 和 vLLM 入口:

docker run --rm --entrypoint python3 vllm/vllm-openai:latest -V
docker run --rm --entrypoint python3 vllm/vllm-openai:latest -c 'import vllm; print(vllm.__version__)'

如果 GPU 服务器访问上游镜像不稳定,可以在镜像层用毫秒镜像(1ms.run)做多源入口验证:

docker pull docker.1ms.run/vllm/vllm-openai:latest
docker pull docker.1ms.run/nvidia/cuda:12.4.1-runtime-ubuntu22.04

这一步只确认镜像获取和环境一致性。镜像正常不等于 GPU runtime、模型缓存和压测都正常。

3. GPU runtime 验证

宿主机先看 GPU:

nvidia-smi

再进容器看 GPU:

docker run --rm --gpus all nvidia/cuda:12.4.1-runtime-ubuntu22.04 nvidia-smi
docker info | grep -i runtime

常见问题:

现象 可能原因 处理方向
宿主机正常,容器内看不到 GPU runtime 未配置或没有传 --gpus all 检查 NVIDIA Container Toolkit
容器内能看到 GPU,vLLM 仍报 CUDA 问题 CUDA / driver / PyTorch 组合不匹配 固定镜像版本,记录 digest
单卡正常,多卡失败 tensor parallel、MIG、设备可见性问题 先单卡验证,再开多卡

4. 模型目录和缓存目录

模型目录建议只读挂载,缓存目录单独放本地磁盘。

mkdir -p /data/vllm-cache/hf /data/vllm-cache/torch

docker run --rm   -v /mnt/models:/models:ro   -v /data/vllm-cache:/cache   --entrypoint bash   vllm/vllm-openai:latest   -lc 'ls -lah /models/Qwen3-32B | head; echo $HF_HOME'

启动服务:

docker run --rm --gpus all   -p 8000:8000   -v /mnt/models:/models:ro   -v /data/vllm-cache:/cache   -e HF_HOME=/cache/hf   -e TORCH_HOME=/cache/torch   vllm/vllm-openai:latest   vllm serve /models/Qwen3-32B     --host 0.0.0.0     --port 8000     --served-model-name qwen3

验证 ready:

curl -fsS http://127.0.0.1:8000/health
curl -s http://127.0.0.1:8000/v1/models

5. 冷启动耗时记录

压测前先记录冷启动耗时:

START=$(date +%s)
until curl -fsS http://127.0.0.1:8000/health >/dev/null 2>&1; do
  sleep 2
done
END=$(date +%s)
echo "ready_seconds=$((END-START))"

如果冷启动过长,先看:

  • 是否每次都重新拉镜像。
  • 是否每次都重新下载模型或缓存。
  • 模型目录是否在 NAS 上,读延迟是否过高。
  • 健康检查窗口是否太短。

6. k6 压测脚本

创建 vllm-load.js

import http from 'k6/http';
import { check } from 'k6';

export const options = {
  vus: 10,
  duration: '3m',
  thresholds: {
    http_req_failed: ['rate<0.02'],
    http_req_duration: ['p(95)<8000'],
  },
};

export default function () {
  const payload = JSON.stringify({
    model: 'qwen3',
    messages: [{ role: 'user', content: '解释一下镜像缓存命中' }],
    max_tokens: 128,
  });
  const res = http.post('http://127.0.0.1:8000/v1/chat/completions', payload, {
    headers: { 'Content-Type': 'application/json' },
  });
  check(res, { 'status is 200': r => r.status === 200 });
}

运行:

k6 run vllm-load.js

记录三组结果:

并发 p95 错误率 GPU 利用率 结论
10 待填 待填 待填 基础试用
20 待填 待填 待填 部门试用
50 待填 待填 待填 是否要扩容

7. 上线前结论模板

上线前不要只写“压测通过”,建议写成可复盘的结论:

镜像:tag/digest 已记录,新 GPU 节点可拉取
GPU:宿主机和容器内均可见
模型:目录只读挂载,缓存目录独立
冷启动:ready_seconds=xx
并发:10 vus p95=xx,失败率=xx
风险:20 vus 后 p95 抖动,需要限流或扩容

这样下次换模型、换镜像、换驱动或换 GPU 节点,排查就有基线。

Logo

免费领 100 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐