MTPLX MTP 最吸引人的說法,是讓 Apple Silicon 上的本機 LLM「大約快兩倍」。但長任務真正的問題不是一小段答案每秒吐幾個 token,而是 Agent 跑完改檔、測試、工具呼叫與多輪修正後,總共省了多少時間,成品有沒有退步。
這篇帶你在同一台 Mac、同一 checkpoint 與同一 Agent 任務下,把 MTPLX 的 MTP 路徑和純 AR(autoregressive,逐 token 解碼)做成可重跑的 A/B。本文提供的是驗收方法與空白評分表,不會把官方或社群數字冒充 AlphaLab 自己跑出的結果;最後的「幾倍」必須由你的硬體、模型和任務算出來。
先說結論:兩倍要用「合格任務」算,不是用 tok/s 猜
🧭 記憶把手:本機 Agent 的有效速度=通過驗收的任務數 ÷ 總 wall time。
- 先過品質:測試、需求與工具呼叫結果至少要守住 AR 基準,否則更快只是更快產生錯誤。
- 再看全程:把 prefill、decode、工具等待、重試與失敗都算進 task wall time。
- 分開回答:同一 MTPLX runtime 的 MTP/AR 才能估 MTP 因果;MTPLX、llama.cpp、oMLX 的比較只能回答整套系統選型。
若 AR 的合格任務中位數是 40 分鐘,MTP 是 20 分鐘,才可在這批任務寫「2.0×」。decode 從 25 提到 50 tok/s,卻因長 prompt、工具或失敗重跑讓整體只從 40 降到 35 分鐘,就只能寫 1.14×。這也是本文和短 benchmark 最大的差別。
MTPLX MTP 原理:內建 head、外部 drafter、Prefix Cache 不一樣
MTP(multi-token prediction)可以想成「先草擬一小段,再由主模型一次驗證」。在本文主測的原生 Qwen 路徑,MTPLX 用同一 checkpoint 內建的 MTP head 猜後續 token,主幹批次驗證;通過的前綴被提交,拒絕處再從修正後的 residual (p−q)+ 分布抽樣。這條路徑不會額外常駐第二套 draft model;Gemma 4 則是官方文件另列的外部 assistant/shared-KV 機制,不能套用同一句話。MTPLX 把這套 probability-ratio acceptance+residual correction 連到 speculative decoding 的 rejection sampling,目標是維持 verifier 計算的 target distribution;它不是與另一 backend 逐 bit 相同的承諾,也不等於每台 Mac 都有相同加速比。

