一、硬件与模型选型
Gemma 4 31B 是 Google 发布的稠密架构(Dense)模型,310 亿参数在推理时全量激活。官方 BF16 完整版权重约 62–71 GB,远超 RTX 4090 48GB 的显存上限,因此必须选择量化版本。
| 量化方案 | 权重体积 | 4090 48GB 可行性 | vLLM 支持度 |
|---|---|---|---|
| BF16 原版 | ~71 GB | ❌ 不可行 | — |
| INT8 | ~36 GB | ⚠️ 极限,无余量 | ✅compressed-tensors |
| AWQ/GPTQ 4-bit | ~17–20 GB | ✅ 充裕,可开长上下文 | ✅awq / gptq |
| GGUF | ~19 GB | ❌ vLLM 不支持 | ❌ 仅 llama.cpp/Ollama 可用 |
结论:在 48GB 显存环境下,优先选择社区已量化好的 AWQ 4-bit 或 INT8 HuggingFace 格式模型(.safetensors + config.json),不要下载 GGUF 格式。
二、前置环境准备
1. NVIDIA 驱动与 Docker
# 确认驱动已正确安装
nvidia-smi
# 安装 Docker(如未安装)
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker
2. 国内 Docker 镜像加速(关键)
国内直接 docker pull 官方镜像大概率超时。推荐配置 阿里云镜像加速器(免费,需登录阿里云控制台获取专属地址)或 DaoCloud 公共镜像:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://你的专属地址.mirror.aliyuncs.com",
"https://docker.m.daocloud.io"
]
}
EOF
sudo systemctl daemon-reload && sudo systemctl restart docker
验证加速生效:
docker info | grep -A 5 "Registry Mirrors"
三、模型下载(ModelScope 源)
国内从 HuggingFace 下载大模型速度较慢,建议通过 ModelScope(魔搭社区)下载 Gemma 4 31B 的量化版本。
假设你将模型下载至以下目录:
/mnt/mydata/modelscope/models/
├── config.json
├── model.safetensors
├── tokenizer.json
└── ...
目录确认要点:vLLM 通过 --model 参数指定的路径是容器内部路径,需要通过 -v 挂载卷映射到宿主机真实目录。
四、部署过程与踩坑实录
坑 1:命令行续行符 \ 失效(最常见)
很多教程为了可读性使用反斜杠换行:
docker run -d --name xxx \
--gpus all \
...
但在终端直接粘贴时,反斜杠后若带有空格、或换行被吞,Shell 会把后半截当成新命令执行,导致报错 --quantization: command not found。
解决方案:直接写单行命令,或写入 .sh 脚本后执行。
坑 2:-v 挂载路径与 --model 路径不匹配
错误示例:
-v /mnt/models:/models # 把宿主机 /mnt/models 挂到容器 /models
--model /mnt/mydata/... # 但模型实际在宿主机 /mnt/mydata,容器内无此路径
正确映射逻辑:
| 参数 | 宿主机真实路径 | 容器内映射路径 | --model 应写 |
|---|---|---|---|
-v /mnt/mydata/modelscope/models:/models |
/mnt/mydata/modelscope/models |
/models |
/models |
坑 3:端口映射 -p 与 --port 不一致
vLLM 默认监听 8000 端口。若你做了 -p 8099:8099,但容器内服务仍在 8000,外部访问 8099 会连接失败。
必须同时指定:-p 8099:8099 和 --port 8099。
坑 4:量化格式与 --quantization 参数不对应
- 模型是 AWQ 格式 →
--quantization awq - 模型是 GPTQ 格式 →
--quantization gptq - 模型是 INT8(compressed-tensors)→
--quantization compressed-tensors - 不能通过
--dtype int8把 BF16 模型动态压缩,该参数只支持float16/bfloat16/float32/auto
五、最终成功启动命令
综合以上排坑,在 Ubuntu 22.04 + RTX 4090 48GB 环境下的最终可用命令如下:
sudo docker run -d \
--name vllm-gemma4-31 \
--gpus all \
-p 8099:8099 \
-v /mnt/mydata/modelscope/models:/models \
--ipc=host \
vllm/vllm-openai:latest \
--model /models \
--quantization compressed-tensors \
--dtype float16 \
--max-model-len 32768 \
--gpu-memory-utilization 0.90 \
--trust-remote-code \
--enable-prefix-caching \
--served-model-name gemma-4-31b \
--port 8099
参数说明:
--gpus all:使用所有可用 GPU(单卡 4090 场景下等效于'"device=0"',且避免引号转义问题)-v /mnt/mydata/modelscope/models:/models:宿主机模型目录挂载到容器/models--model /models:容器内读取模型的路径,与挂载点保持一致--ipc=host:共享宿主机 IPC 命名空间,避免多进程通信时显存拷贝开销--gpu-memory-utilization 0.90:显存占用上限 90%,留 10% 余量给 KV Cache 和系统缓冲--enable-prefix-caching:启用前缀缓存,多轮对话场景下显著降低重复计算
六、验证服务状态
1. 查看容器日志
sudo docker logs -f vllm-gemma4-31
成功标志:
INFO 04-20 17:54:12 model_runner.py:xxx] Loading model weights took xx GB
INFO 04-20 17:54:15 api_server.py:xxx] Started server process [xx]
INFO 04-20 17:54:15 api_server.py:xxx] Uvicorn running on http://0.0.0.0:8099
2. API 连通性测试
vLLM 提供 OpenAI 兼容接口,测试如下:
curl http://localhost:8099/v1/models
应返回:
{
"object": "list",
"data": [
{
"id": "gemma-4-31b",
"object": "model",
"created": 1713620000,
"owned_by": "vllm",
"root": "/models",
"parent": null,
"max_model_len": 32768
}
]
}
3. 推理测试
curl http://localhost:8099/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gemma-4-31b",
"messages": [
{"role": "user", "content": "9.9 和 9.11 哪个大?请逐步分析。"}
],
"temperature": 0.2,
"max_tokens": 1024
}'
七、性能调参与生产建议
| 参数 | 建议值 | 说明 |
|---|---|---|
--max-model-len |
32768(4-bit)/ 16384(INT8) | 根据显存余量调整,过长会导致 OOM |
--gpu-memory-utilization |
0.90 | 48GB 场景下留 4–5GB 给 KV Cache 和系统 |
--max-num-seqs |
默认或 256 | 限制并发请求数,避免显存挤占 |
--enable-chunked-prefill |
建议开启 | 长文本预填充分块,提升吞吐 |
--tensor-parallel-size |
1 | 单卡 4090 无需张量并行 |
如需多模态(图像+文本)支持,Gemma 4 原生兼容,调用时传入 Base64 图片即可,vLLM 会自动处理视觉 Token。
八、FAQ
Q:为什么不用 --dtype int8?
A:--dtype 控制计算时的数据类型,仅支持 float16/bfloat16/float32。INT8/4-bit 需要通过 --quantization 加载已量化好的模型权重。
Q:GGUF 模型能用吗?
A:不能。vLLM 已移除 GGUF 支持。GGUF 是 llama.cpp/Ollama 生态格式,vLLM 只接受 HuggingFace 格式(.safetensors)。
Q:容器启动后立刻退出,怎么看错误?
A:去掉 -d 参数前台运行,或执行 docker logs vllm-gemma4-31 查看。常见原因是 --model 路径错误或量化参数与模型格式不匹配。
以上即完整的部署实录。核心经验是:国内环境优先解决镜像拉取和路径映射问题,量化模型务必确认格式与 --quantization 参数一致,其余按 vLLM 标准流程即可在 4090 48GB 上流畅运行 Gemma 4 31B。