AI-LECTURER 速報課|2026-08-02|約 26 分鐘

29GB記憶體、每秒0.5個字:WASTE怎麼把2.78兆參數的巨獸模型塞進你的筆電

取材:Run Kimi K3 using 29 GB of RAM at 0.50 tok/s(Hacker News(AI 高人氣))
📍 真實場景
陳威,一人新創公司的後端工程師,白天忙產品,晚上喜歡自己摸最新的開源大模型做研究

他看到Kimi K3開源、還有人只用29GB記憶體就跑起來的消息,很興奮地想在自己那台64GB記憶體的舊MacBook上試試看,證明『不用花錢租伺服器,自己的筆電也能碰到最前沿的巨獸模型』

😖 卡住的地方:模型轉換後的檔案是982GB,比整台筆電的記憶體大了十幾倍,過去的經驗告訴他這種情況一律是直接跳出『記憶體不足』的錯誤,連跑都跑不動,更別說等它輸出答案
💡 這堂課會讓他看懂WASTE這套推理引擎怎麼靠『常駐記憶體+隨選讀取硬碟』這招,把一個記憶體塞不下的模型變成『跑得動、只是慢』,並理解背後『用時間換空間』的工程判斷是怎麼做出來的,以後遇到『東西太大裝不下』的問題,也能學會問對的問題

🧭 這到底是什麼(白話版)

Kimi K3是一個2.78兆參數的開源大模型,體積驚人,轉換成WASTE能讀的格式後檔案有982GB。一般的做法是把整個模型全部載進記憶體才能運算,但消費級電腦的記憶體通常只有幾十GB,模型檔案卻大上十幾倍,照傳統做法一律是『記憶體不足』直接失敗,連開始運算的機會都沒有。

但K3其實是一種MoE(混合專家模型)把一個大模型拆成很多個小『專家』模組,每次只喚醒其中一小部分來運算,而不是整個模型一起動架構:每處理一個token,路由器(router)MoE模型裡負責『這一步該交給哪幾個專家處理』的小模組,等於是決定每次要喚醒誰的調度員只會挑出全部專家裡大約4%出來動用,剩下96%在那個當下根本用不到。既然用不到,何必逼它一直待在昂貴又有限的記憶體裡?

WASTE的做法,就是把每個token都一定會用到的『主幹』部分放進常駐記憶體從程式一啟動就一直待在RAM裡的資料,隨時能拿來用,不用再等它從硬碟讀進來,至於數量龐大、但每次只用一小撮的『專家』權重(模型參數)模型裡那些在訓練過程中被調整出來、用來決定輸出結果的數字,模型檔案的大小基本上就是這些數字的總量,則留在硬碟上,等真的被路由器點名要用時才即時讀進來,讀完之後放進一塊大小固定、滿了就要按規則踢人的快取空間。

這個做法換來的是『跑得動』,但代價也很直接:實測的命中率大約38%(9038次命中、14514次未命中),代表六成多的時候都得多花一次硬碟讀取,換算下來速度只剩每秒0.45到0.62個字,一句話要等二十幾秒。作者自己也說得很白:這不是免責聲明,是事實——正確、但慢。

🎯 為什麼值得你花時間

有限硬體也能碰到前沿模型以前想在自己機器上跑兆級參數的旗艦模型,第一句話通常是『你的記憶體不夠,死心吧』。WASTE證明了『跑得動』和『裝得下』其實是兩件可以分開處理的事,讓沒有伺服器等級硬體的個人開發者、學生、研究者,也有機會親手摸到、驗證最前沿的模型,而不是只能看論文和別人的Demo影片。
把『空間問題』改寫成『時間問題』記憶體不夠時,直覺反應通常是『想辦法把模型變小』——量化、剪枝、蒸餾。WASTE換了一個角度:不改模型本身一個位元,而是精準計算『這一刻到底需要哪一小塊資料』,把原本要花在買更多記憶體的空間成本,轉換成願意多等幾秒的時間成本。這種『用時間買空間』的思路,在資料庫、作業系統的虛擬記憶體設計裡其實一直都在用,只是這次搬到了兆級參數的AI推理引擎上。
揭露了MoE架構的一個現實限制文章誠實地寫出:他們原本以為最有效的兩個優化方向——『讀取時更精準地挑位元組』和『讓更多資料常駐記憶體』——實測後都被否決了。這告訴我們一個更深的教訓:系統能不能被優化,往往不是工程師想加就能加,而是被底層資料的統計特性(例如存取分佈有沒有『長尾』)先天限制住了;看懂這個限制,才知道力氣該往哪裡使。

⚙️ 它是怎麼運作的

