> ## Content Index
> Fetch the complete content index at: https://isoziyuan.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Ollama 显存不足怎么解决？从 CUDA out of memory、上下文长度到 GGUF 量化与 CPU 回退的完整排查指南
- URL: https://isoziyuan.com/p/100121/
- Published: 2026-08-31T17:33:58.000Z
- Updated: 2026-08-31T17:33:58.000Z
- Author: Isoziyuan
- Tags: Ollama, AI工具, 本地大模型, 性能优化

当 Ollama 报出 `CUDA out of memory`、模型加载失败，或者明明安装了显卡却显示主要使用 CPU 时，问题通常不只是“显存太小”。

在实际环境中，**模型权重、上下文长度、KV Cache、并发请求、量化格式、其他 GPU 进程以及容器配置**都会影响显存占用。错误地调整其中任何一项，都可能让原本能够运行的模型突然 OOM。

本文给出一套可复现的排查流程，适用于 Linux、Windows、WSL2、Docker，以及使用 NVIDIA GPU 的常见 Ollama 部署。AMD ROCm 和 Apple Silicon 的底层内存机制有所不同，但多数分析思路仍然适用。

> 本文以 **2026 年 8 月**的使用场景为背景。Ollama 的环境变量、默认上下文策略和硬件后端仍可能随版本调整，执行前请通过 `ollama --version` 查看当前版本，并复核对应版本的官方文档。

## 先给结论：Ollama 显存究竟被什么占用了

运行一个本地大模型时，显存消耗大致来自以下部分：

```text
总显存需求
≈ 模型权重
+ KV Cache
+ 推理计算缓冲区
+ CUDA/驱动运行时开销
+ 并发副本开销
+ 其他 GPU 进程占用

```

其中最容易被忽略的是 **KV Cache**。

很多用户看到一个 Q4 模型文件只有 5 GB，就认为 8 GB 显卡一定能够运行。但 GGUF 文件大小主要反映量化后的模型权重，并不等于完整运行显存。

如果将上下文从 4K 提高到 32K，权重大小虽然没有变化，KV Cache 和相关计算缓冲区却可能显著增长。再叠加并发请求，最终就会触发：

```text
CUDA out of memory

```

或者出现以下现象：

- 模型只能部分加载到 GPU；
- Ollama 自动将部分层回退到 CPU；
- 首个 Token 等待时间明显变长；
- GPU 利用率忽高忽低；
- 系统内存持续增长；
- 多模型同时运行时突然 OOM。

因此，排查 **Ollama 显存不足**，不能只盯着模型文件大小。

## 第一步：确认到底是不是 CUDA 显存不足

### 查看 Ollama 与显卡状态

先记录基础信息：

```bash
ollama --version
nvidia-smi
ollama ps

```

`nvidia-smi` 重点查看：

- GPU 型号；
- 显存总量；
- 当前显存占用；
- 是否存在浏览器、桌面程序、训练任务等其他 GPU 进程；
- 是否能看到 Ollama 相关进程。

`ollama ps` 通常可以看到当前已加载模型及其处理器分配情况。不同版本的字段显示可能略有差异，重点关注 `PROCESSOR`：

```text
100% GPU

```

表示模型主要或全部由 GPU 执行。

如果看到类似：

```text
60% GPU / 40% CPU

```

则说明模型进行了部分 CPU 回退。

如果完全显示 CPU，才需要继续检查为什么 **Ollama 没有使用 GPU**。

> `ollama ps` 显示的是 Ollama 当前运行状态；`nvidia-smi` 显示的是 CUDA 驱动视角。两者应结合判断，不能只看其中一个。

### 检查 Ollama 服务日志

Linux 使用 systemd 安装 Ollama 时，可以执行：

```bash
journalctl -u ollama --no-pager -n 200

```

持续查看日志：

```bash
journalctl -u ollama -f

```

Docker 部署则使用：

```bash
docker logs --tail 200 ollama

```

持续跟踪：

```bash
docker logs -f ollama

```

容器名称不是 `ollama` 时，请替换为实际名称。

日志中建议搜索以下关键词：

```text
CUDA
out of memory
VRAM
GPU
offload
CPU
runner
memory

```

需要区分以下几种情况：

