欢迎光临
我们一直在努力

当 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:32bvLLM 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 id models,但实测是 /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 也可以)

    踩坑系列:

    • 《从 Figma 到代码:14 步还原企业级后台》(本博客系列)
    • 《M-014 像素级验收实战》
    赞(0)
    未经允许不得转载:171主机测评 » 当 Ollama 一直 OOM,我用 vLLM 救了 Cline 一次 —— H100 双卡多服务共存实战
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址