当 Ollama 一直 OOM,我用 vLLM 救了 Cline 一次 —— H100 双卡多服务共存实战
当 Ollama 一直 OOM,我用 vLLM 救了 Cline 一次 —— H100 双卡多服务共存实战
副标题:从"模型加载不上去"到"秒回",一个完整的多服务 GPU 资源排查与优化过程
前言
前几天在 192.168.31.9 这台 H100 双卡的机器上配 Cline,想用本地的 Qwen3-VL-32B 做代码开发。
本以为是个"装个 Ollama 跑模型"的简单活,结果一上手就踩了 6 个坑——Ollama 一直 OOM 加载失败、显存碎片化、split mode 自动跨卡、端口混乱、Model ID 猜不对、容器内外不互通。
最后靠换 vLLM 的 OpenAI 兼容 API 才彻底解决。
这篇文章把整个过程复盘一遍,包括:
- 如何排查多服务共存的 GPU 资源问题
- Ollama vs vLLM 的工程取舍
- Cline 接入本地大模型的完整配置
- 一些工具使用上的"坑"和"技巧"
适合读者:想用本地大模型做开发、需要在多服务共存环境部署 AI 推理、踩过 OOM 痛点的工程师。
一、起点:一台共用的 H100 双卡机器
机器是公司内共用的 AI 服务器,配置:
GPU 0 / GPU 1:NVIDIA H100 PCIe 80GB
合计 160GB 显存
接到这台机器时先 nvidia-smi 看看现状:
$ nvidia-smi
| GPU | 占用 | 空闲 |
|---|---|---|
| GPU 0 | vLLM Worker_TP0 60GB + mineru 2GB | ~18GB |
| GPU 1 | vLLM Worker_TP1 59GB | ~21GB |
结论:机器是 root 启动的 vLLM 服务(Qwen2.5-VL-32B 张量并行),Ollama 0.12.7 也装着但没模型加载。
能不能自己跑个 Ollama 试试 Qwen3-VL-32B?
理论上有 18-21GB 空闲,模型 20.9GB——看似刚好能塞下。
二、第一个坑:Ollama 一直 OOM
按 Ollama 官方文档拉模型:
ollama run qwen3-vl:32b "你好"
模型开始冷加载,但日志里疯狂报:
time=2026-08-07T11:34:33 level=INFO msg=load request="GPULayers:7[ID:GPU-87ee4d58...]"
ggml_backend_cuda_buffer_type_alloc_buffer: allocating 16605.68 MiB on device 0:
cudaMalloc failed: out of memory
ggml_gallocr_reserve_n: failed to allocate CUDA0 buffer of size 17412319360
time=... msg=load request="GPULayers:6[...]"
... (反复 backoff 重试)
症状:Ollama 在 GPU 0 上反复尝试 → OOM → 减少层数(7→6→5→4)→ 再试 → 又 OOM → 永远 backoff 循环。
Cline 端的表现是:发一条消息后永远卡在 “thinking…”,因为后端推理在死循环。
排查步骤:
# 1. 看 Ollama 日志
journalctl -u ollama -f
# 2. 看 GPU 实时情况
nvidia-smi
# 3. 看进程占显存
nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv
结论:物理上 GPU 0 剩 18GB,但碎片化到装不下连续的 16.6GB 块。
三、第二个坑:Ollama 的 split mode 自动跨卡
我设置了 OLLAMA_VISIBLE_DEVICES=1 想让它只用 GPU 1,结果更糟:
# 创建 systemd override
sudo tee /etc/systemd/system/ollama.service.d/gpu.conf > /dev/null << 'EOF'
[Service]
Environment="OLLAMA_VISIBLE_DEVICES=1"
EOF
sudo systemctl daemon-reload
sudo systemctl restart ollama
服务是起来了,但 nvidia-smi 显示:
GPU 0: ollama 10848 MiB ← 没用这张卡怎么还占了?
GPU 1: ollama 2766 MiB
原因:Ollama 看到 GPU 0 还有 18GB 空闲,自动把模型 split 到两张卡(即使 OLLAMA_VISIBLE_DEVICES=1 没生效,或者 Ollama 忽略了这个限制)。
加了更严格的 CUDA_VISIBLE_DEVICES=1 也没用——它把 GPU 1 重映射为 device 0,但 OOM 还是 OOM,因为 GPU 1 物理上只有 20GB 装不下 20.9GB 模型。
四、转折点:换 vLLM
思路转变:vLLM 已经在 GPU 0/1 上跑了 Qwen2.5-VL-32B(生产级服务),不如直接用它!
vLLM 提供 OpenAI 兼容 API(/v1/chat/completions),Cline 天然支持。
配置 Cline:
API Provider: OpenAI Compatible
Base URL: http://192.168.31.9:8000/v1
API Key: EMPTY
Model ID: /data/models
但有几个问题要解决——
五、第三个坑:vLLM 端口是 8000 不是 8081/8082
直觉上 vLLM 应该监听默认端口,但实际上:
$ docker ps | grep vllm
74e4934100b0 vllm/vllm-openai:v0.19.1
0.0.0.0:8000->8000/tcp vllm-qwen3-vl
docker port 命令直接给出了答案,不要靠记忆。
六、第四个坑:Model ID 是 /data/models
vLLM 启动参数里:
vllm serve --model /data/models --tensor-parallel-size 2 --dtype bfloat16 --max-model-len 16000 --trust-remote-code --gpu-memory-utilization 0.7 --enable-auto-tool-choice --tool-call-parser hermes
没有指定 --served-model-name。
试了一圈 model id:
# 这些都不对
"models" → 404
"Qwen3VLForConditionalGeneration" → 404
"qwen3_vl" → 404
"Qwen3-VL-32B-Instruct" → 404
正确答案是 /data/models(vLLM 启动时显示 served_model_name=/data/models):
$ curl -s http://192.168.31.9:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "/data/models",
"messages": [{"role": "user", "content": "hi"}],
"max_tokens": 5
}' | jq
{
"id": "chatcmpl-a2c63728969ece55",
"object": "chat.completion",
"model": "/data/models",
"choices": [{
"message": {"role": "assistant", "content": "Hi! 😊 How"}
}],
"usage": {"prompt_tokens": 9, "total_tokens": 14, "completion_tokens": 5}
}
5 tokens 几乎秒回!
七、性能对比:Ollama vs vLLM
| 维度 | Ollama qwen3-vl:32b | vLLM Qwen2.5-VL-32B |
|---|---|---|
| 显存 | 20.9GB(Q4_K_M) | ~32GB(bf16,2 卡分片) |
| 速度 | 30 tok/s(被 vLLM 抢资源) | 秒回(80+ tok/s 估) |
| 冷启动 | 20-30 秒 | 已 warmup,秒回 |
| 工具调用 | 弱 | ✅ hermes parser |
| Agent 模式 | 卡死 | ✅ 稳定 |
| 上下文 | 32K | 16K |
| 视觉 | ✅ | ✅ |
| 部署 | 单机/单机多卡 | 工业级多卡张量并行 |
vLLM 完胜(在多服务共存场景下)。
八、关键命令清单(速查表)
# 1. 看 GPU 状态
nvidia-smi
# 2. 看进程
ps aux | grep -E "vllm|ollama" | grep -v grep
# 3. 看 vLLM/Ollama 在哪个端口监听(宿主机)
ss -tlnp | grep -E "python|vllm|ollama"
# 4. 看 Docker 容器 + 端口映射
docker ps | grep vllm
docker port <container_id>
# 5. 进容器看 vLLM 日志
docker logs <container_id> 2>&1 | grep -iE "model|loaded|register" | head -30
# 6. 在容器内测试 API
docker exec <container_id> curl -s http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "/data/models",
"messages": [{"role": "user", "content": "hi"}],
"max_tokens": 5
}' | jq
# 7. 看 Ollama 日志
journalctl -u ollama -f
# 8. 设置 Ollama 只用某张卡
sudo tee /etc/systemd/system/ollama.service.d/gpu.conf > /dev/null << 'EOF'
[Service]
Environment="OLLAMA_VISIBLE_DEVICES=1"
Environment="OLLAMA_HOST=0.0.0.0"
EOF
sudo systemctl daemon-reload
sudo systemctl restart ollama
九、踩坑清单(5 条经验)
- 不要靠记忆端口 —— 用
docker port/ss -tlnp看实际监听 - vLLM 的 served_model_name 默认从路径推断 —— 路径
/data/models→ model idmodels,但实测是/data/models(看启动日志最准) - 多服务共存时 Ollama 的 split mode 不可控 —— 宁可换 vLLM 也不要在共享机器上和 vLLM 抢资源
- 显存碎片化是隐性 OOM ——
nvidia-smi显示有空,但cudaMalloc还是失败 - 冷启动 vs 已 warmup 性能差 10x —— vLLM 跑 3 天的服务比刚启动的 Ollama 流畅得多
十、配置模板(Cline 接 vLLM 通用版)
# Cline 配置
API Provider: OpenAI Compatible
Base URL: http://<vllm-host>:8000/v1
Model ID: <从 vllm 启动日志拿>
API Key: EMPTY(或 dummy)
# vLLM 启动参数(推荐)
vllm serve \
--model <model_path> \
--tensor-parallel-size <N> \
--dtype bfloat16 \
--max-model-len 16000 \
--trust-remote-code \
--gpu-memory-utilization 0.7 \
--enable-auto-tool-choice \
--tool-call-parser hermes
结尾
本地大模型开发,“先看 GPU 资源,再选引擎,最后接 IDE”。
Cline 跑通后,Qwen2.5-VL-32B 秒回,比之前的 Ollama 30 tok/s 体验好 5-10 倍。Cline 的 Agent 模式(工具调用)也稳了,可以正式用它做代码开发。
下一步:用 Cline 实测 M-014 返工的第一项(改 AppTable 背景色),看它在真实业务任务上的表现。
配套资源:
- vLLM 文档:https://docs.vllm.ai/
- Cline 插件:https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev
- 模型:Qwen2.5-VL-32B-Instruct(Qwen3-VL 也可以)
踩坑系列:
更多推荐


所有评论(0)