soarli

故障排查:Ollama 服务停止后显存不释放?教你三招彻底清理“僵尸显卡”
💥 案发现场在搭建 8x RTX 4090 的 Ollama 高并发集群时,我编写了脚本来启动多个实例。然而在调试...
扫描右侧二维码阅读全文
03
2026/02

故障排查:Ollama 服务停止后显存不释放?教你三招彻底清理“僵尸显卡”

💥 案发现场

在搭建 8x RTX 4090 的 Ollama 高并发集群时,我编写了脚本来启动多个实例。然而在调试过程中,当我试图停止脚本或重启服务时,遇到了一个让人血压升高的现象:

并没有任何模型在跑,但 nvidia-smi 显示 8 张显卡依然被塞得满满当当!

+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.129.03             Driver Version: 535.129.03   CUDA Version: 12.2     |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
|=========================================+======================+======================|
|   0  NVIDIA GeForce RTX 4090        Off | 00000000:19:00.0 Off |                  Off |
| 31°C    P0              30W /  450W |  18292MiB / 24564MiB |      0%      Default |
|-----------------------------------------+----------------------+----------------------+
|   1  NVIDIA GeForce RTX 4090        Off | 00000000:1A:00.0 Off |                  Off |
| 30°C    P0              28W /  450W |  18292MiB / 24564MiB |      0%      Default |
| ... (以此类推,8张卡全红)                                                             |
+---------------------------------------------------------------------------------------+

症状总结

  1. 高显存占用:每张卡都被占了约 18GB(正好是 Gemma-27B 模型的显存量)。
  2. 零算力利用:GPU-Util 为 0%,说明进程虽然占着坑,但没在干活。
  3. 杀不掉:尝试普通的 kill 命令无效,显存依然不释放。

🕵️‍♂️ 原因分析

这是典型的 “僵尸进程” (Zombie/Orphan Processes) 问题。

当你强制终止(Ctrl+C)一个 Shell 脚本时,有时候只能杀掉脚本本身(父进程),而脚本启动的 Ollama 子进程(实际上是底层的 llama_runner)并没有收到退出信号,或者因为程序内部卡死(Deadlock)而忽略了普通的终止信号(SIGTERM)。

这些“孤儿”会继续霸占着显存不肯走,导致你无法启动新的服务,甚至导致 OOM(显存溢出)错误。


🛠️ 解决方案:从温柔到暴力

针对这种情况,我们有三层手段来处理。

方案一:精准狙击(推荐)

如果你只想清理卡住的集群实例,但想保留那个默认的 11434 全局服务,不要用 killall

# 1. 查找所有 ollama serve 进程
ps -ef | grep "ollama serve"

# 2. 排除掉全局服务(11434),杀掉其他的
# awk '{print $2}' 提取进程ID (PID)
# xargs kill -9 传递给 kill 命令执行强制查杀
ps -ef | grep "ollama serve" | grep -v "11434" | awk '{print $2}' | xargs kill -9
  • 关键点:必须使用 -9 参数。普通的 kill 发送的是 SIGTERM(请你退出),卡死的进程听不见;-9 发送的是 SIGKILL(强制处决),由操作系统内核直接把进程干掉,不容反驳。

方案二:按硬件查杀(最直观)

如果你不知道是哪个进程在捣乱,只知道显卡被占用了,可以直接问显卡驱动:“谁在用我的显卡?”

1. 查看占用者:

# -v 显示详细信息
sudo fuser -v /dev/nvidia*

你会看到一串 PID,这就证实了确实有残留进程。

2. 核弹清理(慎用):

这条命令会杀掉所有正在使用 NVIDIA 显卡的进程。如果你的服务器上还有别的人在跑训练,慎用!

# -k: kill (杀掉)
# -9: SIGKILL (强制)
# -v: verbose (显示过程)
sudo fuser -k -9 -v /dev/nvidia*

执行完这条,世界瞬间清净了。

方案三:地毯式轰炸(最简单)

如果你确定服务器上除了 Ollama 没别的显卡应用,且不在乎重启全局服务,直接用 pkill

# 强制杀掉所有名字里带 "ollama" 的东西
sudo pkill -9 ollama

注意:这会连同 Systemd 管理的全局 Ollama 服务一起杀掉。执行完后,记得用 systemctl start ollama 把全局服务拉起来。


🛡️ 如何避免?

为了防止以后每次都要手动“收尸”,建议不要直接在前台跑 Shell 脚本,而是将你的集群脚本注册为 Systemd 服务

Systemd 在停止服务时,会利用 cgroup 管理机制,确保把该服务启动的所有子子孙孙进程全部清理干净,不会留下僵尸进程。

Systemd 服务文件示例 (/etc/systemd/system/ollama-cluster.service):

[Unit]
Description=Ollama 8-GPU Cluster
After=network.target

[Service]
Type=forking
ExecStart=/bin/bash /root/scripts/start_cluster.sh
# 这一行是关键:服务停止时,杀掉控制组内的所有进程
KillMode=control-group
Restart=always

[Install]
WantedBy=multi-user.target

📝 总结

遇见“显存占满但 GPU 利用率为 0”的情况,不要慌张:

  1. 先用 nvidia-smi 确认显存确实没释放。
  2. 使用 sudo fuser -v /dev/nvidia* 揪出幕后黑手。
  3. 使用 kill -9fuser -k -9 执行“死刑”。
  4. 切记:在 Linux 下处理卡死的显卡进程,只有 -9 (SIGKILL) 才是真正的终结者。

希望这篇避坑指南能帮各位“炼丹师”节省宝贵的排查时间!🚀

最后修改:2026 年 02 月 03 日 02 : 14 PM

发表评论