首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >​从 100% CPU 到接近 100% GPU:一次完整的 Ollama 本地大模型加速优化实录

​从 100% CPU 到接近 100% GPU:一次完整的 Ollama 本地大模型加速优化实录

原创
作者头像
云帆沧海
发布2026-08-10 17:18:04
发布2026-08-10 17:18:04
140
举报
文章被收录于专栏:人工智能人工智能

从 100% CPU 到接近 100% GPU:一次完整的 Ollama 本地大模型加速优化实录

一、问题背景

最近在本地部署 Ollama 运行大模型时,遇到了一个非常典型的问题:

  • 硬件配置:NVIDIA GeForce RTX 3090 (24GB 显存) + 64GB 系统内存
  • Ollama 版本:0.32.6
  • 操作系统:Windows 11
  • 现象 1(初始):Ollama 完全不能调用 GPU,ollama ps 显示 PROCESSOR: 100% CPU
  • 现象 2(重装后):虽然能调用 GPU 了,但 GPU 利用率只有 17%,系统内存被拉满,GPU/CPU 模型分层比例为 79%/21%

本文记录了从诊断到彻底优化的完整过程,希望能帮到遇到类似问题的朋友。


二、问题一:完全无法调用 GPU —— 诊断与修复

2.1 初步排查

拿到问题后,首先做了几件事:

代码语言:powershell
复制
# 1. 确认 GPU 驱动正常
nvidia-smi

# 2. 确认 Ollama 版本
ollama --version

# 3. 查看模型实际运行状态
ollama ps

关键输出:

代码语言:python
复制
NAME          ID              SIZE      PROCESSOR    CONTEXT
qwen3.5:9b    6488c96fa5fa    6.1 GB    100% CPU     4096

问题确认:6GB 的小模型竟然也 100% 用 CPU 跑,显然不是显存不够的问题,而是 Ollama 根本没有识别到 GPU。

2.2 深挖日志:启动 GPU 调试模式

Ollama 提供了 OLLAMA_DEBUG=1 环境变量来输出详细日志。我们先停止所有 Ollama 进程,然后手动启动:

代码语言:powershell
复制
Stop-Process -Name "ollama*" -Force
$env:OLLAMA_DEBUG = "1"
ollama serve

这一步让我们发现了关键报错:

代码语言:python
复制
level=INFO  msg="discovering available GPUs..."
level=DEBUG msg="llama-server discovery: stopped subprocess after collecting GPU info" exit=1
level=DEBUG msg="evaluating which, if any, devices to filter out" initial_count=0
level=INFO  msg="inference compute" id=cpu library=cpu name=cpu

核心线索llama-server 在 GPU 发现阶段异常退出(exit=1),检测到的 GPU 数量 initial_count=0,最终只能回退到 cpu 计算后端。

2.3 直接用 llama-server 验证

为了排除 Ollama Go 语言外壳的问题,我们直接调用底层的 llama-server.exe

代码语言:powershell
复制
Set-Location "C:\Users\Admin\AppData\Local\Programs\Ollama\lib\ollama"
.\llama-server.exe --list-devices

输出:

代码语言:python
复制
Available devices:
  (none)

实锤了:llama.cpp 层面就看不到任何 GPU 设备。

2.4 检查文件完整性 —— 发现隐藏的 .tmp 文件

查看 Ollama 的 lib\ollama\cuda_v12\ 目录:

代码语言:python
复制
Name                 Length
----                 ------
concrt140.dll        311,688 字节
cublas64_12.dll     113,720,712 字节
is-8HNSXDBU7C.tmp   692,449,672 字节  ← 可疑的 660MB 临时文件!

同时对比主目录下的 ggml*.dll 文件,发现:

应有的文件

是否存在

ggml-base.dll

✅ 存在

ggml-cpu-*.dll(各种 CPU 架构)

✅ 都有(十几种)

ggml-cuda.dll

完全缺失!

读取 is-8HNSXDBU7C.tmp 文件前几个字节,发现是 MZ(PE 可执行文件头),进一步搜索文件内容,发现 7z / PK 等归档签名。

2.5 根本原因

Ollama 安装过程中,CUDA 支持库的自解压包解压失败了! 那个 660MB 的 .tmp 文件应该是包含 ggml-cuda.dll 的自解压程序,但由于安装中断(可能是安装时卡顿、杀软拦截等原因),文件没有被正确解压和重命名,导致所有 CUDA 相关的 ggml 动态库缺失。

没有 ggml-cuda.dll,llama.cpp 的 GPU 后端自然无法初始化,llama-server --list-devices 当然就看不到任何 GPU。

