Ollama 遷移最近又成為本機 AI 社群的熱門爭論:有人主張直接換掉,也有人看重它「下載後就能跑」的低摩擦。真正對你有用的問題不是站哪一邊,而是:保留同一份模型權重後,換 runtime 究竟改善了什麼,又破壞了什麼?
這篇專為第一次做本機模型遷移的人寫。我們不會拿不同模型、不同量化的網路跑分硬比,也不會假裝 AlphaLab 已在你的硬體上跑出答案;你會從 Ollama 找到可驗證的 GGUF,分別交給 llama.cpp 與 LM Studio,固定 API 與 Tool Calling 測例,再留下能一分鐘切回舊服務的 rollback receipt。若你還分不清模型與 runtime,可先讀LLM 推論引擎新手教學。
先說結論:Ollama 遷移不是換隊,是做四項乘法
遷移驗收 = 同一 GGUF × 同一請求 × 同一硬體 × 可回滾;任何一項沒對齊,就不是 runtime 單變因 A/B Test。
- 先保住 A:不要卸載 Ollama、不要刪模型、不要改所有 consumer;它是可工作的 baseline。
- 再建立 B/C:用同一個 GGUF SHA-256,分別啟動
llama-server與 LM Studio。 - 分開驗收:速度看 TTFT、完成時間與資源;品質看固定 Eval;相容性看 streaming、JSON、Tool Calling 與實際 consumer。
- 最後才決策:新 runtime 必須先過關,再用你預先寫下的改善門檻判斷;沒有可觀察收益,保留 Ollama 也是合格答案。

