SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor

ollama pull 和 run 差在哪裡?模型檔案存在哪裡

ollama pull 下載模型後結束,ollama run 下載後開啟聊天。了解模型檔案位置、VPS root 磁碟為何被填滿,以及如何搬移儲存位置。

ollama pull 與 ollama run 的差異

ollama pull 會下載模型後結束。ollama run 只會在模型不存在時下載,接著將模型載入記憶體並開啟互動式聊天。兩者的下載內容相同,檔案也會寫入相同位置。只有 run 會在之後繼續執行。

這項差異決定了哪個指令適合放在指令碼中,以及哪個指令適合在鍵盤前執行。

ollama pull gemma4
ollama run gemma4
ollama run gemma4 "Reply with one word: ready"

第一行會擷取模型後結束,因此適合用於佈建流程和 systemd unit。第二行會開啟聊天工作階段;輸入 /bye 或按下 Ctrl+D 即可離開。第三行會傳送單一提示、輸出回答後結束。當指令碼需要取得回答而不是建立工作階段時,這就是適合的形式。模型名稱變動很快,因此請將此處的 gemma4 視為佔位符:截至 2026 年 8 月,這是 Ollama 官方文件使用的範例,函式庫中的任何 tag 都會以相同方式運作。

為什麼第一次執行 ollama run 看起來像是停住

在全新的 VPS 上,第一次執行 run 可能會在幾分鐘內沒有任何輸出。這不是故障。模型必須先寫入磁碟並載入記憶體,聊天提示才會出現。因此,run 會先下載數 GB 的資料,之後才有內容可顯示。

有兩個原因會讓這段工作沒有顯示。Ollama 只有在輸出目標是終端機時才會顯示進度列。因此,位於 shell script、cron job、CI 步驟或一般 ssh host ollama run ... 中的 run,在下載期間完全不會輸出任何內容。資料寫入磁碟後,仍須從磁碟讀入 RAM,才能產生第一個 token。在小型 VPS 上,這個讀取動作可能很慢。如果主機沒有足夠記憶體容納模型,kernel 會開始使用 swap,等待時間就會大幅增加。

請改用第二個工作階段監看,不要靠猜測:

df -h /
watch -n5 df -h /

可用空間持續分段減少,表示下載仍在進行。可用空間停止減少,但命令仍在執行,表示下載已完成,系統開始將模型載入記憶體。

這就是應預先下載模型的理由。輸入 ollama run 的人不應該同時承擔下載所需的等待時間。

在有人提出要求前先下載模型

在新主機上,使用安裝伺服器時的相同 script 下載模型:

curl -fsSL https://ollama.com/install.sh | sh
ollama pull gemma4

如果這是第一次架設伺服器,完整的 Ollama VPS 安裝指南會說明服務本身,以及允許連線的對象。接著應設定一個不受終端機工作階段影響的下載程序,因為下載中途終止,容易造成模型儲存區只完成部分內容。

請在 tmux 中執行,或將它交給 systemd,作為開機時執行的一次性 unit。建立 /etc/systemd/system/ollama-pull.service

[Unit]
Description=Pre-pull Ollama models
Wants=ollama.service network-online.target
After=ollama.service network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c 'until ollama list >/dev/null 2>&1; do sleep 2; done'
ExecStart=/bin/sh -c 'ollama pull gemma4'

[Install]
WantedBy=multi-user.target

這兩個命令都刻意透過 /bin/sh -c 執行。單獨執行 ExecStart= 時需要絕對路徑,而 installer 不一定會將 binary 放在相同目錄,因此在主機上使用 command -v ollama 才是可靠的做法。透過 shell 執行會使用服務的 PATH,而不是複製自指南的路徑。第一個 ExecStart 同樣重要:After=ollama.service 只表示伺服器 unit 已啟動,不代表服務已就緒,因此迴圈會等待 ollama list 回應後,才開始下載。

sudo systemctl daemon-reload
sudo systemctl enable --now ollama-pull.service
journalctl -u ollama-pull.service

journal 應顯示下載已完成且沒有錯誤,接著 ollama list 應顯示該模型。若要讓會變動的 tag 保持最新,請加入 systemd timer 或每週執行一次相同下載命令的 cron 項目。重新下載已更新的 tag 時,會下載新的 layers;不再有任何項目指向的舊 layers,會在伺服器下次啟動時清理。

pull 中斷時會發生什麼事

模型的每個 layer 都會以自身內容的 hash 儲存。因此,pull 中斷不代表先前的工作全部浪費;再次執行相同的 ollama pull 時,已完成的 layer 會被辨識並略過,下載會從中斷的 layer 繼續。

有一個操作會破壞這項進度。Ollama server 啟動時,會移除沒有任何 model manifest 參照的已儲存 layer,而中斷的 pull 所留下的 partial layer 正是這類 layer。因此,在重試前重新啟動 service,會丟棄已下載的部分。請先重試 pull,之後再重新啟動。如果確實需要讓 partial download 在重新啟動後保留,請在 service environment 中設定 OLLAMA_NOPRUNE=1,完成後再移除;因為這項啟動時的清理機制,能避免 orphaned layer 持續累積在磁碟上。

