跳到主要內容

【2026 最新】Ollama 遷移教學:同一 GGUF 換到 llama.cpp/LM Studio 做 A/B Test

最後更新: ·
Ollama 遷移教學:同一份 GGUF 在 Ollama、llama.cpp 與 LM Studio 做受控 A/B Test

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 遷移到 llama.cpp 與 LM Studio 的同一 GGUF 四階段流程圖
先凍結權重與設定,再分流到三個 runtime;測試失敗時,路線能直接回到 Ollama baseline。

Ollama 遷移第 0 步:先證明你拿到同一份權重

模型名稱像書名,SHA-256 才像逐字指紋。Ollama 模型清單會顯示名稱、digest、格式與量化,但 runtime 單變因測試要再對實際 GGUF 檔案取 hash,不把 tag 或畫面上的「7B、Q4」當作相同證明。

1. 盤點原模型:名稱、格式、Modelfile、版本

官方 Modelfile 文件說明,ollama show --modelfile會列出 FROMTEMPLATEPARAMETERSYSTEM。先保存它;自訂 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 APIdetails.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_templatechat_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/v1OllamaLM 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

Ollama、llama.cpp、LM Studio 同權重 A/B Test 五關驗收表
圖中是要保存的證據欄位,不是三套 runtime 的跑分或勝負。
  1. 權重關:怕的是「同名不同檔」。三欄都填入 shasum -a 256結果;三個 hash 完全一致才標 exact
  2. 封裝關:怕的是權重一樣、prompt 長得不同。保存原始 Modelfile、llama.cpp /props與 LM Studio lms log stream --source model --filter input --json;system overlay、template 或 stop token不同就標成 confound。
  3. API 關:怕的是聊天能回、consumer 卻壞。依序驗 /v1/models、非串流、串流結束事件、usage、錯誤格式與 timeout;每一項只記 pass/fail 與原始 response。
  4. 工具關:怕的是模型說要用工具,parser 卻沒產生結構。固定同一份 tool schema,檢查 finish_reason、函式名、arguments JSON、必填欄位與 tool result 回填。
  5. 效能關:怕的是把冷啟動、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_counteval_duration等欄位;llama.cpp 回應有 timings.predicted_per_secondLM Studio native v1 Chat回傳 stats.tokens_per_secondtime_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、llama.cpp、LM Studio 遷移決策樹,先過品質與工具 gate 再看改善
先問能不能安全替換,再問值不值得替換;沒有勝出的候選時,baseline 就是答案。
  • 保留 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 個坑

  1. 只比模型名稱:改比 GGUF bytes 的 SHA-256。
  2. LM Studio 匯入時動到唯一副本:先 dry-run,再明確選 hard link 或 copy。
  3. 三套同時吃記憶體:效能輪一次只載入一套,品質 smoke test才可分 port 並存。
  4. 把第一輪當 tok/s:cold load、TTFT、warm decode 分欄記錄。
  5. 只測聊天:把 JSON、stream、Tool Calling、tool result與真實 consumer 都列入 gate。
  6. 先卸載舊工具再驗收:保留原 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與一鍵回切設定,觀察期後再清理。

結語:今晚先產生一張可回滾的成績單

回到開頭那條式子:遷移驗收 = 同一 GGUF × 同一請求 × 同一硬體 × 可回滾。今晚不用先決定誰是冠軍;選一個文字型 GGUF,保存 Modelfile與 SHA-256,讓三個 endpoint各跑完普通聊天、JSON與一個假的天氣工具,最後把 base URL切回 Ollama。當這張 receipt 可以重跑,你才真正擁有「要不要換」的答案。想把測試延伸成可維護的本機 Agent 系統,可到 AlphaLab 的實戰課程AI 專區安排下一步。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週最多三封:一封 Weekly 週報與最多兩封關鍵 Alpha Signal。

我們不會 spam,隨時可退訂。