Ollama 遷移第 0 步:先證明你拿到同一份權重
模型名稱像書名,SHA-256 才像逐字指紋。Ollama 模型清單會顯示名稱、digest、格式與量化,但 runtime 單變因測試要再對實際 GGUF 檔案取 hash,不把 tag 或畫面上的「7B、Q4」當作相同證明。
1. 盤點原模型:名稱、格式、Modelfile、版本
官方 Modelfile 文件說明,ollama show --modelfile會列出 FROM、TEMPLATE、PARAMETER 與 SYSTEM。先保存它;自訂 system prompt、stop token 或 template 都是行為的一部分,不能只搬權重後假裝設定也相同。
OLLAMA_MODEL='qwen2.5:7b-instruct-q4_K_M'
mkdir -p ollama-ab-receipt
ollama --version
ollama show "$OLLAMA_MODEL"
ollama show --modelfile "$OLLAMA_MODEL" > ollama-ab-receipt/original.Modelfile
OLLAMA_BLOB=$(awk '/^FROM / {sub(/^FROM /, ""); print; exit}' \
ollama-ab-receipt/original.Modelfile)
test -f "$OLLAMA_BLOB" && printf '找到本機權重:%s\n' "$OLLAMA_BLOB"
od -An -tx1 -N4 "$OLLAMA_BLOB"
shasum -a 256 "$OLLAMA_BLOB"
這條精確權重路線只涵蓋本機、文字型、單一主 GGUF。前四個位元組應讀成 47 47 55 46(ASCII 的 GGUF),而 Show API的 details.format也應是 gguf。如果是雲端模型、Safetensors、視覺 projector、adapter 或多檔組合,就在紀錄寫清楚「不屬於本篇 exact-byte lane」,改從原發布者取得完整資產;不要把重下載的近似量化稱為同權重。
2. 建立不會被模型管理器移走的穩定副本
不要讓 LM Studio 的匯入流程碰唯一副本。macOS/Linux 可先在同一磁碟建立 hard link;若檔案系統不允許,再複製。兩條路都要重新算 hash,並確認與上一步完全一致。一般複製可能額外占用接近一份模型大小;把實際新增的磁碟用量記進遷移成本。
WEIGHT_SHA=$(shasum -a 256 "$OLLAMA_BLOB" | awk '{print $1}')
TARGET="$HOME/Models/ollama-ab/$WEIGHT_SHA.gguf"
mkdir -p "$(dirname "$TARGET")"
ln "$OLLAMA_BLOB" "$TARGET" 2>/dev/null || cp -n "$OLLAMA_BLOB" "$TARGET"
shasum -a 256 "$TARGET"
若你原本就保留來源 GGUF,直接把它當 TARGET 更乾淨。反過來,若只能重新下載另一個同名 Q4_K_M,hash 不同就只能做「品質相近的部署比較」。更完整的差異定位可搭配本機 LLM 五關 parity A/B Test。
把同一 GGUF 啟動成三個可切換 endpoint
先為三套服務使用共同 model ID ab-model,並固定 4096 context。這不是最佳化參數,而是讓第一輪少一個變因。實際測速度時,一次只讓一套 runtime 載入模型,否則 RAM/VRAM 競爭會污染結果。
A:用最小 Modelfile 重建 Ollama baseline
# Modelfile.ab(把第一行改成 TARGET 的絕對路徑)
FROM /absolute/path/to/model.gguf
PARAMETER num_ctx 4096
ollama create ab-model -f Modelfile.ab
ollama run ab-model
Ollama 官方匯入流程支援以本機 GGUF 建模。這個乾淨 alias 用來比較 runtime;原來的 production tag 與完整 Modelfile仍保留,稍後另做 consumer 回歸。
B:llama.cpp 直接讀取同一檔案
llama-server --version
llama-server -m "$TARGET" --host 127.0.0.1 --port 8080 \
--alias ab-model -c 4096 --jinja --metrics
llama.cpp server 文件目前列出本機 -m、OpenAI-compatible endpoint、--alias、回應 timings 與可選的 metrics endpoint。Tool Calling 需要 template 與 parser 配合;官方 function-calling 文件建議用 /props檢查 chat_template/chat_template_tool_use,而不是只看「server 已啟動」。
C:LM Studio 匯入、命名、啟動 server
lms --version
lms import "$TARGET" --dry-run
lms import "$TARGET" --hard-link --user-repo local/ollama-ab -y
lms ls
lms load <LM_MODEL_KEY> --identifier ab-model --context-length 4096
lms server start --port 1234
LM Studio 官方 lms import 文件提供 dry-run、copy、hard link 與 symbolic link。先用 --dry-run看將發生什麼;hard link 失敗時改用 --copy,不要搬動穩定副本。lms load還能固定 identifier、context 與 GPU offload,並用 --estimate-only先估資源。
先做共同 API contract,再測回答品質
三個預設 base URL 分別是 Ollama http://127.0.0.1:11434/v1、llama.cpp http://127.0.0.1:8080/v1、LM Studio http://127.0.0.1:1234/v1。Ollama與LM Studio都公開列出 OpenAI-compatible routes;llama.cpp 也在 server 文件列出 /v1/chat/completions。但「路徑同名」只是起點,並不替你的 client、欄位或 parser 背書。
BASE_URL='http://127.0.0.1:11434/v1' # 每輪只換這一行
curl -sS "$BASE_URL/models" | jq '.data[].id'
curl -sS "$BASE_URL/chat/completions" \
-H 'Content-Type: application/json' \
--data-binary @plain-chat.json | tee response.json
plain-chat.json固定 model、messages、temperature、seed、max_tokens 與 stream;先跑普通文字,再跑 JSON、Tool Calling、tool result 回填、多輪對話。不要一邊換 endpoint,一邊改 prompt。想把這些案例做成可重跑測試,可參考AI Evals 七步教學。
Ollama 遷移的 5 關 A/B scorecard