2.6 修复方案

最干净可靠的方式是完全卸载后重装

  1. 停止所有 Ollama 进程
  2. 运行卸载程序 + 手动删除残留安装目录
  3. 从官网重新下载安装包,安装时确保网络畅通、关闭杀毒软件、耐心等待解压完成
  4. 不要删除 OLLAMA_MODELS 指向的模型缓存目录(省的重新下载几十 GB)

重装完成后验证:

代码语言:python
复制
> llama-server.exe --list-devices
Available devices:
  [0] NVIDIA GeForce RTX 3090

GPU 识别成功!


三、问题二:GPU 利用率只有 17%,内存拉满 —— 深度优化

重装之后 GPU 是能用了,但新的问题来了:

代码语言:python
复制
> ollama ps
NAME         ID              SIZE     PROCESSOR          CONTEXT
qwen3:32b    030ee887880f    29 GB    21%/79% CPU/GPU    32768

同时 nvidia-smi 显示:

  • 显存占用:23176 / 24576 MiB(94% 几乎占满
  • GPU 利用率:17%(GPU 一直在等 CPU)

3.1 搞懂 Ollama 的分层加载机制

首先要理解一个核心概念:当模型 > 显存时,Ollama 会分层(Layer Offloading)

代码语言:python
复制
模型总权重 = GPU 上加载的层 + CPU 上加载的层

指标

数值

含义

qwen3:32b 模型大小

29 GB

权重总大小

RTX 3090 显存

24 GB

GPU 能放的上限

当前分层

21% CPU / 79% GPU

约 6GB 权重在 CPU,23GB 在 GPU

为什么 GPU 利用率只有 17%?

因为每一步推理(生成一个 token)都需要:

  1. CPU 把它手里那 21% 层的计算结果 → 通过 PCIe 总线 → 传给 GPU
  2. GPU 拿到完整数据后才能开始算
  3. 算完再把中间状态传回去

PCIe 带宽 vs GPU 算力 = 瓶颈,GPU 大部分时间在空转等数据,所以利用率上不去。

💡 经验法则:只要 CPU/GPU 分层比例不是 0%/100%,GPU 利用率通常都很难看。

3.2 为什么 24GB 显存放 23GB 模型还不够?

关键:显存不是只放模型权重的

显存占用有三大块:

代码语言:python
复制
总显存 = 模型权重(Weights) + KV Cache(上下文缓存) + 运行时预留开销

组成部分

当前占用

说明

模型权重

~22.9 GB

29GB × 79%

KV Cache

~1.3 GB

32K 上下文,fp16 精度

预留开销

~0.4 GB

默认预留 + 其他

总计

24.6 GB

超出了!所以要卸载权重到 CPU

3.3 核心优化思路

省显存 → 把省出来的空间用来多放模型层 → 降低 CPU 分层比例 → 减少 PCIe 搬运 → GPU 利用率提升

那怎么省显存?从三大组成部分逐一开刀:

优化 1:砍 KV Cache —— 降低上下文长度(收益最大 ⭐⭐⭐⭐⭐)

KV Cache 的大小公式:

代码语言:python
复制
KV_Cache_Size ≈ 2 × 层数 × 头维度 × 头数 × 上下文长度 × 2(bytes/fp16)

简化后,对 32B 参数模型大致是:

  • 32K 上下文 → 约 1.2 ~ 1.5 GB
  • 8K 上下文 → 约 300 ~ 400 MB
  • 4K 上下文 → 约 150 ~ 200 MB

上下文从 32K 降到 4K,直接省出 1GB+ 显存! 这 1GB 可以多塞几层模型进 GPU。

日常对话场景,99% 的情况 4K 上下文完全够用。除非你要一次丢一整篇论文进去让模型总结。

优化 2:KV Cache 量化(收益 ⭐⭐⭐)

默认 KV Cache 是 fp16(2 bytes/值),可以改成 8bit 量化:

KV Cache 类型

每个值占用

相对占用

fp16(默认)

2 bytes

100%

q8_0

1 byte + 少量缩放因子

~53%

q4_0

0.5 bytes + 缩放

~28%

q8_0 可以再省接近一半的 KV Cache,而且精度损失几乎不可感知。

优化 3:启用 Flash Attention(收益 ⭐⭐)

Flash Attention 是一种更高效的 Attention 计算算法,能减少中间结果的显存占用,同时提升计算速度。

优化 4:减少 GPU 预留开销(收益 ⭐)

Ollama 默认会预留一部分显存(防止 OOM),但我们可以把这个预留调小,榨干每一寸显存。

3.4 落地:设置 Ollama 环境变量

在 Windows 上,用 PowerShell 永久写入用户级环境变量:

代码语言:powershell
复制
# 1. 上下文长度从 32K 降到 4K  ← 最大的优化!
[Environment]::SetEnvironmentVariable("OLLAMA_CONTEXT_LENGTH", "4096", "User")

# 2. KV Cache 8bit 量化
[Environment]::SetEnvironmentVariable("OLLAMA_KV_CACHE_TYPE", "q8_0", "User")

# 3. 启用 Flash Attention
[Environment]::SetEnvironmentVariable("OLLAMA_FLASH_ATTENTION", "true", "User")

# 4. GPU 预留开销设为 0(榨干显存)
[Environment]::SetEnvironmentVariable("OLLAMA_GPU_OVERHEAD", "0", "User")

设置完成后,重启电脑(或者至少重启所有 Ollama 进程),环境变量才会生效。

3.5 优化前后效果对比

以运行 qwen3:32b 为例:

指标

优化前

优化后(预期)

上下文长度

32768

4096

GPU/CPU 分层

79% / 21%

~95%+ / ~5%-

GPU 利用率

17%

60% ~ 95%

系统内存占用

高(~6GB 模型+缓存)

显著降低

推理速度(tok/s)

快 2 ~ 4 倍


四、Ollama 所有 GPU 相关环境变量速查表

变量名

类型

默认值

说明

OLLAMA_CONTEXT_LENGTH

int

模型默认

上下文窗口大小,调小可以省显存换速度

OLLAMA_GPU_OVERHEAD

int

自动计算

额外预留的 GPU 显存(bytes),不想预留设 0

OLLAMA_FLASH_ATTENTION

bool

false

启用 Flash Attention(v2+)

OLLAMA_KV_CACHE_TYPE

string

fp16

KV Cache 精度:fp16 / q8_0 / q4_0

OLLAMA_NUM_PARALLEL

int

1

并行处理的请求数,1 时速度最快

CUDA_VISIBLE_DEVICES

string

全部

控制可见的 GPU,如 "0" 只用第 0 张卡

OLLAMA_SCHED_SPREAD

bool

false

多 GPU 时是否跨卡分散模型(适合推理,不适合并行)


五、给大显存紧张用户的终极建议

如果你的模型 >> 显存,下面是优先级排序:

  1. 先想清楚是不是真的需要这么大的模型? 用 14B 跑满 GPU,往往比 32B 跑 70% GPU 还快,效果差距在日常场景并不大。
  2. 如果非要用大模型,优先降上下文,其次量化 KV Cache。
  3. 永远不要把显存吃满到 99%,留几百 MB 余量防止 OOM。
  4. RTX 3090 24GB 黄金搭配推荐
    • 日常对话:qwen3:14b(约 13GB,100% GPU,速度飞快)
    • 需要更强推理:qwen3:32b + 4K 上下文(~95% GPU,速度不错)
    • 极致速度:qwen3.5:9b / qwen3:8b(6~7GB,零压力)

六、结语

这次排查花了整整一个下午,但收获很大:

  1. 遇到 Ollama 不用 GPU,先看 llama-server --list-devices,如果没设备就去查 ggml-cuda.dll 在不在 —— 90% 的情况是安装不完整。
  2. 能用 GPU 不等于 GPU 好用,一定要看 ollama ps 里的分层比例和 nvidia-smi 的利用率
  3. 显存优化的核心矛盾:模型权重 vs KV Cache,对大多数用户,砍上下文长度是性价比最高的优化。

希望这篇文章能帮你少踩坑,享受本地跑大模型的乐趣!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 从 100% CPU 到接近 100% GPU:一次完整的 Ollama 本地大模型加速优化实录
    • 一、问题背景
    • 二、问题一:完全无法调用 GPU —— 诊断与修复
      • 2.1 初步排查
      • 2.2 深挖日志:启动 GPU 调试模式
      • 2.3 直接用 llama-server 验证
      • 2.4 检查文件完整性 —— 发现隐藏的 .tmp 文件
      • 2.5 根本原因
      • 2.6 修复方案
    • 三、问题二:GPU 利用率只有 17%,内存拉满 —— 深度优化
      • 3.1 搞懂 Ollama 的分层加载机制
      • 3.2 为什么 24GB 显存放 23GB 模型还不够?
      • 3.3 核心优化思路
      • 3.4 落地:设置 Ollama 环境变量
      • 3.5 优化前后效果对比
    • 四、Ollama 所有 GPU 相关环境变量速查表
    • 五、给大显存紧张用户的终极建议
    • 六、结语
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档