SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-10

Ollama 模型如何保持加载在内存中

Ollama 默认空闲 5 分钟后卸载模型,下一次请求会再次承担完整加载时间。通过 keep_alive 设置延长驻留,并使用 systemd drop-in 让服务器重启后仍然生效。

为什么 Ollama 会在几分钟后卸载模型?

Ollama 会在模型处理完最后一个请求后继续将其保留在内存中 5 分钟,随后释放模型。下一个请求必须再次从磁盘读取权重,并将其映射到 RAM 或 VRAM,因此在返回第一个 token 前会出现停顿。这就是聊天界面或编程代理开始响应很快、空闲一段时间后,再发送下一条消息却变慢的原因。系统没有故障,只是空闲计时器已到期。

此计时器称为 keep_alive。它按模型单独计时,每次请求完成后都会重新计时。正在处理请求的模型不会被卸载,因为服务器只会卸载当前没有活动请求的模型。截至 2026 年 8 月,默认值为 5 分钟,适用于此服务器加载的每个模型。

有两个位置可以设置 keep_alive:单个请求,或服务器默认值。使用 systemd drop-in 才能让服务器默认值在重启后继续生效。本指南假设 Ollama 已作为服务运行。如果尚未运行,请先阅读在 VPS 上安装 Ollama,然后返回本指南。

当前驻留了哪些模型?它们何时过期?

ollama ps
NAME        ID              SIZE      PROCESSOR    CONTEXT    UNTIL
qwen3:8b    500a1f067a9f    6.6 GB    100% GPU     4096       4 minutes from now

输出为空表示当前没有加载任何模型,因此下一次请求需要完整加载。PROCESSOR显示权重所在的位置。100% GPU100% CPU表示明确的情况。像25%/75% CPU/GPU这样的拆分表示模型无法完全装入 VRAM,因此部分模型在处理器上运行,生成速度会变慢。

UNTIL表示倒计时,并输出类似4 minutes from now的相对时间。如果模型使用负数keep_alive加载,则输出Forever。服务器卸载模型的短暂时间窗口内会输出Stopping...

不同版本之间的列集合可能发生变化,因此应读取表头,不要在脚本中通过字段数量进行判断。对于自动化任务,请通过 API 查询:

curl -s http://localhost:11434/api/ps

每个条目都包含expires_at(绝对时间戳,例如2026-08-09T14:38:31.83753Z)和size_vram,后者表示该模型当前驻留在 GPU 内存中的部分。size_vram为 0 表示模型在 CPU 上运行。

实际重新加载的成本

不要猜测。Ollama 会在每个响应中报告加载时间,字段为 load_duration,单位是纳秒。

sudo apt install -y jq
ollama stop qwen3:8b
curl -s http://localhost:11434/api/generate -d '{"model": "qwen3:8b", "prompt": "hi", "stream": false}' | jq '{load_duration, total_duration}'
curl -s http://localhost:11434/api/generate -d '{"model": "qwen3:8b", "prompt": "hi", "stream": false}' | jq '{load_duration, total_duration}'

第一次调用会加载模型,因此其 load_duration 数值较大。将它除以 1000000000,即可换算为秒。第二次调用会在模型驻留内存期间执行,因此报告的数值小得多。这两个数值之间的差值,就是计时器到期后每位用户都要承担的成本,也是修改 keep_alive 的根本原因。有关暂停前后生成速度的测量方法,请参阅 如何在自己的服务器上测量每秒生成的 token 数

在一次请求中让 Ollama 模型保持加载在内存中

在请求中发送 keep_alive。请求完成后,该设置会从此刻开始作用于此模型。

curl -s http://localhost:11434/api/chat -d '{
  "model": "qwen3:8b",
  "messages": [{"role": "user", "content": "hello"}],
  "keep_alive": "30m"
}'

支持以下 4 种值格式:

  • 时长字符串:"30m""24h""90s"
  • 普通数字,按秒读取:3600
  • 负值,-1"-1m",表示完全不设置空闲超时
  • 0,表示请求完成后立即卸载

请求中的值会覆盖服务器默认值,且双向都适用。这一点比看起来更重要:客户端自行发送的 keep_alive 会覆盖服务器上的任何配置。