- 權重關:怕的是「同名不同檔」。三欄都填入
shasum -a 256結果;三個 hash 完全一致才標exact。 - 封裝關:怕的是權重一樣、prompt 長得不同。保存原始 Modelfile、llama.cpp
/props與 LM Studiolms log stream --source model --filter input --json;system overlay、template 或 stop token不同就標成 confound。 - API 關:怕的是聊天能回、consumer 卻壞。依序驗
/v1/models、非串流、串流結束事件、usage、錯誤格式與 timeout;每一項只記 pass/fail 與原始 response。 - 工具關:怕的是模型說要用工具,parser 卻沒產生結構。固定同一份 tool schema,檢查
finish_reason、函式名、arguments JSON、必填欄位與 tool result 回填。 - 效能關:怕的是把冷啟動、warm cache 與生成速度混成一個數。分開記 cold load、client 端 TTFT、完成時間、生成 tok/s、峰值 RAM/VRAM與失敗率。
這五關是上一篇 parity 方法的「遷移專用切片」:這次權重先鎖死,主角是 runtime、API consumer 與 rollback,而不是再診斷雲端模型為什麼變笨。
效能要跑兩輪:冷啟動與暖機不能混算
第一輪:cold start 只回答「多久能開始工作」
完全卸載模型後送第一個固定請求,記載入時間、client 端第一個有效 content delta 出現的 TTFT,以及整個請求完成時間。每套 runtime 重做相同次數,測試順序輪替;筆電要記錄電源模式與溫度,避免最後一套因熱降頻吃虧。這一輪不要拿 tok/s 代替啟動體感。
第二輪:warm run 才比較生成與穩定性
固定輸入/輸出上限、batch、context、並發與 cache 狀態,先暖機,再跑多次並保存中位數與較慢尾端。Ollama 原生 Chat API 會回傳 eval_count、eval_duration等欄位;llama.cpp 回應有 timings.predicted_per_second;LM Studio native v1 Chat回傳 stats.tokens_per_second與 time_to_first_token_seconds。三者原生計時邊界不必然完全相同,所以共同排名以同一 client 的 TTFT/完成時間為主,native stats 用來解釋,不把欄位名字相似當成同公式。
RAM/VRAM 也要量整個服務的系統增量,而不只看 GGUF 檔案大小。Context 與 KV cache 會增加記憶體;先用本機 LLM 顯存與 Context 決策樹設預算,再在每輪關閉其他模型服務、保留同一監測工具與取樣間隔。
Tool Calling parity:同一 schema 要過 5 個斷言
在本文的 OpenAI-compatible function-calling 測例裡,模型產生呼叫請求,測試程式執行函式後再把結果送回;這裡不測 server 代執行的 MCP 工具。LM Studio 官方教學也把模型 template 與 server parser 分成兩層。這正是換 runtime 最容易「有回答但整合失敗」的地方。
{
"model": "ab-model",
"messages": [{"role":"user","content":"請查東京天氣,不要自行猜測。"}],
"tools": [{"type":"function","function":{
"name":"get_weather",
"description":"依城市查詢天氣",
"parameters":{"type":"object","properties":{
"city":{"type":"string"}},"required":["city"],
"additionalProperties":false}
}}],
"temperature": 0,
"seed": 42,
"max_tokens": 128,
"stream": false
}
- HTTP 回應成功,而且不是把 XML/自訂標記塞進一般
content。 message.tool_calls存在,函式名精確等於get_weather。arguments可解析為 JSON,包含必填city,沒有 schema 外欄位。- 把假的工具結果回填後,模型能完成第二輪回答;測試環境不必真的連天氣服務。
- 開啟 streaming 後,consumer 能正確累積被切碎的函式名與 arguments。
固定 seed 是控制項,但本測試不預設它會帶來跨 runtime 的逐 token 相同。品質 gate 應看結構與任務是否通過,而不是要求三篇自然語言回答字字一致。若你要把工具迴圈做成正式系統,可接著讀30 行 Agent Harness 實作。
切換 OpenAI-compatible consumer:先 canary,再留 rollback receipt
不要一次改所有應用。挑一個可重試、沒有不可逆工具權限的 canary consumer,只改 base URL,model ID 維持 ab-model;原設定另存一份。若 consumer 其實依賴 /v1/responses、特定 usage 欄位、structured output 或私有參數,這些都要各自列為 gate,不能由 Chat Completions 成功代替。
# 原 baseline
OPENAI_BASE_URL=http://127.0.0.1:11434/v1
OPENAI_MODEL=ab-model
# llama.cpp canary
OPENAI_BASE_URL=http://127.0.0.1:8080/v1
# LM Studio canary
OPENAI_BASE_URL=http://127.0.0.1:1234/v1
Rollback receipt 至少保存:時間、三套版本、GGUF SHA-256、原/新 endpoint、model ID、有效設定、測試集版本、每關結果、consumer 設定 hash、回切命令與核准人。任何 critical Tool Calling 或資料格式案例失敗,就恢復原 base URL、停止新 server,再用 Ollama /v1/models與一筆 smoke test確認 baseline。Ollama 原 tag、模型與設定要留到觀察期結束。
決策層:選 Ollama、llama.cpp,還是 LM Studio?

