跳到內容

Technology

Strata 拆解:一張 12 GB 顯示卡怎麼跑 1250 億參數的模型

Strata 讓 Qwen3.8-Flash-Next 這個 1250 億參數的 MoE 模型在一般電競 PC 上執行。整理它如何把模型拆到顯示卡、記憶體與 SSD,一個 token 的計算怎麼在 GPU 與 CPU 之間分工,以及它和通用推論引擎的差別與限制。

AI
Published: at 09:00 AM
編輯本頁下載圖卡

專案 GitHub:Niko1221/Strata

Strata 是一個開源的推論引擎,專門用來在家用電腦上執行 Qwen 團隊的 Qwen3.8-Flash-Next。推論引擎就是「把訓練好的模型拿來回答問題」的程式。這個模型有 1250 億個參數,壓縮到 2 位元後的檔案仍有 66 GB 左右,平常要放在伺服器上跑。Strata 的目標機器是一張 12 GB 顯示卡、64 GB 記憶體、一顆六核心處理器的電競 PC。

專案在 2026 年 9 月 25 日建立,到 10 月 6 日已有將近 14,000 顆星。作者在 RTX 5070(12 GB)上量到的寫字速度是每秒 53 到 94 個 token,視壓縮程度而定,已經比一般人讀字快。

這篇文章依序說明:

內容根據專案的 README、docs/ 裡的說明、作者附的技術報告(docs/paper/Strata-Paper.pdf),以及 src/、serve/ 的原始碼。

先認識幾個名詞

這個模型為什麼有機會塞進小顯卡

Qwen3.8-Flash-Next 有 48 層,每層有 512 個專家,總共 24,576 個。路由器每次只挑 10 個,所以一個 token 只會碰到約 2% 的專家權重。

技術報告用 Q2_0 檔案列出各部分的大小,以及每個 token 實際要讀多少:

模型的部分存放大小每個 token 讀取Strata 放在哪裡
被路由的專家(48 層 × 512)34.0 GB0.66 GB(2%)RAM 全部,VRAM 放常用的約 4,500 個
混合器、注意力、共享專家、路由器1.8 GB1.8 GBVRAM
閘控殘差權重1.3 GB1.3 GBVRAM
輸出層0.44 GB0.44 GBVRAM
n-gram 嵌入表28.8 GB最多 23 KBSSD 與作業系統快取
MTP 預測層0.8 GB每次猜測時VRAM

這張表的重點在第三欄。66 GB 的檔案裡,每個 token 一定要讀的部分大約 3.5 GB,可以整個放進 VRAM。真正麻煩的是專家:總量 34 GB 放不進顯示卡,但每個 token 只用到其中 0.66 GB。

另外兩個架構特點讓長對話也不會撐爆 VRAM:

那張 28.8 GB 的 n-gram 嵌入表是用「最近三個 token 的編號」來查的,所以下一步要讀哪幾列,在需要之前就已經知道。Strata 因此把它留在 SSD 上,每個 token 提前一步讀 16 列。

三層記憶體:誰放在哪裡

Strata 依照上面那張表,把模型分到三個地方:

64 GB 記憶體剛好夠用:專家區光 Q2_0 就佔 34 GB,IQ3_XXS 佔 43 GB。這也是 README 說「第一次啟動時電腦可能卡住 1 到 3 分鐘」的原因:Strata 要把 35 到 55 GB 讀進 RAM 並鎖定一部分。

產生一個 token 時,一層裡發生什麼事

每一層的計算大致如下:

  1. GPU 先算這一層的混合器和路由器,得到這個 token 要用的 10 個專家編號。
  2. GPU 把這 10 個編號和輸入寫進一小塊主機記憶體。原始碼把它叫做 doorbell(門鈴),src/core/layer.cpp 的註解直接寫「這就是整個協定的重點」。
  3. CPU 一直盯著這個門鈴,一看到編號就把 10 個專家分成三份:
    • 已經在 VRAM 快取裡的,交給 GPU 算;
    • 沒在快取裡的,一部分由顯示卡的複製引擎透過 PCIe 從 RAM 搬上去算(IQ 系列格式約 55%,Q2_0 約 20%);
    • 其餘的由 CPU 直接在 RAM 裡算。
  4. CPU 把結果寫回 GPU 讀得到的記憶體,GPU 把所有專家的結果加總,進入下一層。

