尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Ollama 无法使用 GPU 的完整排查思路:从驱动到模型加载全链路
最近好几个朋友找我问题出奇一致Ollama 装好了新显卡也插上了驱动看着没问题可一跑模型就卡得让人怀疑人生。打开任务管理器一查CPU 飙到 100%GPU 占用率基本为零——模型确实在跑可它跑在 CPU 上。这个问题我前前后后踩了三四次每次原因还都不一样有驱动版本太老的有环境变量被悄悄改掉的还有人在 Docker 容器里忘了加--gpus all的。这篇文章把我积累的完整排查思路整理出来从判断现象到最终修复每一步都给出可复现的命令和判断标准希望能帮你把装了显卡却用不上这个问题一次性解决。1. 先别急着修确认真的跑在 CPU 上1.1 三个肉眼可用的快速判断信号我见过太多人一上来就重装驱动折腾两个小时后发现模型其实早就在用 GPU之前的慢另有原因。所以在动任何配置之前先用下面三个信号确认现象。第一个信号是生成速度。在同一个模型、同一个 prompt 下GPU 和 CPU 的 token 生成速度差距通常在一个数量级以上。拿我机器上的实测数据举例Llama 3.2 3B 用 CPU 纯算大概 5 到 8 token/s切到 GPU 后能到 60 甚至 80 token/s。如果你的模型生成速度让你有明显等待、逐字往外蹦的感觉基本可以怀疑没走 GPU。第二个信号是资源占用。Windows 下开任务管理器Linux 下用top或者htop在跑生成任务的时候看 CPU 占用率。如果 CPU 冲上 80% 以上而 GPU 的 util 和显存纹丝不动那大概率是 CPU 在硬扛。第三个信号是显存。真正卸载到 GPU 上的模型一定会吃显存。一个 7B 模型用 Q4_K_M 量化后大约是 4.5GB再算上 KV cache轻松超过 5GB。你在生成过程中盯住显存占用如果完全没变化GPU 肯定没参与计算。这里有个隐蔽的坑要提醒有时候 Ollama 会部分卸载。比如模型一共 33 层它只往 GPU 上放 20 层剩下的 13 层留在 CPU 上。这种状态下显存确实涨了但速度依然不理想而且 nvidia-smi 里看到的 GPU 利用率可能忽高忽低。所以单看显存变化还不够要结合后面的日志方法综合判断。1.2 用 nvidia-smi 抓现行这一步我习惯叫抓现行操作很简单在终端开一个窗口跑nvidia-smi -l 1这个命令每秒刷新一次 GPU 状态。然后在另一个窗口触发一次模型生成比如ollama run llama3.2 写一段关于春天的短文接着看 nvidia-smi 的输出。如果能看到类似ollama或ollama_llama_server的进程显存占用在生成过程中有变化GPU-Util有跳动说明 GPU 确实参与了推理。如果 nvidia-smi 的进程列表里压根没有相关进程问题基本坐实。有一点要说明GPU-Util这个字段在 transformer 推理阶段不会一直居高不下。解码decode阶段是访存密集型任务GPU 利用率本身就会出现周期性波动这是正常的。真正可靠的指标是显存占用是否匹配模型大小以及进程是否挂在 GPU 上。2. Ollama 的硬件调度逻辑GPU 不是装上就能被认出来的2.1 Ollama 底层是怎么决定让谁干活的要解决这个问题先得理解 Ollama 的调度机制。Ollama 的推理引擎底层用的是 llama.cpp 的运行时模型加载时会把 Transformer 的各层layer拆分到不同设备上执行。它的核心逻辑是启动时扫描可用的计算设备能放 GPU 的层就放 GPU放不下的留在 CPU 内存里。这个扫描过程依赖两个东西一是检测驱动和运行时环境二是检查显存容量。对于 NVIDIA 显卡来说Ollama 自带了一套 CUDA runtime不要求你手动装 CUDA Toolkit但要求显卡驱动不能太老。Ollama 启动时如果发现 CUDA 环境不可用不会报错中断而是静默降级到 CPU 模式——这是很多人没察觉到的关键点。换句话说GPU 加载失败不是一个错误而是一个降级日志里可能只有一行不起眼的 INFO。调度时真正起作用的是一个参数num_gpu也叫 GPU 层数。它决定了把模型的前多少层放到 GPU 上计算。值为0表示全部跑 CPU值为-1或者旧版本里的999表示尽可能把所有层都放 GPU。这个参数有三个来源优先级从高到低是API 请求中的 options、Modelfile 里的 PARAMETER、环境变量OLLAMA_NUM_GPU。2.2 层与显存的关系为什么部分回退最坑理解部分回退是排查 GPU 问题的重要环节。模型每一层都有对应的权重和激活值放到 GPU 上就占显存放到 CPU 上就占内存。Ollama 启动时会估算模型体积再加上推理需要的 KV cache键值缓存空间然后和你的显存总量做比较。举个例子一张 8GB 显存的 RTX 3070跑一个 7B 模型。Q4_K_M 权重大概 4.5GB看起来装得下但 KV cache 会随着上下文长度增长。默认上下文 2048 时可能只要 3GB 左右加起来 7.5GB勉强能塞下。可如果你把上下文调到 8192KV cache 可能涨到 8GB 以上这时候 Ollama 会自动把一部分层放回 CPU而不是报错。结果就是显存占了一半但生成速度依然拉胯还特别难排查。所以排查 GPU 问题不能只看有没有用 GPU还要看用了多少层。日志里会明确打印类似这样的信息offload 20/33 layers to GPU如果你看到的是 20/33 而不是 33/33那说明模型被部分卸载到了 CPU。优先检查上下文长度和量化版本而不是怀疑驱动。2.3 哪些情况会导致 Ollama 主动放弃 GPU根据我自己的踩坑经历以下情况会导致 Ollama 即使检测到显卡也拒绝使用 GPU环境变量OLLAMA_NUM_GPU0被设置。这是最常见的隐蔽原因可能是为了排查别的问题临时设置的之后忘了改回来。模型显存需求超出可用显存调度器自动减少 GPU 层数甚至全量回退。驱动版本低于 Ollama 自带的 CUDA runtime 要求初始化失败后降级。Docker 容器启动时没有加--gpus all容器里根本看不到显卡设备。WSL2 场景下 Windows 侧驱动没装对WSL 内部 nvidia-smi 能跑但 CUDA 库不匹配。Modelfile 里写了PARAMETER num_gpu 0覆盖掉了默认行为。多 GPU 机器上显存碎片化严重调度器分配的显存不足。上面这些原因里第一和第三是实际发生频率最高的。下面我会给出一套逐层排查的命令操作把所有环节都过一遍。3. 从驱动到进程的全链路排查照着做就行3.1 第一层驱动与 CUDA 运行时的可用性排查从最底层开始。Linux 或 Windows 下先跑nvidia-smi重点看两个信息Driver 版本和 CUDA Version。以我的机器为例输出大概是--------------------------------------------------------------------------------------- | NVIDIA-SMI 535.154.05 Driver Version: 535.154.05 CUDA Version: 12.2 | ---------------------------------------------------------------------------------------这里的 CUDA Version 是驱动支持的 CUDA 最大版本不要求你手动装 CUDA Toolkit 跟它对齐Ollama 会自带所需运行库。但驱动版本如果太老比如 470 系列或者更早Ollama 内置的 CUDA 12 runtime 可能初始化失败。判断驱动是否够新的简单标准支持 CUDA 12 以上的版本驱动版本大于等于 525 建议。如果 nvidia-smi 直接提示找不到设备先解决驱动问题再继续。Windows 用户建议用 GeForce Experience 或者官网手动下载对应型号驱动Linux 用户注意发行版内核与驱动的匹配不要只依赖系统自带的 nouveau 开源驱动——Ollama 不支持它。3.2 第二层Ollama 进程是否看到了 GPU驱动没问题之后看 Ollama 自己的日志。这一步是最接近真相的环节。log尾部出现这类内容说明它找到了可用 GPUtime... levelINFO sourcesched.go:123 msglooking for compatible GPUs time... levelINFO sourcesched.go:133 msgfound compatible GPU librarycuda device0 nameNVIDIA GeForce RTX 3070 total8192 MiB如果日志中没有found compatible GPU而是类似no GPU found或者根本没有任何 GPU 相关记录那问题出在进程层面的设备可见性。这里有个容易被忽略的点Ollama 如果是通过 systemd 服务启动的它的环境变量和你 shell 里看到的不一样。很多人直接在终端 export 了 OLLAMA_NUM_GPU然后重启 systemd 服务发现不生效就是因为 systemd 服务的 Environment 配置里没有同步。需要改服务配置文件sudo systemctl edit ollama在打开的配置里加上[Service] EnvironmentOLLAMA_NUM_GPU-1保存后重启服务sudo systemctl restart ollama然后systemctl show ollama --propertyEnvironment可以确认环境变量是否注入。3.3 第三层模型加载与层数分配确认 GPU 可见后加载模型并查看层卸载情况。ollama run llama3.2然后在另一个终端执行ollama ps输出格式大致如下NAME ID SIZE PROCESSOR UNTIL llama3.2:latest a80c4f17acd5 2.0 GB 100% GPU 4 minutes from nowPROCESSOR这一列非常关键。100% GPU表示全部在 GPU 上100% CPU表示完全没走 GPU60% GPU / 40% CPU就是部分卸载。如果你的模型显示100% CPU要么是环境变量问题要么是驱动问题要么是显存不够。这时候回到日志里搜 offload 关键字journalctl -u ollama | grep -i offload或者直接看服务启动后的完整日志journalctl -u ollama -n 100日志里如果出现offload 0/33 layers to GPU说明 Ollama 主动把所有层都留在了 CPU。结合前文说的三个参数来源逐个检查 API options、Modelfile 和环境变量。3.4 第四层Docker 与 WSL2 场景的特殊检查容器部署是重灾区。如果 Ollama 跑在 Docker 里光在宿主机装驱动是不够的还需要 GPU 运行时支持。先确认容器工具链sudo apt list --installed | grep nvidia-container没有就安装 nvidia-container-toolkit然后配置 runtime。启动 Ollama 容器时必须加上--gpus alldocker run -d --gpus all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama进入容器内部自检docker exec -it ollama nvidia-smi如果容器里跑不了 nvidia-smi说明 GPU 没有被共享到容器模型自然只能回退到 CPU。WSL2 是另一个常见环境。注意在 WSL2 里跑 Ollama驱动是装在 Windows 侧的WSL2 内不需要也不应该重装 Linux 驱动。检查方法nvidia-smi在 WSL2 里如果能看到和 Windows 一致的 GPU 信息说明 GPU 转发已经生效。之后还要确认 CUDA 库在 WSL2 内的路径没问题最简单的方法是直接跑一个小模型测试而不是先折腾环境变量。4. 高频坑位盘点每个坑我都付过学费4.1 驱动版本过老CUDA 初始化静默失败这个坑最隐蔽。Ollama 的日志里不会打红字错误只在早期出现一行msglooking for compatible GPUs然后紧接着没有任何 GPU 相关的记录最后模型照常加载只是速度慢。你查 systemctl 状态也是 active一切看起来都正常。我遇到的那次是在一台旧电脑上驱动停留在 470 系列Ollama 内置的 CUDA 12.x runtime 根本跑不起来。解决方式是把驱动升级到 535 或更高。这里给出一个更直接的检查思路用ollama serve前台启动而不是用 systemd这样所有日志直接打在终端里任何 DEBUG 信息都不会被吞掉。# 先停掉服务 sudo systemctl stop ollama # 前台启动 OLLAMA_DEBUG1 ollama serve启动前先导出调试开关export OLLAMA_DEBUG1 export CUDA_LAUNCH_BLOCKING1CUDA_LAUNCH_BLOCKING1是个强制同步标志能让 CUDA 错误直接暴露而不是被异步吞掉。这一步能帮助你从日志里发现隐藏的初始化异常。4.2 环境变量 OLLAMA_NUM_GPU 被悄悄改成 0这个坑有多普遍呢我身边至少有两个人最后查出来是这个原因。有个朋友以前为了排查另一个问题在某篇教程的指导下设置过OLLAMA_NUM_GPU0后来那台机器就没再管过等他换新显卡跑新模型问题就出现了。检查方法很简单env | grep OLLAMA重点看 OLLAMA_NUM_GPU 的值。如果显示 0改成 -1 或直接 unsetunset OLLAMA_NUM_GPU但这里有个细节如果你曾经把它写进过~/.bashrc或~/.zshrcunset 只对当前 shell 生效新的终端还是会加载配置。所以正确的做法是直接编辑对应的 rc 文件把那一行注释掉或删掉。Windows 下则要检查系统环境变量和用户环境变量方法是在 PowerShell 里执行Get-Item -Path Env:OLLAMA_NUM_GPU如果存在就直接删除Remove-Item Env:OLLAMA_NUM_GPU4.3 systemd 服务里的 Environment 配置陷阱如果你习惯用systemctl管理 Ollama多半会踩这个坑。Ollama 的 systemd 服务文件位于/etc/systemd/system/ollama.service或者通过包管理器生成的 unit 文件。很多人直接在终端 export 了环境变量然后重启服务发现不生效——那是因为服务进程的环境变量完全由 unit 文件里的Environment行决定跟你 shell 里 export 的东西没有关系。正确的改法有两种。一种是编辑默认的 service 文件sudo systemctl edit ollama这会创建一个 drop-in 文件比如/etc/systemd/system/ollama.service.d/override.conf你只需要写[Service] EnvironmentOLLAMA_NUM_GPU-1 EnvironmentOLLAMA_DEBUG1保存后sudo systemctl daemon-reload sudo systemctl restart ollama然后通过systemctl show ollama --propertyEnvironment或者直接看进程的/proc/pid/environ来验证pid$(pgrep -f ollama serve) tr \0 \n /proc/$pid/environ | grep OLLAMA这个方法能看到服务进程实际拿到的环境变量比看配置文件更可靠。4.4 显存刚好差一点点导致的部分回退最后这个坑非常有意思模型文件看起来不大显存也够但就是有一部分层被放到 CPU 上。原因前面提到过KV cache 会随着上下文长度增长。Ollama 在加载模型时按设置的最大上下文长度预留显存如果你的上下文设置太大显存估算超了它就会让部分层留在 CPU。排查办法是把上下文调小测试是否恢复全量 GPU 卸载OLLAMA_NUM_GPU-1 ollama run llama3.2 --keep-context 2048或者用 API 显式指定参数curl http://localhost:11434/api/generate -d { model: llama3.2, prompt: hello, options: { num_gpu: -1, num_ctx: 2048 } }如果日志从offload 20/33变成offload 33/33那问题就在上下文长度和显存容量的匹配上。解决方案要么降低上下文要么更换更小量化的模型比如从 Q8 降到 Q4要么换更大显存的卡——没有别的捷径。5. 验证 GPU 真正生效的三种方法修完之后必须做验证下面三种方法建议配合使用形成一套完整的验收流程。5.1 日志锚点法我先看日志这是最硬核的证据。打开 Ollama 服务日志加载一次模型找到这两类日志记录msgfound compatible GPU librarycuda device0 msgoffload 33/33 layers to GPU只要出现offload 33/33 layers to GPU就说明全部层都在 GPU 上。如果出现offload N/33 layers to GPU其中 N 小于总层数说明部分回退继续排查显存或上下文。日志记录是判断最明确的锚点因为它精确告诉你每一层去了哪里比任何外部观测工具都准确。5.2 推理速度对比法速度对比是最直观的验证。分别获取 CPU 与 GPU 下的 token 生成速度对比差距。先强制 CPU 跑一遍拿个基准OLLAMA_NUM_GPU0 ollama run llama3.2 给我讲一个冷笑话注意这种启动方式只对当前命令有效跑完即止。然后强制 GPU 跑一遍OLLAMA_NUM_GPU-1 ollama run llama3.2 给我讲一个冷笑话对比两者输出结束后的时间或者用 API 返回里的eval_count和eval_duration字段算 token/scurl http://localhost:11434/api/generate -d { model: llama3.2, prompt: 讲个冷笑话 } | jq {eval_count, eval_duration, tok_s: (.eval_count / (.eval_duration / 1e9))}gpu 模式下速度通常是 cpu 的 5 到 15 倍。这个倍数本身就是最好的验证结论。5.3 显存占用观察法最后用 nvidia-smi 复核一次。加载模型后观察显存占用是否稳定停留在模型体积加 KV cache 的水平。以 8GB 显存跑 7B 模型为例加载后应该看到接近 7GB 的占用说明 KV cache 也已经预留在显存里。如果显存占用只有一点点比如 200MB 以下那明显不对如果显存占用正常但GPU-Util为 0可能需要检查是不是有别的进程占用了 GPU 计算资源比如其他训练任务把 GPU 占满了Ollama 排队等不到计算时间片表面上看起来像没在用 GPU。6. 应急恢复 CPU 模式与日常预防建议6.1 强制回退的应急手段虽然我们这篇文章的目标是让模型跑在 GPU 上但有一种情况需要反过来操作当你手头只有 CPU 环境或者驱动已经损坏来不及修又必须马上用模型时显式禁用 GPU 反而更稳定。方法很简单export OLLAMA_NUM_GPU0或者在启动每个模型时通过 API 指定curl http://localhost:11434/api/generate -d { model: llama3.2, prompt: test, options: {num_gpu: 0} }这样至少可以保证行为可预期不会出现部分回退造成的不稳定体验。等驱动修好再改回 -1 即可。6.2 我的启动前检查清单排障排多了之后我给自己总结了一条固定检查路径每次部署新机器都按顺序走一遍耗时不超过五分钟nvidia-smi确认驱动版本满足 CUDA 12 要求记录显卡型号和显存。env | grep OLLAMA检查所有 Ollama 相关环境变量确保 OLLAMA_NUM_GPU 不存在或为 -1。ollama --version确认 Ollama 版本较新老版本对新型号显卡的支持可能不完整。ollama run 小模型跑一个 1B 级别的模型做冒烟测试确认 GPU 基本路径通畅。ollama ps查看 PROCESSOR 是否为 100% GPU。日志中确认offload 全部层到 GPU的锚点记录。如果这六步全部通过再跑大模型基本上不会再出现装好显卡却用不上的尴尬。其中任何一步异常都能快速定位到驱动层、进程层、调度层或容器层的具体问题不需要反复重装碰运气。这套方法我用了大半年从 Linux 裸机到 Docker 容器再到 WSL2都能覆盖到。如果你卡在某一步过不去建议把 Ollama 前台日志打开把offload和GPU相关的行贴出来基本上离真相就不远了。
RELATED