| 现象            | 更可能的原因                   |
| ------------- | ------------------------ |
| 模型加载阶段立即 OOM  | 权重放不下，或剩余显存不足            |
| 长提示词输入时 OOM   | 上下文过长，KV Cache 或预填充缓冲区过大 |
| 单请求正常，多请求 OOM | 并发导致上下文和计算资源叠加           |
| 能运行但速度很慢      | 大量模型层回退到 CPU             |
| 完全没有 CUDA 记录  | 驱动、容器透传或服务环境有问题          |
| 重启后暂时恢复       | 其他模型常驻、显存碎片或并发任务积累       |

## 第二步：先释放显存，再做变量隔离

不要一上来就重装 CUDA。先清理能够确定的显存占用。

### 卸载 Ollama 中暂时不用的模型

查看当前模型：

```bash
ollama ps

```

停止指定的常驻模型：

```bash
ollama stop 模型名称

```

例如模型名称应以本机 `ollama ps` 或 `ollama list` 的实际输出为准。

再次检查：

```bash
ollama ps
nvidia-smi

```

如果通过 API 调用模型，也可以在请求中设置：

```json
{
  "keep_alive": 0
}

```

这会让模型在请求结束后卸载，而不是继续常驻。下面是一个完整示例：

```bash
curl http://localhost:11434/api/generate \
  -d '{
    "model": "你的模型名称",
    "prompt": "请用三句话解释 KV Cache。",
    "keep_alive": 0,
    "stream": false
  }'

```

对于频繁调用的生产服务，立即卸载会增加后续加载延迟。因此它更适合故障排查、低频调用或显存极其紧张的环境。

### 清理其他 GPU 进程

执行：

```bash
nvidia-smi

```

确认是否有以下程序占用显存：

- Stable Diffusion 或 ComfyUI；
- PyTorch、TensorFlow 训练任务；
- 另一个 Ollama 实例；
- vLLM、llama.cpp 等其他推理服务；
- 视频编码、游戏或图形程序；
- 容器中未退出的任务。

不要直接杀死不认识的系统进程。先确认 PID 对应程序：

```bash
ps -fp PID

```

如果清理其他进程后模型可以正常加载，说明问题不是 Ollama 本身，而是**可用显存不足**。

## 第三步：降低大模型上下文长度设置

### 为什么上下文长度会吃掉大量显存

上下文包括：

- 系统提示词；
- 用户输入；
- 历史对话；
- 工具调用内容；
- 检索增强生成返回的文档；
- 已生成或计划生成的 Token。

模型推理时需要为这些 Token 保存注意力相关状态，即 KV Cache。

在不考虑特殊优化的情况下，KV Cache 占用与以下因素近似成正比：

```text
KV Cache
≈ 上下文 Token 数
× 模型层数
× KV 头数量
× 每个头的维度
× 数据精度
× 2

```

最后的 `2` 代表 Key 和 Value。

这不是可以直接套用到所有模型的精确显存公式，因为不同架构可能采用 GQA、MQA、滑动窗口注意力、混合层结构或不同的 KV 数据类型。但它足以解释一个核心规律：

> **上下文长度翻倍，KV Cache 通常也会近似线性增长。**

此外，并发请求可能分别维护自己的上下文状态。单请求 16K 能运行，不代表四个并发 16K 也能运行。

### 通过 API 设置 `num_ctx`

调用 `/api/generate` 时可以这样限制上下文：

```bash
curl http://localhost:11434/api/generate \
  -d '{
    "model": "你的模型名称",
    "prompt": "分析这段文本。",
    "options": {
      "num_ctx": 4096,
      "num_predict": 512
    },
    "stream": false
  }'

```

对话接口示例：

```bash
curl http://localhost:11434/api/chat \
  -d '{
    "model": "你的模型名称",
    "messages": [
      {
        "role": "user",
        "content": "解释为什么上下文长度会影响显存。"
      }
    ],
    "options": {
      "num_ctx": 4096,
      "num_predict": 512
    },
    "stream": false
  }'

```

建议按以下顺序测试：

```text
2048 → 4096 → 8192 → 16384

```

每次只修改一个变量，并同时观察：

```bash
watch -n 1 nvidia-smi

```

Windows PowerShell 可以重复执行：

```powershell
nvidia-smi

```

