如果你和我一样,拥有两张 RTX 4090(总计 48GB 显存),并且习惯在本地同时跑两个大语言模型(比如 Qwen2.5:14b 和 Qwen3.5:27b),那么你最近在更新 Ollama 后,大概率遇到了一件极其崩溃的事情:原本完美双开的配置,突然跑不动了!
以前双开毫无压力,更新后单单跑一个 14B 的模型,显存竟然直接飙到了 75GB,不仅导致模型溢出到了 CPU 内存,甚至连第二个模型都塞不进去了。
今天,我们就来彻查这个“显存刺客”的真面目,并提供一套从底层逻辑到日常开机的终极解决方案。
异常现象:一个 14B 模型吃掉 75GB 内存?
问题的起因是我在命令行中运行 ollama ps,看到了极其离谱的一幕:
- SIZE: 75 GB(一个 4-bit 量化的 14B 模型,正常大小应该在 9GB 左右)
- PROCESSOR: 40%/60% CPU/GPU(显存彻底爆仓,被迫使用慢速的系统内存)
- CONTEXT: 32768(32K 的超大上下文)
- UNTIL: Forever(模型常驻内存)
在我的使用习惯中,我通过环境变量设置了 OLLAMA_NUM_PARALLEL=5(允许 5 个并发请求)以及 OLLAMA_KEEP_ALIVE=-1(模型常驻内存)。在旧版本中,这套配置在双 4090 上跑得顺风顺水,为什么更新后直接翻车?
破案:新版 Ollama 过于“实诚”的预分配机制
根本原因在于 Ollama(及其底层的 llama.cpp)在近期的更新中,彻底改变了内存分配和上下文(KV Cache)的加载策略。
Ollama 的内存占用遵循一个简单的公式:
总占用 = 模型基础体积 + (单次上下文缓存大小 × 并发数量)
- 旧版本的逻辑(省显存):
老版本比较保守,如果你不强制指定上下文长度,它会给一个比较小的默认值(比如 4096)。此时 14B (9G) + 30B (18G) 加上保守的缓存,总占用在 35GB 左右,48GB 显存轻松双开。 - 新版本的逻辑(吃显存怪兽):
新版本为了防止高并发时中途爆显存,采取了严格的提前预分配机制。更要命的是,它会直接读取模型原生的配置文件!当它发现 Qwen2.5 原生支持 32K 甚至更长的上下文时,它会默认直接拉满。
系统为了满足我设置的 Parallel=5,提前准备了 5 份 32K 的超大上下文缓存。仅这部分缓存就吃掉了六十多 GB 的空间,直接把 48G 的物理显存撑爆。
解决方案:夺回控制权
既然知道了是默认上下文分配过大惹的祸,我们只需要通过自定义 Modelfile,把上下文长度(num_ctx)强行限制回旧版水平(比如 8192),就能完美复刻之前的体验。
为了彻底解决这个问题并兼顾日常使用的便利性,我们需要分两步走:一次性改造模型 和 配置日常开机环境。
阶段一:一键锁死上下文(仅需执行一次!)
为了避免手动输入的编码乱码问题,我写了一个 Windows 批处理脚本,一键生成限制好显存的“精简版”模型。这个脚本你这辈子只需要运行一次!
- 在桌面新建一个文本文档,重命名为
setup_models.bat。 - 将以下代码复制进去并保存:
@echo off
chcp 65001 >nul
echo ==========================================
echo 正在为你创建限制显存版 Qwen 模型...
echo ==========================================
echo.
:: --- 处理 14B 模型 ---
echo [1/2] 正在配置 qwen2.5:14b (限制 8K 上下文)...
(
echo FROM qwen2.5:14b
echo PARAMETER num_ctx 8192
) > temp_14b.txt
ollama create myqwen14 -f temp_14b.txt
del temp_14b.txt
echo 14b 模型处理完成!
echo.
:: --- 处理 27B 模型 ---
echo [2/2] 正在配置 qwen3.5:27b (限制 8K 上下文)...
(
echo FROM qwen3.5:27b
echo PARAMETER num_ctx 8192
) > temp_27b.txt
ollama create myqwen27 -f temp_27b.txt
del temp_27b.txt
echo 27b 模型处理完成!
echo.
echo ==========================================
echo 模型编译完毕!按任意键退出。
echo ==========================================
pause
- 双击运行它。跑完之后,你的硬盘里就有了
myqwen14和myqwen27这两个不会乱吃显存的新模型。这个setup_models.bat现在可以删除了。
阶段二:日常开机启动(焊死环境变量)
模型有了,接下来要解决每次开机怎么启动的问题。我们需要让 Ollama 每次启动都带上我们的高并发和显存压缩参数。
最一劳永逸的方法:写入 Windows 系统环境变量。
这样你就不需要每次开机都去点什么脚本,Ollama 开机自启时会自动读取这些配置。
- 按键盘上的
Win键,搜索“环境变量”,打开“编辑系统环境变量”。 - 点击右下角的“环境变量(N)...”。
- 在“系统变量”或“用户变量”里,点击“新建”,连续添加以下三个魔法参数:
- 变量名:
OLLAMA_NUM_PARALLEL,变量值:5(恢复 5 并发) - 变量名:
OLLAMA_KEEP_ALIVE,变量值:-1(模型常驻内存) - 重点关注: 变量名:
OLLAMA_KV_CACHE_TYPE,变量值:q8_0
💡 隐藏技巧:
q8_0是新版 Ollama 的救星级参数。它开启了 8-bit KV Cache 量化,能在几乎不损失精度的情况下,把上下文带来的显存占用直接砍掉一半!
- 保存并重启电脑。
最终效果:重返巅峰
重启电脑后,你只需要像平常一样打开终端(CMD),直接运行我们第一步做好的模型:
- 窗口一输入:
ollama run myqwen14 - 窗口二输入:
ollama run myqwen27
得益于 num_ctx 8192 的限制和 q8_0 的显存压缩,这两个模型加起来在并发 5 的情况下,也只占用约 30GB - 35GB 的 VRAM。双 4090 再次火力全开,回复速度瞬间找回了以前那种丝滑的感觉!
最后解决方案
挣扎了两个小时,由于bug与不兼容的地方太多了而且qwen3.5表现也未达预期,决定降级!
版权属于:soarli
本文链接:https://blog.soarli.top/archives/896.html
转载时须注明出处及本声明。