您还可以在不生成内容的情况下加载模型。只发送模型名称。服务器会加载该模型,并返回带有 "done": true 的空响应。

curl -s http://localhost:11434/api/generate -d '{"model": "qwen3:8b", "keep_alive": "30m"}'

重启后或拉取新模型后应运行此命令。这样,首个实际用户请求无需承担模型加载时间。CLI 使用一个 flag 执行相同操作:

ollama run --keepalive 30m qwen3:8b "hello"

默认使用 OLLAMA_KEEP_ALIVE 保持模型加载

服务器启动时读取 OLLAMA_KEEP_ALIVE,并将其应用于未单独设置该值的所有模型。它支持与请求字段相同的格式,因此 30m3600-1 均可使用。

关键在于该变量必须存在于正确的环境中。在 SSH 会话中运行 export OLLAMA_KEEP_ALIVE=30m 不会产生任何效果,因为通过软件包安装的服务会由 systemd 以独立用户运行,并使用自己的环境变量。您的登录 shell 与该服务彼此隔离。这是该设置看似未生效的最常见原因。

通过 systemd drop-in 使设置在重启后保留

sudo systemctl edit ollama.service

编辑器打开后会显示两个注释标记。在这两个标记之间输入内容:systemd 会丢弃您写在第二个标记之后的任何内容。

[Service]
Environment="OLLAMA_KEEP_ALIVE=30m"

保存操作会写入 /etc/systemd/system/ollama.service.d/override.conf。这是 drop-in 文件,不是对已发布 unit 文件的直接修改,因此 Ollama 软件包升级并替换 ollama.service 时,您的设置仍会保留。如果您不熟悉 drop-in 和 unit 文件,请参阅systemd 服务与计时器指南,了解具体机制。

sudo systemctl daemon-reload
sudo systemctl restart ollama
systemctl show ollama --property=Environment

最后一条命令会输出该服务实际运行时使用的环境变量。如果这一行中缺少 OLLAMA_KEEP_ALIVE=30m,说明 drop-in 未生效。原因几乎总是缺少 [Service] 标头,或将内容输入到了标记之后。重启本身会卸载所有已加载的模型,因此下一个请求会执行冷加载。使用上面的预加载调用使模型预热。

保持模型常驻的成本

ollama ps 中的 SIZE 列表示整个空闲窗口期间都被占用的内存,而不只是处理请求时占用的内存。采用 4-bit 量化的 8B 模型通常占用约 5 到 6 GB。27B 模型的情况完全不同;在决定让它保持常驻前,值得先计算仅使用 CPU 的 VPS 运行该模型所需的内存。将 keep_alive 设置为 -1,就表示模型将永久优先于服务器上的其他所有任务。在小型 VPS 上,这会直接占用数据库、Web 应用和构建任务所需的资源。

不要只相信估算值,应查看实际数据。模型加载后运行一次,执行 ollama stop 后再运行一次:

free -h

available 列表示内核仍可分配给新进程的内存。在配备 NVIDIA GPU 的服务器上,nvidia-smi 会在显存中显示相同的情况。如果服务器耗尽资源,内核会终止某个进程以回收资源:

sudo dmesg -T | grep -i "out of memory"

如果某行指向 ollama,表示模型服务器被终止。如果某行指向数据库,表示模型获得了资源,而你关心的服务被终止。这两种结果都源于同一个决定:在没有资源余量的服务器上设置过长的保持连接窗口。

这里还有两个容易忽略的成本。上下文长度越大,预留的 KV cache(键值缓存,即模型生成内容时为每个 token 保留的注意力状态)越大,而该缓存属于常驻内存的一部分。将 OLLAMA_NUM_PARALLEL 设置为大于 1 的值后,每个并行槽位都会分别预留一份缓存。如果计划让一个模型为多名用户提供服务,应按槽位计算内存,而不能只按模型权重计算。

一个合理的默认设置是:在有足够资源余量的服务器上运行一个模型,可以使用 -1。共享服务器应使用覆盖请求间隔的窗口,例如 30m,这样停止工作后内存就会释放。

立即卸载模型

ollama stop qwen3:8b

