Ollama 模型常駐記憶體,避免閒置後重新載入
Ollama 預設閒置 5 分鐘就卸載模型,下一次請求會重新載入並等待。設定 keep_alive,讓模型持續留在記憶體中,重開機後也能保留。
為什麼 Ollama 會在幾分鐘後卸載模型?
Ollama 會在最後一個請求完成後,讓模型繼續保留在記憶體中 5 分鐘,之後將其釋放。下一個請求必須再次從磁碟讀取權重,並將其映射到 RAM 或 VRAM,因此第一個 token 產生前會停頓。這就是為什麼聊天 UI 或程式碼代理一開始反應很快,閒置一段時間後,下一則訊息又變慢。系統沒有故障,而是閒置計時器已到期。
此計時器稱為 keep_alive。它以模型為單位,且每次請求完成後都會重新計時。目前正在回應請求的模型不會被卸載,因為伺服器只會卸載沒有進行中請求的模型。截至 August 2026,預設值為 5 分鐘,且適用於此伺服器載入的每個模型。
有兩個地方可以設定 keep_alive:個別請求,或伺服器預設值。使用 systemd drop-in 設定伺服器預設值,才能在重新啟動後保留設定。本指南假設 Ollama 已經以服務的形式執行。若尚未執行,請先參閱 在 VPS 上安裝 Ollama,再返回本節。
目前有哪些模型常駐,以及何時到期?
ollama psNAME ID SIZE PROCESSOR CONTEXT UNTIL
qwen3:8b 500a1f067a9f 6.6 GB 100% GPU 4096 4 minutes from now輸出為空表示目前沒有載入任何模型,因此下一個請求必須完整載入模型。PROCESSOR 會顯示權重所在的位置。100% GPU 與 100% 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 種值:
- duration 字串:
"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 使用旗標也能執行相同操作:
ollama run --keepalive 30m qwen3:8b "hello"預設載入模型:使用 OLLAMA_KEEP_ALIVE
伺服器啟動時會讀取 OLLAMA_KEEP_ALIVE,並將其套用至所有未自行指定值的模型。它採用與請求欄位相同的格式,因此 30m、3600 和 -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 欄位,表示整個閒置期間都會占用的記憶體,不只是在處理請求時占用。8B 模型採用 4-bit 量化時,通常約占 5 到 6 GB。27B 模型則是另一個層級;在決定讓模型常駐前,值得先推算僅使用 CPU 的 VPS 執行模型所需的記憶體。將 keep_alive 設為 -1,就表示你決定讓模型永久優先於伺服器上的其他工作。在小型 VPS 上,這會直接排擠資料庫、Web 應用程式與建置工作。
請查看實際數值,不要只相信估算。模型載入時執行一次,然後在 ollama stop 後再執行一次:
free -havailable 欄位表示核心仍可提供給新程序的記憶體。在 NVIDIA GPU 伺服器上,nvidia-smi 會在 VRAM 中顯示相同的情況。記憶體耗盡時,核心會終止某個程序以回收資源:
sudo dmesg -T | grep -i "out of memory"若某行列出 ollama,表示模型伺服器成了受害者。若某行列出你的資料庫,表示模型存活,但重要的服務被終止。這兩種結果都源自相同的決定:在沒有餘裕的伺服器上設定過長的 keep-alive 時間。
這裡有兩項容易忽略的成本。較長的 context length 會保留較大的 KV cache(key value cache,即模型在生成內容時,針對每個 token 保留的 attention 狀態),而這個快取也會計入常駐大小。其大小取決於 num_ctx,因此提高 context window會增加常駐模型在整個閒置期間占用的記憶體,不只是在回應時占用。大於 1 的 OLLAMA_NUM_PARALLEL 會為每個平行 slot 各保留一份快取。若計畫讓同一個模型服務多位使用者,記憶體應按 slot 數量規劃,而不是只按模型權重規劃。
合理的預設值是:有足夠餘裕的伺服器可使用 -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 限制同時保持載入的模型數量。截至 August 2026,預設值是每個 GPU 3 個模型;僅使用 CPU 的主機則是 3 個模型。此上限計算的是模型數量,但真正的限制是記憶體。因此,第二個大型模型可能在達到 3 個模型以前就因記憶體不足而無法載入。
要求載入新模型時,如果可用記憶體不足,排程器會卸載其中一個目前常駐的模型以釋出空間。排程器優先選擇沒有作用中請求的模型,也會逐出計時器尚未到期的模型,包括使用 -1 載入的模型。因此,負值 keep_alive 表示不設定閒置逾時。它不會固定模型權重以防止其他模型提出請求。
此決策會以 debug 層級記錄。將第二行 Environment="OLLAMA_DEBUG=1" 加入同一個 drop-in 檔案,重新啟動服務,然後監看:
sudo journalctl -u ollama -f如果在觸發該請求的記錄旁看到為了釋出空間而卸載 runner 的訊息,表示這兩個模型無法在此主機上同時容納。解決方式是減少此主機上的模型數量,或為必須快速回應的模型設定較長的保留時間,並為很少呼叫的模型使用 0。
不受下一個版本影響的指引
Ollama 經常發布新版本,預設值也會變動。因此,請檢查目前使用的 build,不要死記數字:
ollama --version
ollama serve --helpollama serve --help 會列出該 build 實際讀取的環境變數,其中包括 OLLAMA_KEEP_ALIVE。有兩項規則在各版本中都維持不變,可以放心依循。請求中的值會覆寫伺服器預設值。此外,無論設定檔宣告應載入什麼,ollama ps 才是實際已載入內容的依據。
如果由編輯器或 agent 控制伺服器,請先確認該用戶端傳送的內容,再判斷問題是否出在伺服器。將 coding agent 指向自有的 Ollama 伺服器說明這些請求設定所在的位置。
FAQ
為什麼 Ollama 會在 5 分鐘後卸載我的模型?
5 分鐘是預設的 keep_alive,也就是 Ollama 在請求完成時啟動的閒置計時器。計時器到期後,伺服器會釋放模型權重,因此下一個請求必須從磁碟重新載入。這段重新載入時間就是您感受到的停頓。若只要對單一請求延長時間,請在 JSON body 中傳送 "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-reload 和 sudo systemctl restart ollama。另一個原因是用戶端在請求中自行傳送 keep_alive,覆寫了伺服器預設值。
如何在不重新啟動 Ollama 的情況下釋放記憶體?
ollama stop qwen3:8b 會立即卸載該模型,並讓伺服器及其他已載入的模型繼續執行。使用 API 時,請傳送不含 prompt 且包含 "keep_alive": 0 的請求,回應會包含 "done_reason": "unload"。使用 ollama ps 確認,輸出中應不再列出該模型。