GPU 和 CPU 在同一層裡同時工作,下一層要等兩邊中較慢的那一邊做完。為了不讓 CPU 等驅動程式,Strata 把 48 層的整段計算錄成一個 CUDA graph。CUDA graph 是 NVIDIA 提供的機制,可以把一連串 GPU 工作錄下來一次送出,省掉每一步都要和驅動程式來回溝通的時間。

技術報告拆解了 4K 上下文、Q2_0 時的一輪時間(單位:毫秒):

項目時間
一輪總計34.3
等 GPU 的部分14.6
等 CPU 算專家13.4
MTP 猜測2.0
其他4.3

GPU 和 CPU 各佔約一半。作者的結論是這個引擎已經平衡,所以只升級其中一邊,速度最多只能提升約三分之一。

先猜再驗證:MTP 推測解碼

GPU 每輪最大的成本是讀那 3.5 GB 的固定權重。一次算一個 token 和一次算四個 token,讀的量幾乎一樣。推測解碼(speculative decoding)就是利用這一點:先用便宜的方法猜接下來幾個 token,再讓大模型一次把這些猜測全部檢查完,留下猜對的。

Qwen3.8-Flash-Next 本身附有一層 MTP(multi-token prediction,多 token 預測),專門用來猜後面的 token。量化過的 GGUF 檔案(llama.cpp 常用的模型檔格式)沒有包含這一層,所以 Strata 的安裝程式另外從 Qwen 釋出的原始 16 位元(BF16)檔案只抓這一層(約 5 GB),壓縮後放進 VRAM。

運作方式:

整體加速 1.6 到 1.8 倍。全部放在 VRAM 的引擎通常能拿到 2.5 到 3 倍,Strata 少一些,原因是每多驗證一個 token,那個 token 也有自己的 10 個專家,其中沒在快取裡的都得讓 CPU 算。

另外有一個補充機制叫 prompt lookup:回答在重複前文時(例如改程式碼、引用原文),直接從前文複製最多 5 個 token 當作猜測。它只在實測划算時啟用,改程式碼快 6% 到 11%,其他文字不受影響。

會跟著對話調整的專家快取

不同專家被挑中的頻率差很多,VRAM 裡放哪些專家,決定 CPU 要做多少事。Strata 的做法分兩步:

  1. 啟動時:根據事先在其他提示上記錄的使用頻率(data/expert-profile.bin),把最常用的專家先放進 VRAM。用沒看過的提示測試,4,500 個位置可以接住約 50% 的專家呼叫。
  2. 對話中:每四輪檢查一次,把這段對話一直在用、卻不在快取裡的專家換進來,一次最多 96 個,換掉最少用的。換的動作在 GPU 忙著猜測時進行。

第二步把命中率從 50% 拉到約 72%。expert_cache.hpp 的開頭註解說明了這件事的分量:CPU 算專家是整個引擎最大的單項成本,量測時每個 token 要讀 663.6 MB,佔掉一個 token 約三成的時間,唯一的解法是少讀這些位元組。

報告裡還有兩個小調整帶來明顯差異:

這也解釋了 README 的一句建議:VRAM 大小比顯示卡快不快更重要。每多 1 GB VRAM 大約多放 700 個專家,每多一個專家在 GPU 上,CPU 就少算一個。

讀長提示:把專家整批搬上 GPU

讀提示(prefill)和寫回答的狀況不一樣。一次讀進幾千個 token 時,每個專家都會被很多 token 用到,這時在 GPU 上算最划算。

Strata 每次最多讀 8,192 個 token。每一層開始前,把沒在快取裡的專家從 RAM 經 PCIe 送上 GPU,同時 GPU 先算已經送到的部分。暫存空間向專家快取借用,讀完再還回去。因為稀疏注意力只看有限的位置,提示讀取速度幾乎不隨長度下降。依 README 的量測,RTX 5070 上讀 32K token 的提示,Q2_0 約每秒 2,650 個,IQ3_S 約每秒 1,620 個。

