显存不足怎么办:本地大模型 OOM 排查清单(Ollama 与 llama.cpp) - 显存不足怎么办

显存不足怎么办:本地大模型 OOM 排查清单(Ollama 与 llama.cpp)

模型加载失败、跑到一半崩溃,或者速度突然慢得像在爬,多半都是同一个原因:显存不够。这篇 显存不足怎么办 的清单按我们建议的顺序走一遍:先确认问题真的是显存,再依次调整上下文长度、并发数、KV 缓存和量化,最后才考虑换更小的模型或加硬件。所有设置都以 Ollama 和 llama.cpp 的官方文档为准。如果你还没搞清楚一个模型大概要多少显存,先看我们的显存选择指南,再回到这里排查。

核对说明:环境变量名、默认值和“约 1/2、约 1/4”的说法来自 Ollama 常见问题文档,--n-gpu-layers、--ctx-size、--cache-type-k 和 --fit 的说明来自 llama.cpp 服务端 README。文档会随版本变化,所以请以你所用版本为准。我们没有为这篇文章在特定显卡上复现每一种报错,算例都是假设性的。

要点速览(更新于 2026-10-30)

  • 先用 ollama ps 看模型放在哪:100% GPU 是全在显卡里,100% CPU 是全在内存里,两个百分比并列说明一部分被挪到了内存。
  • 最有效的顺序是:关掉占显存的程序,降上下文,把并发降到 1,再用 KV 缓存 q8_0,之后才换更低位的量化。

  • 上下文和并发相乘:Ollama 文档说所需内存随 OLLAMA_NUM_PARALLEL 乘以 OLLAMA_CONTEXT_LENGTH 增长。

先判断:真的是显存不足吗

“显存不足”有三种常见表现,处理方式不同。第一种是加载时就失败,日志里提示内存不足,说明模型加上上下文放不下。第二种是能加载、但跑长对话时崩溃,通常是上下文或并发把 KV 缓存撑大了。第三种最容易被忽略:没有报错,但速度很慢,原因是一部分层被放进了系统内存。

Ollama 文档给了一个简单的检查办法:运行 ollama ps,看 Processor 一列。100% GPU 表示模型整个在显卡里,100% CPU 表示整个在系统内存里,像 48%/52% CPU/GPU 这样的写法表示部分在显卡、部分在内存。如果你预期它全在显卡里,却看到了混合或纯 CPU,那就是显存不够,Ollama 悄悄帮你做了卸载。这种情况的原理见我们的内存与显存卸载指南。

下面这张表把三种表现和最可能的原因、最先该做的事对应起来,方便你快速定位。

表现 最可能的原因 最先做什么
加载时就失败 权重加上上下文放不下 降低上下文,或换更低位的量化文件
长对话中途崩溃 KV 缓存随上下文和并发增长 降上下文,并发设为 1,量化 KV 缓存
不报错但很慢 部分层被放进了系统内存 用 ollama ps 确认,再按下面的顺序省显存
换模型后突然不行 旧模型还驻留在显存里 ollama stop 卸载旧模型

如果 ollama ps 显示全在 GPU,却仍然报错,别急着加显存,先排除另一类问题:驱动或 GPU 没被识别。这类问题的排查在显卡排障文章里,不属于显存不足。

显存不足的排查顺序:看现象、看占用、先降上下文和并发、再换量化或更小模型、最后才加硬件
图 1:显存不足时的排查顺序

第一步:看清到底谁在占显存

在做任何调整之前,先看实际占用。NVIDIA 显卡用 nvidia-smi,它会列出显存总量、已用量和占用显存的进程。浏览器的硬件加速、视频播放器、另一个推理程序、还没卸载的旧模型,都会和你的模型抢同一块显存。

Ollama 默认会把模型在内存里保留 5 分钟,之后才卸载,文档里说明了这一点。所以你刚换了一个模型再加载另一个,旧的可能还占着显存。用 ollama stop 模型名 可以立即卸载,也可以通过 API 的 keep_alive 参数设为 0 来卸载。反过来,如果你想让模型常驻,keep_alive 设成负数或者设置 OLLAMA_KEEP_ALIVE,但要清楚它会一直占着显存。

另外,Ollama 允许同时加载多个模型,OLLAMA_MAX_LOADED_MODELS 的默认值是 3 乘以显卡数,只要放得下就会同时加载。如果你在不同工具里用了不同模型,可能不知不觉有两三个模型同时驻留。需要时把它调小,或者让不用的模型及时卸载。

第二步:降低上下文长度

