Ollama 探测不到 GPU,全跑在 CPU

Ollama 启动后模型在 CPU 上运行,生成速度极慢。定位 CUDA/ROCm 驱动缺失、环境变量遮蔽、多显卡配置等根因并给出可执行修复命令。

在 RTX 4090 / 24 GB 显存的机器上运行 ollama run llama3:8b,生成速度只有 2-5 token/s,而同配置下正常应在 80-120 token/s。执行 ollama ps 看到模型确实在运行,但 nvidia-smi 显示 GPU 利用率始终为 0%。Ollama 0.4 默认会自动探测并使用 NVIDIA/AMD GPU,如果没探测到,几乎必然是驱动层或环境变量的问题,而不是 Ollama 本身的 bug。

常见原因

1. CUDA 驱动版本低于 Ollama 最低要求

Ollama 0.4 要求 NVIDIA 驱动版本不低于 535(对应 CUDA 12.2)。旧驱动下 libcuda.so 的符号表缺少 Ollama 用到的接口,探测失败后静默回退到 CPU。

怎么判断nvidia-smi --query-gpu=driver_version --format=csv,noheader 查看驱动版本;ollama serve 日志(journalctl -u ollama -n 50 或直接前台启动)搜索 cuda driver 关键字,若看到 no CUDA GPU 即可确认。

2. CUDA_VISIBLE_DEVICES 被设为空或 -1