讀過的內容會留下來。引擎在 RAM 裡保留最多 6 個對話檢查點,每個約 118 MB,在每個新的助理回合開始時和每 16K 個 token 時各存一次。新請求的開頭只要和某個檢查點完全一樣,就從那裡接著讀。最舊的那個檢查點通常是系統提示的結尾,會永久保留,所以同一個工具開新對話時,也能跳過共用的系統提示。技術報告把這項功能列為「未來最大的改進」,現在的版本已經做出來了。README 說第一次讀約 1 分鐘處理 30,000 個 token,之後的追問幾秒內就開始回答。

從請求到回答:外層的零件

上面講的都是 C++ 引擎(src/、include/,支援 NVIDIA 的 CUDA 和 AMD 的 HIP)。使用者實際碰到的是外面幾層:

一次請求的路徑:

  1. 你的程式把對話送到 http://127.0.0.1:8080/v1/...;
  2. server.py 依模型的聊天範本把對話排好,轉成 token 編號;
  3. 伺服器在引擎的標準輸入寫一行文字指令:GEN、最多產生幾個 token、取樣設定,後面接 token 編號;
  4. 常駐的 strata --serve 程序找出可沿用的檢查點,讀完剩下的提示,開始逐輪推測與驗證;
  5. 引擎把產生的 token 編號從標準輸出送回,伺服器轉回文字,以串流方式傳給你的程式。

引擎和伺服器之間只用文字指令溝通,好處是 server.py 可以換上一個寫好劇本的假引擎 MockEngine,所有 API 路徑都能在沒有顯示卡的機器上測試。預設一次只處理一個請求,其他的排隊;要同時處理多個,可以設定 "parallel": 2,但在 12 GB 的卡上每個回答都會變慢。

跟常見做法比起來特別在哪

在家用電腦跑放不進顯示卡的模型,最常見的工具是 llama.cpp:把放不下的部分留在 RAM 交給 CPU 算。技術報告認為這樣做可行,但機器的大部分零件多數時間都閒著。Strata 的差異主要在以下幾點。

一個引擎只為一個模型寫。 通用引擎要支援各種模型,Strata 則依照 Qwen3.8-Flash-Next 每一部分的大小與使用頻率來決定放置位置、快取大小與分工比例。報告說這個想法來自 Splash、ninfer 和 HyperQwen 這幾個同樣只服務單一模型的專案。代價很直接:Strata 只能跑這個模型和它的幾個變體(Coder、Swift 1.5、Unsloth 的版本)。

GPU 和 CPU 在同一層裡同時工作。 讓 CPU 分擔 MoE 專家的想法早就有,Fiddler、KTransformers 都做過;MoE-Infinity 研究過專家快取,PowerInfer 利用冷熱權重的差別。Strata 把這些想法組合起來,再加上門鈴機制、會跟著對話調整的快取、MTP 推測解碼,以及讓顯示卡的複製引擎分擔一部分搬運。

堅持結果精確。 推測解碼的輸出和一般貪婪解碼逐字相同。和 llama.cpp 比較下一個 token 的機率分布,平均 KL 散度(衡量兩個機率分布差多少的指標)是 0.022,比 llama.cpp 自己的 CPU 版和 GPU 版之間的差距 0.058 還小。i-quant 格式的運算也是從 llama.cpp 的程式碼轉寫過來,再拿真實模型的各層逐一比對。

每個說法都附量測,失敗的嘗試也記下來。 專案的 AGENTS.md 明文要求「沒有量測就不下結論」。技術報告記錄了沒有效果的做法,例如把一輪拆成兩組 token、讓一組的 CPU 工作和另一組的 GPU 工作重疊。結果精確但慢了約 7%(每秒 85.8 對 91.8 個 token),原因是固定權重要多讀一次,每組共用的專家也變少。src/kernels/ 底下大量的 *_parity.cpp 測試,用來確認每個手寫運算核心和參考實作算出相同結果。

限制

註釋

編輯本頁

Podcast

關於語音摘要

此語音摘要由 Google NotebookLM 提供,不完全代表作者本人對文章的理解。