如果 pull 因 no space left on device 中止,請先釋放磁碟空間再重試。如果 df 回報磁碟已滿,而 model directory 上的 du 無法說明這些用量,表示空間位於其他位置。此時請先閱讀 df 與 du 數據不一致的原因,再刪除任何內容。

Ollama 會將模型儲存在哪裡?

請直接查詢自己的伺服器,不要盲目信任任何指南中的路徑,包括本指南。套件安裝與容器使用的儲存位置不同;如果有人設定了 OLLAMA_MODELS,位置也會再次改變。

systemctl cat ollama.service
getent passwd ollama
sudo find / -xdev -type d -name blobs 2>/dev/null

systemctl cat 會列出 unit file 及所有 drop-in,因此由你設定或內建於映像中的 OLLAMA_MODELS 行都會顯示在其中。若沒有這類行,模型儲存區會位於服務執行帳號的 home directory 下,而 getent passwd 會在以冒號分隔的第六個欄位輸出該 home directory。find 會在單一檔案系統中搜尋 blobs directory;模型層實際上就寫入此處。如果模型可能已位於獨立掛載點,請移除 -xdev

現在測量,並依照你自己的數值判讀:

ollama list
df -h /
sudo du -sh /the/directory/you/found
sudo du -h -d1 /the/directory/you/found

儲存區分成兩個部分。manifests 會為每個 model tag 儲存一個小檔案,該檔案會列出此 tag 所使用的 layers。blobs 會儲存實際的 layers,每個 layer 都以其內容的 hash 命名;儲存區大小幾乎都來自這些檔案。由於不同 tag 會共用 layers,兩個以相同 weights 建立的模型會在 ollama list 中各自回報大小,但在磁碟上只會佔用一次該空間。因此,列出的大小總和可能大於 du 回報的 directory 大小。

模型檔案填滿小型 VPS 的 root filesystem 的速度,可能比你預計安裝的其他軟體都快。影響模型大小最大的因素是 weight format。q4、q8 與 fp16 的選擇 每個模型可能相差數 GB。

使用 OLLAMA_MODELS 將模型移至資料磁碟區

如果規劃中包含第二顆磁碟或較大的資料磁碟區,請在 root 檔案系統用滿前先移動儲存位置。先停止伺服器,避免複製仍在寫入的檔案。

sudo systemctl stop ollama
sudo mkdir -p /mnt/data/ollama-models
sudo rsync -a /the/directory/you/found/ /mnt/data/ollama-models/
sudo chown -R ollama:ollama /mnt/data/ollama-models
sudo systemctl edit ollama.service

systemctl edit 會在 drop-in 檔案上開啟編輯器,因此不會修改套件提供的 unit,套件更新也不會覆寫你的變更。加入以下兩行:

[Service]
Environment="OLLAMA_MODELS=/mnt/data/ollama-models"
sudo systemctl daemon-reload
sudo systemctl restart ollama
systemctl show ollama --property=Environment
ollama list

systemctl show 應顯示新的路徑,而 ollama list 應列出移動前相同的模型。清單為空表示伺服器無法讀取新的目錄。服務會以 ollama 使用者身分執行,因此該使用者必須具備目的地的讀寫權限;上方的 chown 行就是用來設定此權限。檢查 journalctl -e -u ollama 是否有指出新路徑的權限錯誤。只有在清單正確後才刪除舊副本,因為移動失敗後又刪除來源,將導致你必須重新下載全部模型。

另一個選項是保留原始路徑,並將資料磁碟區掛載到該路徑:

echo '/mnt/data/ollama-models /the/directory/you/found none bind 0 0' | sudo tee -a /etc/fstab
sudo mount -a
findmnt /the/directory/you/found
df -h /

findmnt 顯示掛載資訊表示 bind mount 已生效。當主機上的其他元件已預期使用預設位置時,bind mount 很實用。但它有一個陷阱:你複製出去的檔案仍留在 root 磁碟上的掛載點下方,只是被掛載內容遮蔽,因此必須卸載並移除這些檔案後,空間才會釋出。對下一位登入的管理者而言,環境變數是兩種方法中較容易說明的做法。

容器實際儲存模型的位置

官方映像會將模型儲存在你掛載的位置,而不是任何屬於 ollama 使用者的主機目錄。文件中的執行命令如下:

docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

冒號前的 ollama 是具名 Docker volume,/root/.ollama 則是伺服器在容器內寫入的位置。因此,對上一節中的路徑執行 du 會找不到任何內容,因為模型根本不在那些位置。請列出實際位置與大小:

docker volume inspect ollama
docker system df -v
docker exec -it ollama ollama list