某些 conda 环境、Docker 容器或 VSCode 插件会在激活时将 CUDA_VISIBLE_DEVICES 设为 """-1",导致所有 CUDA 应用看不到任何 GPU。

怎么判断echo $CUDA_VISIBLE_DEVICES;若输出空字符串或 -1,就是这个问题。同时检查 ~/.bashrc~/.zshrc、conda 的 activate.d/ 脚本。

3. Ollama 服务通过 systemd 启动,未继承用户级 GPU 权限

当 Ollama 作为 systemd 服务运行时,服务账户可能不在 rendervideo 用户组,无法访问 /dev/dri/ 下的 AMD GPU 设备节点;NVIDIA 则可能缺少 nvidia-modprobe 权限。

怎么判断groups ollama(若有专用服务账户)或 ls -la /dev/nvidia* 查看设备文件权限;journalctl -u ollama -n 100 | grep -i 'permission\|denied'

4. AMD ROCm 版本与内核模块不匹配

AMD GPU 用户需要 ROCm 5.7 以上。若系统升级了内核但 ROCm 内核模块(amdgpu)没有对应更新,/dev/kfd 设备不可用,Ollama 探测失败。

怎么判断rocm-smi 命令能否正常输出 GPU 信息;dmesg | grep amdgpu 检查内核模块加载状态。

5. WSL2 环境缺少 NVIDIA Paravirtualization 驱动

在 Windows 11 + WSL2 中,Ollama 需要 Windows 侧安装 NVIDIA 驱动(不是在 WSL2 内部安装),且 WSL2 内核需要 5.15.90.1 以上才支持 GPU passthrough。

怎么判断:在 WSL2 中执行 ls /dev/dxg,若文件不存在则 GPU passthrough 未启用;nvidia-smi 若报 command not found 说明 Windows 驱动版本过旧。

6. Metal(Apple Silicon)被 OLLAMA_GPU 覆盖

Mac M 系列芯片上,若设置了 OLLAMA_GPU=0OLLAMA_NO_GPU=1,Ollama 会强制使用 CPU,但错误信息不明显,容易被忽视。

怎么判断env | grep -i ollama 检查所有 Ollama 相关环境变量。

最短修复路径

Step 1:检查基础 GPU 可见性

# NVIDIA
nvidia-smi
# 应该看到 GPU 名称、显存、驱动版本

# AMD
rocm-smi
# 应该看到 GPU 列表

# Apple Silicon
system_profiler SPDisplaysDataType | grep -i "metal\|chip"

Step 2:以前台模式启动 Ollama,查看 GPU 探测日志

# 停止 systemd 服务(如果有的话)
sudo systemctl stop ollama 2>/dev/null || true

# 前台启动,日志直接输出到终端
OLLAMA_DEBUG=1 ollama serve 2>&1 | grep -i 'gpu\|cuda\|metal\|rocm\|error'

正常应看到类似:

msg="inference compute" id=GPU-xxxx library=cuda compute=8.9 driver=12.4 name="NVIDIA GeForce RTX 4090" total="23.6 GiB" available="23.2 GiB"

Step 3:清除可能遮蔽 GPU 的环境变量

unset CUDA_VISIBLE_DEVICES
unset CUDA_DEVICE_ORDER
unset OLLAMA_GPU
unset OLLAMA_NO_GPU

# 然后重新测试
ollama run llama3:8b "hello" --verbose
# 观察输出里是否有 eval rate,正常 GPU 下应在 30 token/s 以上

Step 4:NVIDIA 驱动升级(Linux)

# Ubuntu 22.04 / 24.04
ubuntu-drivers devices
sudo ubuntu-drivers autoinstall
sudo reboot

# 升级后验证
nvidia-smi | grep "Driver Version"
# 应该是 535 以上

Step 5:systemd 服务添加 GPU 访问权限

sudo systemctl edit ollama
# 在 [Service] 下添加:
# Environment="CUDA_VISIBLE_DEVICES=all"
# SupplementaryGroups=render video

sudo systemctl daemon-reload
sudo systemctl restart ollama

预防建议

  • 升级系统驱动后立即执行 ollama run <model> "test" --verbose 验证 GPU 仍可用。
  • conda/virtualenv 激活脚本中不要无差别 unset CUDA_VISIBLE_DEVICES,改用具体的 GPU ID(如 export CUDA_VISIBLE_DEVICES=0)。
  • WSL2 环境中固定 Windows 侧 NVIDIA 驱动版本,避免自动更新破坏 GPU passthrough。
  • 多 GPU 机器上用 CUDA_VISIBLE_DEVICES=0,1 明确指定,而不是依赖自动探测。
  • OLLAMA_DEBUG=1 写入 systemd 服务的 EnvironmentFile,便于排查时快速查日志。
  • AMD 用户在内核升级后检查 modprobe amdgpu 是否报错,必要时重新编译 DKMS 模块。
  • Apple Silicon 用户不要设置任何 CUDA_* 环境变量,这些变量在 Metal 后端下会触发意外行为。

常见问答 (FAQ)

Q: ollama run 显示 “using GPU” 但速度依然很慢,是 GPU 没真正用上吗? A: 可能是显存不够,模型部分层被卸载到 CPU(称为 CPU offload)。用 ollama ps 查看 Size 列,再对比 nvidia-smi 的已用显存;若显存使用率低但模型大,说明大量层在 CPU 上。解决办法是换更小的量化版本或用显存更大的 GPU。

Q: Docker 容器里运行 Ollama,GPU 探测失败怎么办? A: 需要在 docker run 时加 --gpus all 并安装 nvidia-container-toolkit。执行 docker run --rm --gpus all nvidia/cuda:12.2-base nvidia-smi 验证容器内 GPU 可见后,再启动 Ollama 容器。

Q: 有两块 GPU,Ollama 只用了一块,另一块闲着? A: 参考多 GPU 没分配上,模型只跑在卡 0 这篇文章,需要设置 CUDA_VISIBLE_DEVICES=0,1 并在模型加载时启用张量并行。

Q: 更新 Ollama 版本后 GPU 突然不可用,怎么回滚? A: Ollama 不提供官方版本管理,但可以从 GitHub Releases 手动下载旧版二进制替换。先用 which ollama 找到安装路径,备份后替换即可。回滚前先确认旧版是否与当前 CUDA 驱动兼容。

相关阅读

标签: #local-llm #ollama #排查