如果 4K 正常、16K OOM，就已经基本确认是上下文相关问题，而不是模型文件损坏或 CUDA 完全不可用。

### 通过 Modelfile 固化上下文长度

创建一个 `Modelfile`：

```dockerfile
FROM 你的基础模型名称

PARAMETER num_ctx 4096
PARAMETER num_predict 512

```

然后创建新模型：

```bash
ollama create my-low-vram-model -f Modelfile

```

运行：

```bash
ollama run my-low-vram-model

```

这种方式适合把低显存参数固化下来，避免每个客户端分别设置。

### 不要把“模型支持的最大上下文”当成推荐值

模型架构支持 32K、128K 甚至更长上下文，不代表你的硬件应该直接设到最大值。

应区分三个概念：

1. **训练或架构允许的最大上下文；**
2. **Ollama 当前实际配置的上下文；**
3. **你的显存和延迟可以承受的上下文。**

生产环境应从业务实际需要出发，而不是追求最大数字。普通问答和代码补全通常未必需要超长上下文；RAG 系统也不应把所有检索结果无差别塞进提示词。

## 第四步：正确选择 GGUF 量化版本

### 量化降低的是权重，不是全部运行内存

GGUF 模型常见量化标识包括：

- `Q8_0`
- `Q6_K`
- `Q5_K_M`
- `Q5_K_S`
- `Q4_K_M`
- `Q4_K_S`
- `Q3_K_M`
- `Q2_K`

一般来说，位宽越低：

- 模型文件越小；
- 权重占用越低；
- 更容易完整加载到 GPU；
- 输出质量损失风险越高；
- 某些硬件上的速度未必单调提升。

其中 `_K` 表示 K-quant 系列；`_M` 和 `_S` 涉及不同张量的量化组合。不能简单理解为所有 `_M` 都一定更快，或所有 `_S` 都一定更省显存到相同比例。

### 低显存环境的实用选择

下面是经验性而非绝对的选择策略：

| 场景          | 可优先考虑             |
| ----------- | ----------------- |
| 显存较充裕，更重视质量 | Q6\_K、Q8\_0       |
| 质量、体积与速度平衡  | Q5\_K\_M、Q4\_K\_M |
| 显存非常紧张      | Q4\_K\_S、部分 Q3 版本 |
| 仅验证能否运行     | 更低量化或更小参数模型       |
| 对精度敏感的专业任务  | 先缩小模型，再谨慎降低量化位宽   |

**`Q4_K_M` 常被视为通用平衡点，但不是所有模型和硬件的最佳答案。**

语言模型、视觉语言模型、MoE 模型以及代码模型的运行内存结构可能明显不同。尤其是多模态模型，还可能加载视觉编码器等附加组件。

### 模型参数规模通常比量化微调更重要

如果 14B 模型即使使用低量化仍需要大量 CPU 回退，那么切换到质量更好的 7B 或 8B 模型，往往比强行运行 14B 更实用。

例如，仅用于粗略理解：

```text
理论权重大小 ≈ 参数量 × 每参数位数 ÷ 8

```

一个 8B 参数的 4-bit 模型，其理论纯权重下限约为：

```text
8,000,000,000 × 4 ÷ 8 ≈ 4 GB

```

但实际 GGUF 文件和运行内存通常会更大，因为还包含：

- 未按相同位宽量化的张量；
- 词表与元数据；
- 对齐和格式开销；
- KV Cache；
- 计算缓冲区；
- CUDA 运行时开销。

因此，“8B Q4 等于准确占用 4 GB”是错误判断。

### 导入本地 GGUF 时注意模板与兼容性

如果需要导入本地 GGUF，可以创建：

```dockerfile
FROM ./model.gguf

```

然后执行：

```bash
ollama create my-gguf-model -f Modelfile

```

但随机下载 GGUF 存在几个风险：

- 文件可能不完整；
- 量化工具版本过旧；
- 聊天模板不匹配；
- 模型架构尚未被当前 Ollama 后端完整支持；
- 分词器或特殊 Token 配置异常；
- 多模态模型可能还需要额外组件。

因此，优先使用来源明确、校验完整、与当前 Ollama 版本兼容的模型。具体可用标签和量化版本会变化，应以模型发布页和 Ollama 模型库的实时信息为准。