1
拆開模型:主幹 vs 專家WASTE先把模型分成兩塊:每個token都一定會用到的『主幹』,以及數量龐大、但每次只用一小撮的『專家』模組群。主幹整份常駐記憶體,專家群留在硬碟。
2
路由器決定要問誰每處理一個token,路由器會從全部專家裡,挑出這一步真正要用的那一小群(K3裡大約占整體的4%),其餘的專家在這一刻完全用不到。
3
先檢查快取,命中就直接用引擎先看這幾個被點名的專家是不是剛好已經待在記憶體裡的『快取』區——如果是,幾乎不花額外時間,直接拿來算。
4
沒命中,就去硬碟讀一份如果快取裡沒有,就得去硬碟把那個專家的資料讀進來。WASTE的設計是『一個專家剛好對應一次讀取』,讀完後這份資料會被放進快取,供接下來可能的重複使用。
5
快取滿了,就得騰位置快取空間是固定大小、不能無限塞的(例如實測用了17.56 GB的專家快取),所以塞新資料進去之前,得先按規則(例如踢掉最久沒用到的)把舊資料清出去,才裝得下。
6
真正的瓶頸:等硬碟,不是等算術命中率只有大約38%,代表六成多的時間都在等硬碟把資料讀進來,而不是卡在GPU/CPU的乘加運算上。這也是為什麼團隊接下來想做的優化方向,是讓『讀取專家資料』跟『進行運算』這兩件事盡量重疊進行,而不是讀完才開始算——與其硬要少讀幾個位元組,不如想辦法別讓機器在等硬碟時整個閒置。
同一顆引擎、兩種體感:模型大小差距 vs. 速度差距
模型轉換後容器大小最低需要的記憶體實測速度
Kimi K3(2.78兆參數)982 GiB29.05 GiB每秒 0.45–0.62 個字
Kimi-Linear(480億參數)19 GiB1.87 GiB每秒 10.7 個字

🔍 程式碼漫遊(點有 ● 的行看白話講解)

這段是簡化過的示意程式碼,把文章描述的『有限快取+隨選讀取硬碟』行為抽出來寫成一個小型的ExpertCache類別,方便理解WASTE的核心邏輯——它不是WASTE的真實原始碼(WASTE是用C寫的),只是把概念翻成好讀的Python。