相关推荐

极寒冰雪旅运背后:苏州金龙×海格旅汽如何破解客车冬季运营难题

极寒冰雪旅运背后:苏州金龙×海格旅汽如何破解客车冬季运营难题

2023年底那波冰雪旅游热,我是真真切切感受了一回。朋友圈里全是雪乡、亚布力、冰雪大世界的视频,但作为常年关注客车行业、跟旅运企业打交道比较多的人,我看到的不只是热搜上的热闹场景,还有一个更现实的画面:机场大巴…

📅 2026/9/11 3:07:34
700+免费公开API清单:public-api-lists 快速筛选接口指南

700+免费公开API清单:public-api-lists 快速筛选接口指南

700免费公开API清单:public-api-lists 快速筛选接口指南 【免费下载链接】public-api-lists A curated list of free public APIs — searchable, community-maintained, with a free JSON API. 项目地址: https://gitcode.com/GitHub_Trending/pu/public-api-lis…

📅 2026/9/11 3:07:34
部署DeepSeek Harness:把大模型变成团队统一协作基础设施

部署DeepSeek Harness:把大模型变成团队统一协作基础设施

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/11 3:07:34
MORE NEWS

更多资讯

📰

安全锥AI检测系统:YOLO多版本实战选型与边缘部署

1. 这不是又一个YOLO Demo:安全锥检测系统的真实战场逻辑你搜“yolov8训练自己的数据集”,点开前十个教程,八成在教你怎么用COCO格式跑通一个猫狗分类;你查“springboot配置”,文档里全是application.yml里加个server.…