## 第五步：排查 Ollama 没有使用 GPU

如果模型完全在 CPU 上运行，或者日志中找不到 CUDA 后端，需要从驱动层开始排查。

### 先验证宿主机驱动

执行：

```bash
nvidia-smi

```

如果命令本身失败，优先解决：

- NVIDIA 驱动未安装；
- 驱动模块未加载；
- 驱动与内核不兼容；
- WSL2 GPU 支持异常；
- 虚拟机未配置 GPU 直通。

**安装 CUDA Toolkit 并不是所有 Ollama 场景的必要前提，但可用且兼容的 NVIDIA 驱动是基础条件。**

不要看到 CUDA 报错就反复安装多个 Toolkit 版本。先确认 `nvidia-smi` 正常，再看 Ollama 日志识别到了什么后端。

### 确认服务进程能看到 GPU

一个高频错误是：

> 在终端设置了环境变量，但 Ollama 实际由 systemd、Docker 或桌面程序启动。

此时变量只对当前终端生效，对 Ollama 服务进程无效。

Linux systemd 可以查看服务配置：

```bash
systemctl status ollama
systemctl cat ollama

```

如果需要开启调试日志，可执行：

```bash
sudo systemctl edit ollama

```

加入：

```ini
[Service]
Environment="OLLAMA_DEBUG=1"

```

然后应用配置：

```bash
sudo systemctl daemon-reload
sudo systemctl restart ollama
journalctl -u ollama -f

```

排查结束后，可以删除调试配置或将其关闭，避免日志过多。

### Docker 必须正确透传 GPU

检查容器：

```bash
docker inspect ollama

```

同时在宿主机查看：

```bash
nvidia-smi

```

Docker 场景通常需要：

- 宿主机 NVIDIA 驱动正常；
- 安装并配置 NVIDIA Container Toolkit；
- 创建容器时声明 GPU 设备；
- 容器运行时没有被错误限制。

如果容器启动时未获得 GPU 权限，那么容器内的 Ollama 即使能够正常响应，也可能只使用 CPU。

修改 GPU 参数后，通常需要**重新创建容器**，仅在旧容器内部重启 Ollama 未必能改变设备分配。

### 检查 GPU 可见性变量

如果设置过：

```bash
CUDA_VISIBLE_DEVICES

```

需要确认它没有隐藏目标显卡。

查看当前终端变量：

```bash
echo "$CUDA_VISIBLE_DEVICES"

```

但要注意：systemd 服务、Docker 容器和桌面应用拥有各自的环境。当前 Shell 中的值不一定代表 Ollama 服务实际看到的值。

多 GPU 环境还应检查：

- Ollama 是否看到了正确的 GPU；
- 某张卡是否已被其他任务占满；
- 容器是否只暴露了一张卡；
- GPU 序号与预期是否一致；
- MIG 或虚拟化切分是否限制了可用显存。

## 第六步：控制并发与常驻模型数量

单用户测试正常、接入应用后 OOM，通常与并发有关。

### 为什么并发会放大显存需求

并发可能带来：

- 多个请求分别维护 KV Cache；
- 更大的批处理缓冲区；
- 多个模型同时驻留；
- 长短请求互相叠加；
- 请求结束后模型继续常驻。

因此，排查时应先建立单请求基线：

1. 停止其他模型；
2. 只发送一个请求；
3. 使用 2K 或 4K 上下文；
4. 限制输出长度；
5. 观察显存峰值；
6. 再逐步增加并发。

Ollama 提供过与并行请求、模型常驻数量和默认上下文有关的服务端配置，但具体环境变量及默认行为可能随版本变化。使用前应对照当前版本官方文档，不要直接照搬旧教程中的参数。

无论使用哪一版本，都应遵循同一个原则：

> **先把并发降到 1 验证，再逐项提高，不要同时修改上下文、模型量化和并发。**

## 第七步：理解 CPU 回退——它不一定是故障

### 什么是 CPU 回退

当模型不能完全放入显存时，Ollama 的底层推理后端可能将部分模型层放在 GPU，其余部分放在系统内存中由 CPU 执行。

这使低显存设备仍有机会运行较大模型，但代价是：

- 推理速度下降；
- 首 Token 延迟增加；
- CPU 占用升高；
- 系统内存占用增加；
- GPU 与 CPU 之间的数据传输成为瓶颈。