上下文长度是最常见的“隐形大户”。模型处理的每个词元都要在 KV 缓存里占一份空间,上下文越长,缓存越大。Ollama 文档写明默认的上下文窗口是 4096 个词元,可以用 OLLAMA_CONTEXT_LENGTH 环境变量改,也可以在交互里用 /set parameter num_ctx,或者在 API 里传 num_ctx。

llama.cpp 里对应的是 -c 或 --ctx-size。服务端 README 说默认值是 0,意思是从模型里读取。这一点要小心:有些模型自带的上下文很大,如果你不手动指定,它会按模型的设定去申请缓存,显存立刻就紧了。把它显式设成你真正需要的长度,比如 8192,往往就能解决问题。

一个假设性的算例可以说明思路。假设你有一块 12GB 的显卡,一个 8B 的 Q4 模型文件约 5GB 左右,权重本身绰绰有余。如果你把上下文开到 32K,KV 缓存加上运行时开销可能就把剩下的空间吃光。这时先把上下文降到 8K 再试,是代价最小的办法。KV 缓存怎么算、为什么随长度增长,见我们的上下文长度与 KV 缓存指南。

第三步:把并发降到 1

并发是第二个容易被忽略的乘数。Ollama 文档说,对一个模型做并行请求处理,会让上下文大小按并行请求数相乘,例子是 2K 上下文加 4 个并行请求等于 8K 上下文,并额外分配内存。变量 OLLAMA_NUM_PARALLEL 默认是 1,文档还说所需内存会随 OLLAMA_NUM_PARALLEL 乘以 OLLAMA_CONTEXT_LENGTH 增长。

所以,如果你为了让几个人同时用,把并发调到了 4,再加上较长的上下文,显存需求就是四倍。个人使用时保持默认的 1 就好。多人共用的场景,应该先算清楚账,再决定要不要换更大的显卡,这在我们的本地 API 服务指南里有更详细的讨论。

llama.cpp 的服务端也有类似的并行槽位设置,具体参数名请查你所用版本的 README,因为选项会随版本调整。

第四步:开启闪存注意力,并量化 KV 缓存

Ollama 文档说,闪存注意力(Flash Attention)能在上下文变大时明显减少内存占用,在后端和设备支持时 Ollama 会自动使用,也可以用 OLLAMA_FLASH_ATTENTION=1 强制打开。llama.cpp 里对应的是 -fa,取值 on、off 或 auto,默认 auto。

在闪存注意力开启的前提下,KV 缓存可以量化。Ollama 的变量是 OLLAMA_KV_CACHE_TYPE,默认 f16。文档的描述是:q8_0 用大约 f16 一半的内存,精度损失很小,通常没有明显影响,是不用 f16 时的推荐选择;q4_0 大约用四分之一,精度损失为小到中等,在更长的上下文下可能更明显。llama.cpp 的对应参数是 -ctk 和 -ctv,允许的类型包括 f16、q8_0、q4_0 等,默认 f16。

KV 缓存 f16、q8_0、q4_0 三种类型的相对内存占用条形图
图 3:KV 缓存类型的相对内存占用,来自 Ollama 文档

注意这里节省的是 KV 缓存,不是模型权重,所以它在长上下文下效果最明显;短上下文时缓存本来就小,省不了多少。文档也提醒,需要自己实验,在内存占用和质量之间找平衡。

显存不足怎么办:各种手段的效果与代价

显存不足时可用手段的对照表:关闭其他程序、降低上下文、降低并发、闪存注意力、KV 缓存量化、更低位量化
图 2:各种手段的省显存效果与代价
手段 省显存的效果 代价 我们的建议顺序
关闭其他占显存的程序 取决于程序 无 第 1 步
降低上下文长度 明显 长输入放不下 第 2 步
OLLAMA_NUM_PARALLEL 设为 1 明显 同时处理的请求变少 第 3 步
开启闪存注意力 上下文越长越明显 需要后端和显卡支持 第 4 步
KV 缓存用 q8_0 约省一半缓存 精度损失很小 第 5 步
换更低位的量化文件 很大 质量略降 第 6 步
换更小的模型 很大 能力下降 第 7 步
加显存或换显卡 最彻底 花钱 最后

表里最后一列是我们自己的建议,不是官方规定:它按“代价最小的先做”排序。

第五步:换量化文件或更小的模型

前面都做完仍然放不下,说明权重本身就太大了。这时有两条路:换更低位的量化文件,或者换更小的模型。量化的原理和各档的取舍,见我们的量化指南,一般的规律是位数越低文件越小,质量也会略降。