📰

亮数据API:一句话生成爬虫脚本的革新体验

1. 项目概述:用一句话生成爬虫脚本的革新体验 最近在数据采集领域出现了一个颠覆性的工具——亮数据API。这个服务最吸引我的地方在于,它真正实现了"一句话生成爬虫脚本"的承诺。作为一名长期与数据打交道的开发者,我亲测后发现&am…

📰

Agent六大核心:从LLM到Orchestration的工程化落地指南

1. 这不是概念复习,是重新校准你对智能体的认知坐标系“从LLM到Agent、Agent的6大核心。这些基础知识你还记得吗”——这句话乍看像知识测验,实则是一次认知重启的信号。我带过二十多个落地型AI项目,从金融风控对话引擎到工业设备预测性维护助…

📰

多用户MIMO块对角化预编码:零空间投影与SVD实现详解

简介:多用户MIMO系统在现代无线通信中依靠多根天线提升数据传输速率和系统容量,但在服务多个用户时,用户间干扰成为核心挑战。块对角化(BD)预编码可将各用户信号空间分解到相互正交的子空间中,使不同用户的…

📰

零成本实现Clawdbot与飞书、Telegram双平台集成

1. 项目概述:零成本玩转Clawdbot与双平台集成Clawdbot作为一款新兴的自动化工具,其"满血版"通常需要付费订阅才能解锁全部功能。但通过合理的配置和开源方案组合,我们完全可以实现零成本使用全部核心功能。这次我将分享如何在不支付…

📰

售货柜识别流水线实战:从IPC拉流到YOLO推理的全链路解析

做售货柜项目最容易被低估的,就是“从摄像头到最终识别结果”这整条链路。很多人把精力全压在模型训练上,觉得只要YOLO跑通、精度够高就完事了,结果一上真机,画面卡顿、识别延迟、偶发漏检,问题全堆在流水线上。这篇就…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