因此，看到部分 CPU 并不意味着 GPU 完全失效。

通过：

```bash
ollama ps

```

如果处理器分配显示 GPU 与 CPU 混合，就说明正在进行部分卸载。

### 什么时候 CPU 回退是可接受的

适合 CPU 回退的场景：

- 低频个人问答；
- 离线总结；
- 对响应时间不敏感；
- 只需验证模型能力；
- 系统内存充足。

不适合的场景：

- 实时语音对话；
- IDE 代码补全；
- 高并发 API；
- 长上下文 RAG；
- 对首 Token 延迟敏感的产品。

如果大量层回退到 CPU，与其持续优化边缘参数，通常不如：

1. 换更小参数规模的模型；
2. 选择更合适的 GGUF 量化；
3. 缩短上下文；
4. 限制并发；
5. 减少同时常驻的模型。

### 系统内存也可能成为瓶颈

CPU 回退并不意味着内存需求消失，而是从显存转移到系统内存。

Linux 可以查看：

```bash
free -h

```

持续观察：

```bash
watch -n 1 free -h

```

如果系统开始大量使用 Swap，即使模型没有崩溃，速度也可能降到不可接受。

本地 AI 低显存方案必须同时考虑：

- 显存容量；
- 系统内存容量；
- 内存带宽；
- PCIe 传输；
- CPU 性能；
- 上下文长度；
- 可接受延迟。

## 第八步：按症状选择解决方案

### 症状一：加载模型时立即 CUDA OOM

优先操作：

1. 关闭其他 GPU 程序；
2. 停止 Ollama 中不用的模型；
3. 换更小参数规模；
4. 改用更低位 GGUF 量化；
5. 将上下文降到 2K 或 4K；
6. 重启 Ollama 服务后重新测试。

如果模型权重本身就超过可用显存，降低输出长度通常解决不了根本问题。

### 症状二：短提示正常，长文档 OOM

优先操作：

1. 降低 `num_ctx`；
2. 减少 RAG 返回文档数量；
3. 对历史消息做摘要；
4. 限制单段文档长度；
5. 限制最大输出 Token；
6. 关闭不必要的并发。

这是典型的**上下文与 KV Cache 问题**。

### 症状三：第一个请求正常，后续请求 OOM

检查：

- 模型是否持续常驻；
- 是否同时加载多个模型；
- 客户端是否重复建立并发请求；
- 请求超时后，服务端任务是否仍在执行；
- 是否有长对话历史不断累积；
- 应用是否把完整历史每次都重新发送。

可以暂时使用：

```json
{
  "keep_alive": 0
}

```

验证是否与模型常驻有关。

### 症状四：GPU 有占用，但生成非常慢

查看：

```bash
ollama ps
nvidia-smi

```

如果模型只有少部分在 GPU 上，问题通常是大量 CPU 回退。

优化优先级应为：

```text
缩小模型参数量
> 选择合适量化
> 缩短上下文
> 关闭其他显存占用
> 再考虑接受部分 CPU 回退

```

### 症状五：完全没有使用 GPU

检查顺序：

```text
nvidia-smi 是否正常
→ Ollama 日志是否识别 CUDA
→ 服务进程是否能看到 GPU
→ Docker 是否透传 GPU
→ CUDA_VISIBLE_DEVICES 是否隐藏设备
→ 当前模型是否真的正在运行

```

不要只根据任务管理器中的瞬时 GPU 百分比判断。Token 生成负载可能呈脉冲式变化，显存占用和 `ollama ps` 往往更有参考价值。

## 一套可直接执行的最小化排查流程

下面这套流程适合快速定位大多数 Ollama CUDA out of memory 问题。

### 1\. 记录环境

```bash
ollama --version
nvidia-smi
ollama list
ollama ps

```

### 2\. 停止无关模型

```bash
ollama stop 实际模型名称

```

对 `ollama ps` 中暂时不用的模型逐个执行。

### 3\. 查看日志

Linux：

```bash
journalctl -u ollama --no-pager -n 200

```

Docker：

```bash
docker logs --tail 200 ollama

```

### 4\. 使用低上下文、低输出长度测试