class ExpertCache:
💬 代表『快取管理員』:負責決定哪些專家資料現在待在記憶體裡
def __init__(self, capacity_gb):
💬 建立快取時,先講好『記憶體上限』是多少(例如文章裡的17.56 GB)
self.capacity_gb = capacity_gb
💬 把記憶體上限記下來,之後每次要塞新資料都得檢查有沒有超過這個數字
self.resident = {}
💬 目前真的待在記憶體裡的專家資料,key是專家編號、value是它的大小
self.recent_order = []
💬 記錄使用順序,最前面是最久沒被用到的,最後面是剛剛才用過的
def used_gb(self):
💬 算出目前快取已經用掉多少記憶體
return sum(self.resident.values())
💬 把目前常駐的所有專家大小加總起來
def get(self, expert_id, size_gb, read_from_disk):
💬 每次路由器點名要用某個專家時,就呼叫這個方法
if expert_id in self.resident:
💬 關鍵判斷:這個專家剛好已經在記憶體快取裡嗎?
self._mark_recent(expert_id)
💬 命中!只需要更新一下『最近使用』的順序,幾乎不花額外時間
return 'hit'
💬 回報這一次是命中,對應文章裡9038次命中的其中一次
read_from_disk(expert_id)
💬 沒中,只好真的去硬碟讀一份——這就是拖慢速度、耗掉20幾秒的元兇
self._admit(expert_id, size_gb)
💬 讀完之後,把這份資料收進快取,供接下來可能的重複使用
return 'miss'
💬 回報這一次是未命中,對應文章裡14514次未命中的其中一次
def _mark_recent(self, expert_id):
💬 把某個專家標記成『剛剛用過』
self.recent_order.remove(expert_id)
💬 先從舊的位置移除
self.recent_order.append(expert_id)
💬 再放到最後面,代表它現在是最新使用的
def _admit(self, expert_id, size_gb):
💬 把一份新讀進來的專家資料塞進快取
while self.used_gb() + size_gb > self.capacity_gb:
💬 如果空間不夠塞這份新資料,就要先騰位置
oldest = self.recent_order.pop(0)
💬 找出最久沒被用到的那個(LRU(最近最少使用)一種快取滿了要騰位置時的規則:先踢掉最久沒被用到的那個
del self.resident[oldest]
💬 把它從記憶體裡真的踢掉,空間才騰得出來
self.resident[expert_id] = size_gb
💬 確定空間夠了,把新資料正式收進常駐記憶體
self.recent_order.append(expert_id)
💬 同時把它加進『最近使用』名單的最後面

🛠️ 動手做:『快取預算』怎麼決定你等多久:專家快取模擬器

  1. 先觀察上方的快取預算滑桿:目前設定是8格,代表只有8個專家的資料能同時待在『記憶體』裡,其餘52格平常都放在『硬碟』上。
  2. 按下『產生20個token』,觀察格子被點亮(代表這一步被路由器點名要用)、命中時格子維持綠色,未命中時格子要先從硬碟讀進來、可能還會把別的綠色格子擠掉變回灰色。
  3. 看右下角的命中率跟模擬耗時:模擬時特地讓『命中』只花2毫秒、『未命中』要花50毫秒,藉此還原文章裡『命中率越低、整體越慢』的真實現象。
  4. 把預算滑桿拉到接近上限(例如40格,接近全部60格),再重新產生一次,比較命中率跟耗時的變化幅度——你會發現就算快取開到很大,命中率也不會顯著逼近100%,這正好對應文章講的『這個模型家族的路由器沒有長尾可以砍』:使用分佈太平均,快取再大也很難靠『少數常用者』撐起高命中率。
  5. 最後把預算調到最小(2格),感受最壞情況下耗時暴增的樣子,體會為什麼記憶體太小、又要跑超大模型時,速度會被『硬碟等待』徹底綁架。
👇 下面是活的,直接操作

🧠 工程思維透鏡(資深工程師看到的是什麼)

🔭 為什麼工程師寧願要每秒只有0.5個字的慢速度,也不乾脆把模型裁小一點?
文章特別強調『這不是蒸餾、剪枝或縮減過的版本』——這個專案要證明的重點是『完整、未閹割的旗艦模型,在消費級硬體上是可觸及的』這件事本身。如果先把模型砍小,證明出來的就是另一件事(『裁剪過的模型能跑』),跟原本想驗證的問題不一樣了。速度慢是誠實揭露出來的代價,不是拿模型正確性去換來的,這是先把『能不能』跟『快不快』分成兩個獨立問題來看待的工程判斷。
🔭 為什麼『更精準地挑選要讀哪些位元組』和『讓更多資料常駐記憶體』這兩個看起來最直覺的優化方向,反而都失敗了?
文章直接寫出兩個結論:第一,這個模型家族的路由器分佈太平均,沒有『長尾』可以犧牲——意思是沒有一小撮專家是明顯很少用、可以放心不管的,所以想靠『少讀一點』取巧行不通。第二,工作集(每次真正需要用到的資料總量)本身就大到這台機器的記憶體留不住,砸多少錢加大快取,機器都『留不住』它。這說明系統能不能被優化,往往不是工程師想加就能加,而是被底層資料的統計特性先天限制住了。
🔭 文章最後提到的『重疊專家讀取與運算』,解決的到底是空間問題還是時間問題?
記憶體(空間)已經到極限,唯一還能擠的是延遲隱藏讓系統在等待慢速的事情(像硬碟讀取)發生時,不要整個停下來乾等,而是先去做別的、之後再需要時已經做完了——也就是讓CPU/GPU在等硬碟讀取的同時,先去做其他還算得動的運算,而不是整個閒置乾等。即使讀取速度本身沒有變快,只要機器沒有整段時間都在發呆,總耗時就能縮短。這是一個純粹的時間工程思路,跟資料庫、作業系統裡『用非同步I/O換取吞吐量』是同一套邏輯,只是這次用在AI推理引擎上。

📝 隨堂考(點選答案,立即回饋)

Q1. WASTE能讓Kimi K3在消費級電腦上跑起來,主要是利用了MoE模型的什麼特性?
✅ WASTE沒有改動模型一個位元,也沒有讓硬碟變快;它能生效完全是因為MoE架構本身『每一步只用一小撮』的特性,讓『其餘暫時不用的專家』可以先放在硬碟上,等被點名才拿。
Q2. 文章提到,想靠『讀更少位元組』或『多塞一點進記憶體常駐』來加速,結果為什麼都失敗了?
✅ 文章明講:兩個看起來最直覺的優化方向都『被量測、然後被否決』——不是沒嘗試,是嘗試完發現架構的統計特性根本不支持這樣優化。
Q3. 文章提到的命中率大約38%(9038次命中、14514次未命中),代表什麼意思?
✅ 命中率是快取設計最核心的指標:38%的命中率,代表六成多的時候都得付出一次硬碟讀取的等待時間,這也是為什麼整體速度只剩每秒0.5個字左右。
Q4. 為什麼這個專案堅持用完整版的Kimi K3,而不是先裁剪過再拿來展示?
✅ 文章特別強調『這不是蒸餾、剪枝或縮減過的版本』——他們要驗證的重點是『完整模型可以在消費級機器上被觸及』這件事本身,速度慢是誠實揭露的代價,不是拿模型正確性去換來的。

🃏 翻牌記憶卡(先想答案,再點開對答)

MoE(混合專家模型)點我翻面
把大模型拆成很多個小『專家』模組,每個token只喚醒其中一小部分(K3裡大約4%),而不是整個模型一起算。
常駐記憶體 vs 隨選讀取點我翻面
常駐記憶體=一直待在RAM裡隨時能用;隨選讀取=平常放硬碟,真正需要那一刻才讀進來,換來省記憶體、但要多等硬碟的時間。
LRU(最近最少使用)點我翻面
快取滿了要騰位置時的規則:把最久沒被用到的那個先踢掉,留位置給新的資料。
命中率(hit rate)點我翻面
要用的東西剛好已經在快取裡的比例;命中率越低,代表越常要花額外時間去硬碟現撈,速度也就越慢。
延遲隱藏(latency hiding)點我翻面
在等待慢速的事(像硬碟讀取)發生時,讓系統先去做別的事,而不是整個閒置乾等,藉此縮短總耗時。

✅ 離開前自測(全勾=這課真的學會了)

0%