该命令不会返回任何输出,模型会从 ollama ps 中消失。指定未加载的模型时,会返回 couldn't find model "qwen3:8b" to stop。API 形式是不带提示词的请求,并将 keep_alive 设置为 0

curl -s http://localhost:11434/api/chat -d '{"model": "qwen3:8b", "messages": [], "keep_alive": 0}'

响应中包含 "done_reason": "unload"。请使用此方法,不要重启服务。systemctl restart ollama 也会释放内存,但会卸载其他所有已加载的模型,并终止正在运行的请求。

在一台服务器上运行多个模型

OLLAMA_MAX_LOADED_MODELS限制同时保持加载状态的模型数量。截至 2026 年 8 月,默认值为每个 GPU 3 个;仅使用 CPU 的服务器默认也是 3 个。此限制按模型数量计算,但真正的限制是内存。因此,第二个大型模型可能在达到 3 个之前很久就因内存不足而无法加载。

请求加载新模型时,如果可用内存不足,调度器会卸载一个当前驻留的模型以释放空间。调度器优先选择没有活动请求的模型,也可能驱逐计时器尚未到期的模型,包括使用 -1 加载的模型。因此,负数 keep_alive 表示没有空闲超时。它不会锁定模型权重来阻止其他模型的请求。

此决策会以 debug 级别记录。向同一个 drop-in 文件再添加一行 Environment="OLLAMA_DEBUG=1",然后重启并监控日志:

sudo journalctl -u ollama -f

如果某行显示为腾出空间而卸载 runner,且该行紧邻触发卸载的请求,则说明这两个模型无法在此服务器上同时运行。解决方法是减少此服务器上的模型数量,或为必须快速响应的模型设置较长的窗口,并为很少调用的模型设置 0

适用于后续版本的指导

Ollama 经常发布新版本,默认值也会变化。因此,请检查当前实际使用的构建版本,不要死记数字:

ollama --version
ollama serve --help

ollama serve --help会列出该构建实际读取的环境变量,其中包括 OLLAMA_KEEP_ALIVE。有两条规则在各个版本中都保持稳定,可以据此配置。请求中的值优先于服务器默认值。无论配置文件声明应加载什么,ollama ps都反映实际加载的内容。

如果编辑器或代理负责驱动您的服务器,请先检查客户端发送了什么,再判断是否是服务器的问题。将编码代理指向您自己的 Ollama 服务器介绍了这些请求设置的位置。

FAQ

Ollama 为什么会在 5 分钟后卸载模型?

5 分钟是默认的 keep_alive,即 Ollama 在请求完成后启动的空闲计时器。计时器到期后,服务器会释放模型权重,因此下一次请求必须从磁盘重新加载模型;您感受到的停顿就是重新加载造成的。您可以在 JSON 请求体中发送 "keep_alive": "30m",为单个请求延长保留时间;也可以使用 OLLAMA_KEEP_ALIVE 环境变量,为整个服务器设置该值。

如何让 Ollama 模型永久加载在内存中?

使用负值:在请求中设置 "keep_alive": -1,或为服务器设置 OLLAMA_KEEP_ALIVE=-1。随后,ollama ps 会在 UNTIL 列中显示 Forever。这只会移除空闲计时器,不会产生其他影响。如果请求另一个模型时内存不足,调度器仍会卸载此模型以释放空间。

为什么会忽略 OLLAMA_KEEP_ALIVE?

检查您设置该变量的位置。运行 systemctl show ollama --property=Environment。如果输出中没有该变量,说明服务器从未收到它,因为在 shell 中导出的变量不会传递给 systemd 服务。使用 sudo systemctl edit ollama.service 设置该变量,然后运行 sudo systemctl daemon-reloadsudo systemctl restart ollama。另一种原因是客户端在请求中发送了自己的 keep_alive,从而覆盖服务器默认值。

如何在不重启 Ollama 的情况下释放内存?

ollama stop qwen3:8b 会立即卸载该模型,同时保持服务器和其他已加载模型继续运行。通过 API 发送不包含提示词且带有 "keep_alive": 0 的请求,响应会返回 "done_reason": "unload"。使用 ollama ps 确认;输出中不应再列出该模型。