MTP 合進 llama.cpp 後,27B 快了,但我的 35B 沒什麼感覺
上週看到 PR #22673 merged 進 llama.cpp,第一個反應是「終於」。MTP(Multi-Token Prediction)這個東西跟 speculative decoding 有點像但不完全一樣——你不需要另外一個 draft model,模型本身就會同時預測接下來幾個 token,理論上可以讓 decoding 速度快很多。
然後社群的回報開始進來,我花了點時間把數字消化一遍,有個地方蠻值得講的。
27B 的人真的有感
先說好消息。有人跑了蠻完整的 benchmark,27B 在長 context 的場景下效果很明顯:
- 15k prompt 的 single turn:87.44s → 77.39s,大約快了 11%
- 5-turn 對話加起來:258.65s → 200.55s,差了快 22%
11% 到 26% 這個範圍,對本地跑模型來說不是小數字。你想想 5-turn 對話省掉快一分鐘是什麼感覺——我日常用本地模型做 code review 的時候,就是那種「你問一個問題、等它生完、再問下一個」的循環,累積起來很有感。
35B 就沒那麼快樂了
然後是壞消息。同樣的測試,35B 的結果:部分場景 +2%,某些情況甚至 +11%,講白話就是:沒有更快,還可能微幅變慢。
這個落差剛開始讓我有點困惑,因為照理說 MTP 是 model-level 的改進,不應該會因為 model 大小差這麼多。後來想了一下,覺得答案跟 prefill/decoding 的比例有關係。
瓶頸在哪裡,決定你能省多少
MTP 本質上是在加速 decoding 的部分,也就是模型一個字一個字「生」出來那段。但整個 inference 的時間是由兩個東西組成的:
Prefill:把你的 prompt 全部讀進去,建 KV cache。
Decoding:一個 token 一個 token 生出回答。
MTP 只碰 decoding。如果你的 workload 是「長 prompt + 短回答」,那 prefill 佔的比例本來就高,MTP 省下來的那塊實際上只佔總時間的一小部分。
27B 跑得動,同樣硬體下 prefill 速度相對快,decoding 才是主要瓶頸,MTP 發揮空間就大。35B 在同樣硬體上 prefill 本來就已經夠慢了,MTP 把 decoding 壓下去之後,prefill 就變成更明顯的新瓶頸,整體改善有限,甚至因為 MTP overhead 讓某些場景反而慢一點點。
換個說法:你家的網路很慢,買了台新電腦也不會讓網頁跑更快。
對我的 workflow 實際改了什麼
我手邊跑本地模型主要有兩個用途:一是長文件分析(contract review、tech spec review),二是多輪 code 問答。這兩個場景差異蠻大的。
長文件分析幾乎都是大 prompt 進去、短到中等長度的回答出來,prefill 壓力大,decoding 相對快——MTP 對這塊幫助有限,跑完 benchmark 之後我基本上打消了對這個場景的期待。
多輪 code 問答則不一樣,context 是慢慢累積的,每輪 prompt 不一定很長,但 decoding 的量可能不小(特別是要它生完整函式或詳細解釋的時候)。這種場景 27B 的改善就比較明顯,27B 現在確實是我多輪對話的主力選擇。
☕ 所以如果你在用 27B 跑多輪對話、decoding 是主要耗時的,現在更新 llama.cpp 值得。如果你跑 35B、或者使用場景是大 prompt 進去短答案出來,先別期待太高,等社群有更多不同硬體的實測再說。
一個更根本的問題
MTP 合進來這件事讓我想到另一個問題:本地模型的速度優化,我們是不是一直在優化錯誤的地方?
decoding 這塊的優化(speculative、MTP)做了很多,但 prefill 的瓶頸隨著大家用越來越長的 context 只會越來越明顯。特別是現在 RAG + long context 很流行,你塞進去的 prompt 動不動就幾萬 token,prefill 時間有時候已經是 decoding 的好幾倍了。
下一波真正有感的優化,我覺得會在 prefill 加速這塊——不管是更激進的 KV cache 壓縮、還是 chunked prefill 的改進。MTP 是一步,但不是終點。
先這樣,等我把 35B 的場景再多跑幾個不同 prompt 長度,看看 prefill ratio 跟速度改善的相關性有多強,有結果再補一篇更完整的測試報告。
作者:咖啡驅動開發