在 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 服务运行时,服务账户可能不在 render 或 video 用户组,无法访问 /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=0 或 OLLAMA_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 #排查