外部 drafter則是另一個模型先猜,會多吃記憶體,也多一組模型匹配問題。Prefix Cache處理的是 prefill:多輪 Agent 重用相同對話前綴時,不要從頭讀完整份歷史。三者都可能讓體感變快,卻作用在不同階段;若控制組同時失去 cache,你量到的就不是 MTP。
想先弄懂模型、MLX runtime、API server 與 client 的分工,可搭配 LLM 推論引擎新手指南;若模型連記憶體都放不下,先用 本機 LLM 記憶體選擇指南縮小候選。
第 0 關:先確認 MTPLX 2.9.1 與能放進記憶體的模型
截至 2026 年 8 月 24 日,最新 MTPLX release 是 v2.9.1。這版修正長 Agent session 約 19K tokens 附近可能截斷/crash 的容量問題、補強多輪 cache reuse,並加入本機 flight recorder 與 mtplx trace。它也明確要求:若曾在 v2.9.0 測 Turbo,必須重跑,因為當時有一個 fast-path flag 實際未生效。這些是 release notes 的修正範圍,不是任何模型、任何 context 都不會失敗的保證。
目前官方 README要求 Apple Silicon M1 以上與 macOS 14+;16GB 建議跑 4B/9B,Qwen3.8 27B Optimized Speed 則建議 32GB 以上。不要為了跟別人的截圖同型號,讓 16GB Mac 硬載 27B 再用 swap 跑完全程。模型大小、量化與 context 必須在 A、B 兩組完全相同。
brew install youssofal/mtplx/mtplx
# 已安裝者先更新;也可用 pip install -U mtplx
brew upgrade mtplx
mtplx --version
mtplx doctor
command -v jq >/dev/null || brew install jq
system_profiler SPHardwareDataType | grep -E 'Chip|Memory'
sw_vers
先把版本、macOS、晶片、統一記憶體、電源模式和室溫寫進 manifest。接電,關掉會搶 GPU/記憶體的程式;每輪開始前確認 memory pressure 與熱狀態一致。這不是為了做華麗實驗室數字,而是避免 B 組剛好遇到降頻。
第 1 關:檢查模型真的有 MTP,並啟動本機 endpoint
MTPLX 的原生 Qwen 路徑不接受把來源不明的 MTP sidecar 硬接到任意 trunk;先用 inspect 看完整模型是否被標為 verified、family-compatible、AR-only 或沒有 MTP head。第一次可讓 app 依硬體推薦,也可把已下載模型的實體路徑綁進環境變數。不要只存顯示名稱,至少保存 repo revision、模型檔清單雜湊與 chat template。
# Server Terminal:quickstart 會保持前景執行
# 請把下一行替換成已下載模型的實際完整目錄
export MODEL_PATH='/完整/模型/路徑'
test -d "$MODEL_PATH"
MODEL_INSPECT="$(mktemp "$PWD/model-inspect.XXXXXX")"
if ! mtplx inspect "$MODEL_PATH" --require-mtp --json > "$MODEL_INSPECT"; then
echo '模型未通過 MTP capability gate;停止本次 A/B' >&2
exit 1
fi
mtplx tune --model "$MODEL_PATH" --retune
# API-only;只綁這台 Mac
mtplx quickstart --model "$MODEL_PATH" \
--host 127.0.0.1 --port 8000
看到 server ready 後另開 Probe Terminal;驗完從這個 Terminal 正常停止,並要求 health probe 失敗,才進入 18083 的 Agent lane:
curl -fsS http://127.0.0.1:8000/health | jq
curl -fsS http://127.0.0.1:8000/v1/models | jq -r '.data[].id'
# smoke 完成就清掉這個 server,避免它和 A/B 同時佔記憶體
mtplx stop --port 8000
! curl -fsS --max-time 2 http://127.0.0.1:8000/health >/dev/null
預設 endpoint 是 127.0.0.1,含 OpenAI-compatible /v1/chat/completions、/v1/models,也有 Anthropic-compatible /v1/messages。若改綁 0.0.0.0,官方 CLI 會要求 API key;本文的驗收不需要對外開放,保持 localhost 最省事。想直接接 Agent,MTPLX v2.9.1 的官方入口是:
mtplx start opencode --port 18083
# 或
mtplx start hermes --port 18085
這兩條是擇一的連線 smoke,不是同時啟動。驗完後從另一個 Terminal 執行 mtplx stop --port 18083 或 --port 18085,並確認 /health 已無回應;A/B 開始前只能留一個 server 與一個模型常駐。後面的 trace 主流程選 OpenCode,因為目前 trace session/report會接 OpenCode DB;若選 Hermes,改存 server metrics/request artifacts,不要照抄這兩個 trace 子命令。
先只選一個 client,後面所有組別都用同一版本與同一設定。若你還不熟悉 Agent 外圍的狀態、工具與權限,可先看 AI Agent Harness 實作框架;使用 Hermes 者可對照 Hermes Agent 新手指南。
第 2 關:把長任務做成可重跑 fixture
不要拿「介紹一下你自己」測 Agent。以下只是一組起始 fixture 設計,不是統計充分性的門檻:準備三個固定 commit 的 disposable repo,小任務約 3~5 次工具呼叫、中任務約 10 次、長任務必須跨多輪讀檔、改檔與測試。每題寫清楚輸入 commit、需求、允許工具、timeout、不可碰的檔案、測試命令與人工評分 rubric;A、B 都從新的 worktree 或乾淨複本開始。
- 可機器驗:既有 tests+你為需求新增的 hidden tests,任何 critical test 失敗即不合格。
- 可人工驗:需求覆蓋、修改範圍、可讀性與是否需要人類救援;先寫評分規則再看輸出。
- 真的夠長:至少包含一次工具錯誤後修正、一次回讀舊 context,以及足以觀察 cache reuse 的多輪歷史。
固定模型、量化、context 上限、temperature、top-p、top-k、reasoning mode、seed、工具 schema、併發數與 client。若使用隨機取樣,可先以每題三次配對當 smoke 起點,再依變異加樣本;三次不代表已有統計把握。若先用 temperature 0,也不要外推成所有取樣設定。更完整的任務設計可沿用 Qwen3.8-27B 本機 Agent 驗收,但本篇只切換解碼路徑。