我们的经验法则是:宁可用小一档但量化较好的模型,也不要用大一档但压得很狠的模型。比如 14B 的 Q3 文件和 8B 的 Q6 文件大小可能接近,但后者通常更稳。这是经验判断,不是实测结论。模型尺寸选择指南用同样的思路讲了怎么按显存选尺寸。

llama.cpp 还有一个值得知道的选项:-ngl,也叫 --n-gpu-layers,控制放进显存的层数,默认值是 auto,可以是具体数字、auto 或 all。你可以手动让它少放几层,把剩下的放在内存里,这样能运行更大的模型,代价是速度。服务端 README 还写到 --fit 选项默认是 on,意思是会自动调整没有设置的参数以适应设备内存,--fit-target 的默认余量是每个设备 1024 MiB。也就是说,在较新的版本里,llama.cpp 会尽量自己帮你避开爆显存,但如果你手动写死了很多参数,它能调整的余地就小了。具体的参数用法见 GGUF 与 llama.cpp 入门。

一个假设性的排查例子

假设你有 12GB 显卡,用 Ollama 跑一个 14B 的 Q4 模型,聊到一半就崩了。我们会这样排:

  1. 运行 ollama ps,发现显示的是 70%/30% CPU/GPU,说明有部分层被挪到了内存,已经很吃紧。
  2. 用 nvidia-smi 看,发现浏览器还占着一部分显存,先把它关掉,再加载一次。
  3. 把 OLLAMA_CONTEXT_LENGTH 从原来的值降到 8192,确认 OLLAMA_NUM_PARALLEL 是 1。
  4. 设置 OLLAMA_FLASH_ATTENTION=1 和 OLLAMA_KV_CACHE_TYPE=q8_0,重启 Ollama 再看 ollama ps。
  5. 如果仍然有 CPU 占比,就换成 8B 模型,或同一个 14B 的更低位量化。

这只是演示方法,数字是假设的。关键是每次只改一样,改完看 ollama ps 的变化,这样你才知道哪一步真正起作用。

显存够,但内存或磁盘不够的情况

有时报错并不是显卡的问题。系统内存不足时,卸载到 CPU 的那部分也会失败;磁盘空间不够时,模型下载或解压会失败,这两种情况的提示容易和显存不足混淆。看到“out of memory”时,先看是哪一类:是 CUDA 报的,还是系统报的。在 Windows 上通过 WSL 2 运行时,WSL 本身的内存上限也会限制你,设置方法见WSL 2 与 Docker 指南。

如果你的显卡只有 8GB 或更少,很多问题其实是预期之内的,换一个小一点的模型比反复调参更省事,见 12GB 与 16GB 显存指南里对不同容量能放什么的讲解。

常见错误

  • 一上来就买显卡。 多数爆显存的原因是上下文或并发,调设置就能解决。
  • 只看模型文件大小。 实际占用还有 KV 缓存和运行时开销,要留余量。
  • 一次改太多。 同时改五个设置,你不知道哪个起了作用。
  • 忘了旧模型还在显存里。 用 ollama ps 检查,用 ollama stop 卸载。
  • 把 KV 缓存量化当成万能药。 它只省缓存,对权重没用,短上下文时效果有限。
  • 把 q4_0 缓存用在很长的上下文上。 文档提醒精度损失在长上下文下更明显。

常见问题

显存不足会让模型变慢吗?

会。当部分层被放进系统内存时,不会报错,但速度会明显下降。用 ollama ps 的 Processor 一列确认是不是全在 GPU。

为什么模型文件才 5GB,12GB 显卡还爆了?

因为除了权重,还要为 KV 缓存和运行时开销留空间,上下文越长、并发越多,缓存越大。

Ollama 的默认上下文是多少?

按当前常见问题文档,默认是 4096 个词元,可以用 OLLAMA_CONTEXT_LENGTH 修改。请以你安装的版本文档为准。

KV 缓存量化会损失多少质量?

文档说 q8_0 的精度损失很小,通常没有明显影响,q4_0 的损失为小到中等,在长上下文下可能更明显。我们没有自己测过具体数字。

怎么让 Ollama 立刻释放显存?

运行 ollama stop 模型名,或者在 API 里把 keep_alive 设成 0。默认情况下,模型会在内存里保留 5 分钟。

llama.cpp 怎么控制放进显存的层数?

用 -ngl 或 --n-gpu-layers,可以填具体数字、auto 或 all。默认是 auto。

和我们聊聊

把你的显卡型号、模型和报错信息发到社区,我们帮你排查,或者发邮件到 admin@microaione.com。

参考资料:Ollama 常见问题、Ollama 排障文档、llama.cpp 服务端 README、NVIDIA nvidia-smi 文档。

类似文章