引言:一台「不該跑 AI」的機器
這篇文章是 point.free 上一篇 Gemma 4 系列的最後一篇——前面兩篇講了怎麼把 Gemma 4 的 MTP drafter 量化、怎麼跟 verifier 配對,而這一篇要回答一個更刁鑽的問題:
「把這些成果丟到一台根本沒有資格跑 AI 的機器上,會怎樣?」
作者的硬體規格聽起來像是一台從墳墓裡挖出來的古董:
- CPU:Intel Xeon E5-2620 v4(2016 年產,約為當前筆電 CPU 的五分之一慢)
- 記憶體:128 GB DDR3(頻寬只有最新筆電 RAM 的五分之一到六分之一)
- GPU:無(連內顯都沒有)
換作一般工具,比如 ollama,直接放棄。但這篇文章的作者說:「等等,聽我說完……」
核心問題:記憶体牆(Memory Wall)
要理解這篇文章的精髓,先搞懂一個概念——LLM 推理的瓶頸不在運算能力,而在記憶體頻寬。
當你使用 ChatGPT 看著文字逐字流出時,你看到的是「decoder pass」。在這個階段,處理器要不斷把龐大的模型權重從記憶體拉進 CPU cache 才能計算下一個 token。處理器的運算速度其實很快,但它大部分時間都在等記憶體傳輸——這就叫「記憶體受限」(memory-bound),而非「運算受限」(compute-bound)。
這就是著名的「記憶体牆」問題。不管你用的是 2016 年的 Xeon 還是最新的 H100,這堵牆都在那裡。
所以,直接拿預設參數跑 llama-cli 在 DDR3 機器上會慢到令人發指。解法是什麼?把 ik_llama.cpp 能用的優化選項全部拉滿。
那串「魔法咒語」
作者甩出了一長串 llama-cli 參數,看起來像中世紀巫師的咒語:
llama-cli \
--model gemma-4-26B-A4B-it-Q8_0.gguf \
--model-draft wikitext-2-raw_ik-llama-mtp_drafter-conservative/gemma-4-26B-A4B-it-assistant-Q8_0.gguf \
--spec-type mtp --draft-max 3 --draft-p-min 0.0 --spec-autotune \
-cnv --color --jinja --special \
-sm graph -smgs -sas -mea 256 --split-mode-f32 \
--temp 0.7 -t 8 --parallel 8 \
--cpu-moe --merge-up-gate-experts \
--flash-attn on --mla-use 3 \
--mlock --run-time-repack --no-kv-offload
25 個參數,一半沒有文件說明,四分之一會靜默失敗。這就是作者所說的「可用性的護城河」(usability moat)——黑盒工具讓你看不見這些,但也讓你無法優化。
讓我們一個一個拆開看:
1. 猜解編碼(Speculative Decoding)
這是整篇文章最核心的優化。原理很簡單:用一個超小型的 drafter 模型先「猜」接下來幾個 token,然後用 260 億參數的 verifier 一次性驗證。猜對的 token 一次接受,最多一次猜 3 個(--draft-max 3),全部接受(--draft-p-min 0.0),並根據不同工作負載自動調整鏈長(--spec-autotune)。
在 CPU 上,這個策略比在 GPU 上更有價值。因為 CPU 運算便宜,而 verifier 的權重要透過 cache 流過來的代價昂貴。drafter 的 Working set 小到能塞進 L3 cache,所以多跑 drafter 的邊際成本幾乎為零。
2. CPU 上的 MoE 路由優化
Gemma 4 26B-A4B 是一個 MoE(Mixture of Experts)模型,有 128 個 expert,但每個 token 只激活其中 8 個,所以實際運算的參數只有約 38 億(總參數 252 億)。
CPU 的記憶體管理跟 GPU 完全不同。GPU 有巨大的 HBM(高頻寬記憶體),CPU 則依賴晶片上超小的 cache(L1、L2、L3)。在 MoE 模型中,不斷在 128 個 expert 之間跳來跳去會造成「cache thrashing」——CPU 的 cache 不斷被清空,從慢速記憶體重新載入權重。
--cpu-moe 讓路由演算法針對 CPU cache 架構優化,--merge-up-gate-experts 把兩個獨立的矩陣運算合併成一個,少跑一趟記憶體總線。日誌會顯示:fused_up_gate = 1。
核心數用 -t 8(物理核心數)而不是 16(SMT 執行緒數),因為記憶體受限的工作負載下,多開執行緒不會增加頻寬,只會增加排程開銷。
3. 記憶體固定與重組
--run-time-repack:在推理開始前,把權重矩陣在記憶體中重新排列,對齊 CPU cache 的預期格式。啟動時會多花幾秒,但推理時能最大化記憶體頻寬利用率。日誌顯示:Repacked 265 tensors。
--mlock:把 27 GB 的模型權重「釘」在實體記憶體中,防止 Linux 把它 swap 到硬碟。如果不設這個,模型被 swap 出去的那一刻,生成速度直接歸零。
--no-kv-offload:KV cache 是模型的短期記憶。通常引擎會試著把它放到 GPU,但我們沒有 GPU,這個參數直接跳過偵測 GPU 的步驟。
4. 圖分割(Graph Split)
這組參數控制計算圖在記憶體區域間的分配,有點像業界說的「Tensor Parallelism」。
--split-mode-f32:資料在處理器之間分割後重新拼接時,用 32 位元浮點精度,避免捨入誤差導致 AI 幻覺。-sas(Split Across Sockets):跨 CPU 插槽分配工作負載。
不過在這台機器上,-sm graph 因為 MTP 架構還不被支援,會靜默降级成 layer 分割模式。作者說這個參數留著,未來版本可能就用得到了。
5. Flash Attention 與 MLA
Flash Attention 是這篇文章最讓人驚艷的部分。
標準的 attention 機制要計算一個 N×N 的矩陣(N 是 token 數量)。如果輸入一份 10 萬字的文件,這個矩陣會膨脹到 100 億個格子。通常處理器會把整個矩陣寫到記憶體,然後再讀回來——浪費頻寬。
Flash Attention 把 attention 的 softmax 和矩陣乘法合併(kernel fusion),把巨大的矩陣切小块在 cache 裡算完,根本不需要寫到記憶體。這個優化原本是為 GPU 設計的,ikawrakow(ik_llama.cpp 的作者)把它移植到了 CPU 上。
MLA(Multi-Head Latent Attention) 則是另一個記憶體救星。標準的 KV cache 為每個 token 儲存原始的 Key 和 Value 資料,佔記憶體極快。MLA 把這些資料壓縮成一個更緊湊的「潛空間」表示,大幅減少 KV cache 的記憶體佔用。
結果:82 GB 的記憶體佔用在 DDR3 上
跑完所有優化後的記憶體帳單:
- 模型權重:約 25 GB
- KV cache(262K 完整上下文):約 56 GB
- 總計:82 GB
KV cache 比模型本身還大。在一台 2016 年的 Xeon 上,用 DDR3 記憶體,跑一個 260 億參數的 MoE 模型,而且沒有 GPU。
但關鍵是:它跑到了「閱讀速度」。
結論:護城河不在矽片裡
這篇文章最後有一段非常有力的總結:
「在舊硬體上跑 AI 的瓶頸不只是硬體本身,而是你需要真正理解 inference engine 是如何運作的。」
數據中心的 GPU 集群、企業 API token、龐大預算——這些對特定工作負載確實很有用。但對 open-weight 模型能覆蓋的場景來說,你只需要一台二手設備,加上拒絕讓黑盒工具替你決定一切。
有了正確的 fork、校準過的量化模型,以及對記憶體架構的理解,可用性的護城河就會消失。
Open Weight AI 的 bleeding edge 沒有鎖在付費牆後面。它就在你一台十年舊伺服器的命令列上。
給開發者的啟示
這篇文章給所有想在本機跑大模型的開發者幾個實用建議:
別怕用
llama-cli而不是 ollama:黑盒工具方便,但你要榨出舊硬體的最後一滴效能,就得直視每一行參數。Speculative decoding 是 CPU 推理的銀彈:如果你只有 CPU,這個技術幾乎是必開的。
注意
--mlock和ulimit:很多人跑著跑著突然變超慢,就是因為模型被 swap 出去了。記得ulimit -l看一下記憶體鎖定限制。Flash Attention on CPU 是真的:ikawrakow 的 ik_llama.cpp 把 GPU 級優化帶到了 CPU 上,值得關注。
DDR3 也能戰:記憶體頻寬確實重要,但透過軟體優化,舊記憶體也能跑出實用的速度。
原文:A 10 year old Xeon is all you need by point.free,2026 年 6 月 1 日