第 3 關:用 ABBA 跑 MTPLX MTP/AR 對照
最乾淨的主比較,是同一 MTPLX 版本與同一模型只切換 --mtp/--no-mtp。但版本必須至少 v2.8.0:一位第三方在 v2.5.4 發現 --no-mtp 會同時失去 prefix cache,維護者確認這是非預期副作用;官方在 v2.8.0 修正,讓 AR 走相同 restore/prefill 路徑並回報真實 cache stats。舊版資料不能拿來估純 MTP 貢獻。
先做 ABBA,而不是所有 A 跑完才跑 B:A1(MTP)→B1(AR)→B2(AR)→A2(MTP),再把下一題順序反轉。每個 cold cell 都正常停止舊 daemon、確認 port 關閉,再以 fresh Agent session、fresh repo 和 --ssd-session-cache off重啟,這樣 in-memory cache 隨程序消失、SSD 也不 restore。若另測 warm session,兩組才共同保留相同 cache policy,結果另表。MTP 組使用同一台 Mac auto-tune 選出的 depth,不要抄別人的 depth。
# Server Terminal A:保持前景執行
mtplx start opencode --model "$MODEL_PATH" --port 18083 \
--mtp --ssd-session-cache off --no-open-dashboard
# 完成 A1 後,在另一個 Results Terminal 保存證據並正常停止
RESULTS_DIR="$(mktemp -d "$PWD/mtplx-ab-results.XXXXXX")"
chmod 700 "$RESULTS_DIR"
curl -fsS http://127.0.0.1:18083/health > "$RESULTS_DIR/A1.health.json"
mtplx settings get --port 18083 --json > "$RESULTS_DIR/A1.settings.json"
mtplx trace sessions --port 18083 --limit 5 --json > "$RESULTS_DIR/A1.sessions.json"
export SESSION_ID='ses_把本次 OpenCode session ID 貼在這裡'
case "$SESSION_ID" in ses_*貼*) exit 1 ;; ses_*) ;; *) exit 1 ;; esac
mtplx trace session "$SESSION_ID" --port 18083 --json > "$RESULTS_DIR/A1.trace.json"
mtplx trace report "$SESSION_ID" --port 18083 --out "$RESULTS_DIR/A1.trace.html"
mtplx stop --port 18083
# Server Terminal B:只切換為 target-only AR
mtplx start opencode --model "$MODEL_PATH" --port 18083 \
--no-mtp --ssd-session-cache off --no-open-dashboard
每個 run 另記錄 task 起訖 UTC、repo 起始與結束 commit、tests、Agent client session ID、輸入/輸出 tokens、cached tokens、prefill/TTFT、decode tok/s、MTP acceptance、峰值統一記憶體、memory pressure、錯誤、重試與人類介入。v2.9.1 的 flight recorder 會在本機 ~/.mtplx/metrics 保存輪次資料並輪替;分享 trace 前先檢查內容是否包含私有 repo 路徑或 prompt。
若 fixture 含私密內容,還要知道目前 request log 會保存最後一則 user 訊息前 180 字,異常 flight 也可能留生成文字。可在啟動前設 MTPLX_REQUEST_LOG_JSONL=off、MTPLX_FLIGHT_TEXT=off;最高隱私可再設 MTPLX_FLIGHT_RECORDER=off,代價是 trace 證據會減少。更穩妥的做法是用無秘密的固定 fixture,並把 ~/.mtplx/metrics 與 results 權限鎖好、不直接外傳。
主指標不能刪掉失敗 run:先報 有效吞吐=通過任務數 ÷ 全部嘗試 wall time,OOM、crash、timeout 與重試耗時全部留在分母。只有兩組都通過預先設定的品質/穩定 gate,才加報相同 task 的條件式 latency:成功 run speedup=AR 合格 wall time 中位數 ÷ MTP 合格 wall time 中位數。若 MTP 有 critical regression,結論就是「不通過」,不能用成功樣本的速度沖淡。
第 4 關:把 cold、warm、長 context 拆成三張表
Cold量完整 prefill+decode;warm量相同 session 前綴命中後的 TTFT 與 decode;long-context則把對話推到你真實會用的長度,例如 8K、32K,再觀察 cache、記憶體與穩定性。三種情境不能混成一個平均值。
- decode 快、wall time 不變:工具或 prefill 才是瓶頸;MTP 不是這個工作流的第一優先。
- warm 快、cold 不快:主要收益來自 cache;報告 cached tokens 與 TTFT,不要全算給 MTP。
- 前段快、長 session crash:穩定性 gate 失敗;保留 trace,縮短 context 或回到 AR/較小模型。
- 平均快但尾端很慢:檢查 memory pressure、熱降頻與 acceptance 是否隨 context 崩落。
若你的產品本來就需要長對話 cache,另讀 oMLX Prefix Cache 長 session 驗收,把「MTP 解碼」和「前綴復用」各自建立證據鏈。
第 5 關:MTPLX、llama.cpp+MTP、oMLX 要分開做系統選型
完成同引擎 A/B 後,才把同一批任務搬到其他 server。llama.cpp 官方 speculative 文件目前提供 --spec-type draft-mtp,偏向 GGUF 與跨平台生態;截至 2026 年 8 月 24 日,oMLX 0.6.3rc2 預覽版的 pinned source把 continuous batching、多模型服務與 RAM/SSD prefix cache 放在核心,stable 線是 0.6.2。它們解決的主要痛點不完全相同,stable/RC 數據也不能混在一起。