docker volume inspect 讀取 Mountpoint 欄位,然後對該路徑執行 sudo du -sh。若要將模型放在資料 volume 中,請將具名 volume 替換為主機目錄(-v /mnt/data/ollama:/root/.ollama),再重新建立容器。容器會以 root 身分寫入,因此該主機目錄最後會由 root 擁有。在 rootless Podman 中,UID 會改映射到你使用者的 subuid 範圍,因此主機上的擁有者看起來會不同:在 rootless Podman 下執行 Ollama 說明了這項映射。

清理時請注意。docker volume prune 會移除所有未被任何容器參照的 volume。若移除或重新建立 ollama 容器時未保留其 volume,之後執行 prune 會刪除你下載的所有模型,而且除了重新下載之外無法復原。對於存放模型的 VPS,執行 prune 前請先閱讀如何清理 VPS 上的 Docker 磁碟使用量

使用 ollama rm 移除模型,不要使用 rm

ollama list
ollama rm gemma4
ollama list
df -h /

ollama rm 會刪除該標籤的 manifest,接著刪除其他 manifest 都未參照的 layer。檔案解除連結後,空間會立即釋出,因此 df 會馬上變小。由於 layer 可以共用,移除兩個高度相關標籤中的一個時,釋出的空間可能遠小於 ollama list 旁顯示的大小。這是正常行為,不表示刪除失敗。

手動刪除檔案會破壞兩者之間的對應。使用 rm 移除 blob 後,manifest 仍會列出該 blob,因此 ollama list 仍會顯示該模型;嘗試使用模型時,讀取遺失的 layer 便會失敗。手動移除 manifest 後,對應的 layer 會留在磁碟上,卻沒有任何項目參照它們,持續占用空間,而且 Ollama 指令不會回報這些空間。如果已經這樣做,對該標籤執行 ollama rm 可清除殘留項目;重新啟動伺服器則會清除沒有任何參照的 layer。

最後說明一個經常混淆的差異。ollama rm 處理的是磁碟空間。ollama stop gemma4 會將模型從記憶體卸載,完全不會釋出磁碟空間。下載完成後模型在 RAM 中保留多久,是另一項設定;讓模型保持載入,而不是每次請求都重新載入會說明這項設定。

FAQ

ollama pullollama run 有何差異?

ollama pull 會將模型下載至磁碟後結束。ollama run 會檢查模型是否已存在於磁碟;若不存在,便下載模型、載入記憶體,然後開啟互動式聊天工作階段。兩者都會將相同檔案寫入相同目錄。在佈建作業與指令碼中使用 pull,有人員在鍵盤前操作時則使用 runollama run <model> "your prompt" 會送出一個提示後結束,是 run 的可指令碼化形式。

為什麼第一次執行 run 似乎會卡住?

系統正在下載模型。在模型寫入磁碟並載入記憶體前,聊天提示無法出現,而模型通常有數 GB。Ollama 只有在輸出目標是終端機時才會顯示進度列,因此在指令碼、cron 工作或 ssh host ollama run ... 中執行 run 時,工作期間完全不會顯示任何內容。開啟另一個工作階段並執行 watch -n5 df -h /:可用空間分階段減少,表示下載正在進行。預先下載模型即可避免等待。

Ollama 將模型儲存在哪裡?

位置取決於安裝方式,因此應列印實際位置,不要直接假設。執行 systemctl cat ollama.service,確認 OLLAMA_MODELS 是否在 unit 或 drop-in 中設定。若未設定,模型儲存區位於服務執行帳號的 home directory 下;getent passwd ollama 可列印該帳號。sudo find / -xdev -type d -name blobs 2>/dev/null 可直接找出 layer directory。對於 container image,儲存區位於掛載的 volume 內,而 docker volume inspect ollama 會列印其主機端 Mountpoint

如何將 Ollama 模型移至其他磁碟?

停止服務,使用 rsync -a 將儲存區複製到新位置,使用 sudo chown -R ollama:ollama <directory> 將目錄的擁有權交給服務帳號,然後執行 sudo systemctl edit ollama.service,並在 [Service] 行下加入 Environment="OLLAMA_MODELS=<directory>"。使用 sudo systemctl daemon-reload 重新載入後重新啟動服務。使用 systemctl show ollama --property=Environmentollama list 確認結果。清單為空通常表示 ollama 使用者無法讀取新目錄;journalctl -e -u ollama 會顯示該路徑。

刪除模型檔案是否會釋放磁碟空間?

手動刪除檔案會釋放空間,但會使儲存區不一致。刪除 blob 後,manifest 仍會列出該模型,因此模型仍會出現在 ollama list 中,使用時也會失敗。刪除 manifest 後,其 layers 仍留在磁碟上,但沒有任何項目引用它們。請使用 ollama rm <model>;它會刪除 manifest,接著刪除其他模型不再需要的 layers。若檔案已經被手動刪除,請對該 tag 執行 ollama rm 以清除項目,再重新啟動 server;server 會移除任何 manifest 都未引用的 layers。