- 保留 Ollama:你最在意少步驟的模型管理,而新候選沒有跨過預先設定的效能/控制門檻,或 consumer regression 尚未清零。
- 加入 llama.cpp:你需要直接掌控 GGUF、server flags、template、metrics 或除錯面,且同權重測試已通過 critical cases。
- 加入 LM Studio:你需要 GUI 模型探索、CLI 管理與本機 server 串在一起,而且匯入、Tool Calling 與 consumer workflow 全部過關。
- 其實可以並存:Ollama 留作低摩擦 baseline,llama.cpp 做細部實驗,LM Studio 做桌面探索;用不同 port 與明確 model ID 管理,不必把選型變成永久信仰。
最常踩的 6 個坑
- 只比模型名稱:改比 GGUF bytes 的 SHA-256。
- LM Studio 匯入時動到唯一副本:先 dry-run,再明確選 hard link 或 copy。
- 三套同時吃記憶體:效能輪一次只載入一套,品質 smoke test才可分 port 並存。
- 把第一輪當 tok/s:cold load、TTFT、warm decode 分欄記錄。
- 只測聊天:把 JSON、stream、Tool Calling、tool result與真實 consumer 都列入 gate。
- 先卸載舊工具再驗收:保留原 Ollama 路線與設定,直到 canary 與觀察期完成。
截至 2026 年 9 月,執行前要再看的版本證據
本文在 2026 年 9 月 8 日核對的官方文件,已明列 Ollama 的 GGUF 匯入、OpenAI Chat Completions 與 tools;llama.cpp 的 llama-server、timings、metrics與 --jinja Tool Calling;LM Studio 的本機 GGUF import、OpenAI-compatible server、Tool Calling及 native v1 stats。這些專案更新很快,所以 receipt 必須保存本機 --version與當版 --help輸出;若旗標名稱和本文不同,先依你安裝版本的官方說明調整,再開始同一輪測試。
Ollama 遷移 FAQ
1. 同一個 Ollama tag 就是同一份權重嗎?
不能這樣證明。保存 tag 與 digest之外,還要對實際 GGUF bytes 計算 SHA-256;搬到另外兩套後再算一次。
2. 可以直接讓 llama.cpp 讀 Ollama blob 嗎?
在本文限定條件下可以測。先由 Modelfile取得路徑,再同時確認本機檔案存在、magic bytes 是 GGUF、Show API 格式是 gguf;之後以穩定 hard link/副本做實驗,不把內部路徑當永久 consumer 設定。
3. 匯入 LM Studio 一定要重下載嗎?
不一定。官方 lms import提供 local file、hard link、copy與 symbolic link選項;先 dry-run,並依檔案系統與回滾需求選擇。
4. OpenAI-compatible 等於可以無痛替換嗎?
不等於。它先描述共同 route與 payload 形狀;你的 app 是否依賴 Responses、stream 事件、usage、JSON schema、tool parser或非標準參數,仍要逐項驗收。
5. llama.cpp 一定比 Ollama 快嗎?
不能先下結論。結果會受硬體、backend、版本、context、cache、offload與工作負載影響;本文提供的就是把這些條件寫進 receipt 的方法。
6. 做 A/B 前需要先卸載 Ollama 嗎?
不用。保留程式與原模型作 rollback;測效能時只要讓其他 runtime卸載模型、避免共同占用記憶體即可。
7. 三個 server 能同時開嗎?
port 可以分開,但 benchmark 不要同時載入。相容性 smoke test可用 11434、8080、1234 分流;效能測試則一次一套,才不會互搶 RAM/VRAM。
8. 什麼情況該保留 Ollama?
當 baseline 已滿足需求,而替代方案沒有帶來足以抵銷遷移成本的可觀察改善。少維護一套服務本身也是收益,不需要為了社群聲量而換。
給新手的 7 個重點
- 先 hash GGUF,不先看品牌立場。
- 同權重不等於同 prompt;Modelfile、template與 parser 都要留證。
- 三套使用共同 model ID,consumer只換 base URL。
- 先品質與 Tool Calling,後速度。
- cold、warm、RAM/VRAM分開記。
- 門檻在看結果前寫下,避免挑自己喜歡的數字。
- 保留 Ollama baseline與一鍵回切設定,觀察期後再清理。
接著閱讀
左右滑動查看更多推薦