```bash
curl http://localhost:11434/api/generate \
  -d '{
    "model": "你的模型名称",
    "prompt": "只回答：测试成功。",
    "options": {
      "num_ctx": 2048,
      "num_predict": 32
    },
    "keep_alive": 0,
    "stream": false
  }'

```

### 5\. 同时监控显存

```bash
watch -n 1 nvidia-smi

```

### 6\. 根据结果分支判断

- **仍在加载阶段 OOM**：换更小模型或更低量化；
- **能够运行但使用 CPU**：检查 GPU 配置，或接受部分回退；
- **2K 正常、长上下文 OOM**：降低 `num_ctx`；
- **单请求正常、并发 OOM**：限制并发和常驻模型；
- **日志完全无 CUDA**：排查驱动、服务环境和容器透传。

## 常见误区

### 误区一：GGUF 文件小于显存，就一定能运行

错误。文件大小不包含完整 KV Cache、计算缓冲区和运行时开销。

### 误区二：上下文越长越好

错误。更长上下文意味着更高显存、首 Token 延迟和处理成本，而且模型未必能有效利用全部内容。

### 误区三：安装 CUDA Toolkit 就能解决所有问题

错误。Ollama 是否使用 GPU，首先取决于驱动、硬件支持、运行环境和服务进程能否访问设备。反复混装 Toolkit 甚至可能增加环境复杂度。

### 误区四：只要 GPU 利用率不是 100%，就是没用 GPU

错误。大模型推理存在加载、预填充、逐 Token 解码和 CPU 调度阶段，GPU 利用率不一定持续满载。

### 误区五：CPU 回退等于完全没用 GPU

错误。CPU/GPU 混合卸载仍然会使用 GPU，只是性能取决于实际卸载比例与数据传输开销。

### 误区六：直接把量化降到最低一定最好

错误。过低量化可能损失输出质量，而且速度不一定线性提升。很多情况下，**更小模型的中等量化**优于更大模型的极低量化。

## 低显存部署的推荐策略

如果你只有有限显存，可以采用以下组合：

1. **优先选择更小参数规模的模型；**
2. 从 `Q4_K_M` 或相近中等量化开始测试；
3. 默认上下文先设为 4096；
4. 将最大输出限制在业务真正需要的范围；
5. 单模型、单并发建立基线；
6. 不使用的模型及时卸载；
7. RAG 只返回高相关片段；
8. 定期压缩对话历史；
9. 用 `ollama ps` 检查是否发生大量 CPU 回退；
10. 用真实任务评测质量，而不是只比较量化文件大小。

如果 4K 上下文、单并发和中等量化仍然无法稳定运行，那么继续微调参数的收益通常有限，应该直接换更小模型。

## 最终排查清单

遇到 Ollama 显存不足时，按以下顺序检查：

- \[ \] `nvidia-smi` 能否正常识别 GPU；
- \[ \] Ollama 日志是否加载了 CUDA 后端；
- \[ \] `ollama ps` 显示 GPU、CPU 还是混合运行；
- \[ \] 是否有其他程序占用大量显存；
- \[ \] 是否同时常驻多个模型；
- \[ \] 模型参数规模是否超出硬件能力；
- \[ \] GGUF 量化版本是否过大；
- \[ \] `num_ctx` 是否设置得过高；
- \[ \] RAG 和历史对话是否塞入过多 Token；
- \[ \] 是否存在多请求并发；
- \[ \] Docker 是否正确透传 GPU；
- \[ \] 服务进程是否继承了正确环境变量；
- \[ \] 系统内存和 Swap 是否成为新瓶颈。

## 总结

解决 **Ollama 显存不足**，最有效的方法不是盲目重装驱动，而是先明确显存消耗发生在哪一层：

- 权重放不下，就换小模型或更低量化；
- 长提示词触发 OOM，就降低上下文；
- 多请求才 OOM，就限制并发；
- 模型很慢，就检查 CPU 回退比例；
- 完全没有 GPU，就排查驱动、服务环境和容器透传。

一个可靠的排查原则是：

> **先用小上下文、单并发、单模型建立可运行基线，再一次只增加一个变量。**

只要严格区分模型权重、KV Cache、量化版本、并发和 CPU 回退，大多数 `Ollama CUDA out of memory` 问题都能被快速定位，而不必在 CUDA、驱动和模型文件之间反复试错。