跨引擎表仍記 decode、prefill/TTFT、task wall time、峰值記憶體、tests、成品分數與錯誤,但額外標出權重來源、格式、量化、context、chat template、tool adapter 和 cache policy。即使模型家族同名,只要 MLX 與 GGUF 的量化或轉換不同,就不要宣稱是純引擎因果。最誠實的句子是:「在這台 Mac、這批任務與這三套完整設定下,哪一套通過最多且更快。」
第 6 關:先寫回滾條件,再決定是否日常使用
在開跑前就寫下回滾線:critical test 少過一個、需求分數超出預先設定的非劣界線、出現 OOM/crash/timeout、長 context 需要人類救援,或合格 wall time 沒有穩定改善,都先退回 AR 或較小模型。不要看到單輪 2× 就把 MTP 設成所有專案預設。
- MTPLX:用
--no-mtp回到 target-only AR;至少 v2.8.0 才是乾淨的 cache 對照。 - 模型:memory pressure 升高就先降模型/context,而不是把安全限制關掉。
- client:OpenCode/Hermes 更新後重跑 smoke set,因為 tool schema、預設 output cap 或 reasoning policy 都可能改變。
- 版本:MTPLX、MLX、模型 revision、量化、macOS 或 profile 任一改變,都把舊結果標為不可直接合併。
MTPLX MTP 驗收 FAQ
1. MTPLX 真的一定快兩倍嗎?
不一定。官方首頁是「大約兩倍」的定位,README 也公開特定 M4/M5 組態的數字;加速會受模型、depth、接受率、context、熱狀態與任務中推論占比影響,必須用你的合格 wall time 回答。
2. MTP 會降低輸出品質嗎?
在 exact speculative-sampling 條件下可維持 verifier 的目標分布,但工程驗收仍不可省。Turbo custom verify 的累加順序也不保證和 stock MLX 逐 bit 相同;版本、模型配對、backend 數值與 client 行為都可能出錯,仍要保留 tests、成品 rubric 與多次 run。
3. 可以拿 MTPLX 和 oMLX 的 tok/s 直接比較嗎?
不夠。兩者的模型格式、cache、batching 與最佳場景不同;至少同時比較 TTFT、task wall time、記憶體、成品與失敗率。
4. 為什麼不能用 MTPLX 2.5.4 的 --no-mtp 當基準?
因為它會連 prefix cache 一起失去。維護者確認 v2.8.0 才讓 AR 共用 restore/prefill 路徑;舊版差值混入 cache 效果。
5. 16GB Mac 能測 Qwen3.8 27B 嗎?
不建議把它當官方推薦路徑。目前 MTPLX README 建議 16GB 跑 4B/9B,Qwen3.8 27B Optimized Speed 建議 32GB 以上;選能留下系統 headroom 的模型。
6. 要關掉 Prefix Cache 才公平嗎?
依問題而定。想隔離 decode 就讓兩組都用相同 cold/cache policy;想知道日常 Agent 體感,就保留兩組相同的 cache,並另報 cached tokens 與 TTFT。
7. 用一個長任務跑一次夠嗎?
不夠。至少準備多個任務、採配對 ABBA,隨機取樣則每題重複;否則單次工具錯誤、降頻或剛好較短的答案就能翻轉名次。
8. 哪些更新後要重跑?
任何會改變執行路徑的更新。包括 MTPLX/MLX、模型 revision、量化、profile、chat template、Agent client、工具 schema、context 與 macOS;v2.9.0 Turbo 更被官方明確要求重跑。
給新手的 5 個重點
- 先用 v2.9.1、同 checkpoint 與同 client 做 MTPLX MTP/AR,別先跨引擎。
- 成品與穩定性先過關,才計算 wall-time speedup。
- Prefill、decode、cache 與工具等待分開記,才知道快在哪一段。
- 用 fresh repo、fresh session、ABBA 與多任務,降低順序和隨機性偏差。
- 跨引擎只做整體選型,清楚標記模型格式、量化、cache 與 adapter 差異。
想把 endpoint、Agent harness、eval 與部署串成完整練習,可看 AlphaLab 軟體工程課程;更多本機 AI 與 Agent 文章整理在 AI 專區。
接著閱讀
左右滑動查看更多推薦
結語:今晚先跑一題 ABBA,不要先追排行榜
回到開頭的公式:有效速度=通過驗收的任務數 ÷ 總 wall time。今晚先挑一個有 tests、會改檔、會多輪用工具的任務,用 MTPLX v2.9.1 跑 A1→B1→B2→A2;保存 health、settings、trace、commit 與評分。品質守住、長 session 不出錯、成品 wall time 又穩定下降,才把 MTP 擴到更多任務。這份屬於你自己的驗收紀錄,比任何一張 tok/s 截圖更能回答「本機 Agent 真的快多少」。
