Qwen3.5-122B on DGX Spark · part 1
[vLLM] Qwen3.5-122B 跑起來了。但只有 14 tok/s。
前言
這篇講的是一個看起來像失敗、但其實不是的結果。
套用第一篇的四個 SM121 bug 修法之後,Qwen3.5-122B 在 DGX Spark 上正常運作。輸出正確。模型可以用。但速度穩定在 14 tok/s——大約是 gpt-oss-120B 在同一台機器上的四分之一。
怎麼調都不動。這就是這篇的故事。
用個比喻:想像一條十二線道的公路,六條是鋪好的柏油路,六條還是泥土路。車子在跑——沒有壞掉——但一半的車道在工程速限裡爬行。硬體沒有問題。架構裡一半的層(GDN 層)缺少最佳化的軟體支援。你沒辦法靠調整駕駛方式來修一條還沒鋪好的路。
我想做什麼
目標很單純:用 Qwen3.5-122B-A12B-NVFP4 當 DGX Spark 的主力模型。122B 參數,NVFP4 量化,128 GB 統一記憶體——算法沒問題:122B × 4-bit ≈ 61 GB,剩下空間給 KV cache。gpt-oss-120B 在同一台機器上能跑 59 tok/s,所以對 122B NVFP4 的預期也在這個量級。也許稍慢一點——模型更大,架構不同——但應該在同一個數量級。
14 tok/s 不在預期裡。
我做了什麼
套用第一篇的修法(SM121 PTX 路徑、Marlin thread race、SupportsQuant、排除 CUTLASS_FP4)之後,模型正常載入,輸出正確。前幾個 token 出得很快,然後吞吐量穩定在 14 tok/s。
把能調的全試了:
- 拿掉
--enforce-eager— 本來就沒有,不是這個問題 - KV cache dtype — fp8,跟 gpt-oss 一樣,沒有差別
--max-num-batched-tokens— 上下調整,幾乎沒有影響VLLM_MXFP4_BACKEND=marlin— 已設定,啟動 log 確認有讀到--moe-backend marlin— 已設定- GPU 記憶體使用率 — 0.90,標準值
14 tok/s 沒有動。這就是「調參問題」變成「架構問題」的時刻。
問題真正在哪
Qwen3.5-122B-A12B 是混合架構,不是標準 Transformer。它把兩種層混在一起:
- 標準 attention 層 — 一般的 Transformer MHA/MLA,Marlin 有針對這種計算形狀特別最佳化的 kernel(可以想像成:有專用工具)
- GDN(Gated Delta Network)層 — SSM 風格的遞迴層,必須保持 BF16
Marlin 對標準 linear 層和 MoE expert GEMM 有快速的特化 kernel。對 GDN,沒有。每個 GDN GEMM 都走 generic fallback 路徑——能跑,但慢。
這也解釋了第一篇的 SupportsQuant 修法為什麼不能省:沒有它,vLLM 會把 GDN 層量化成 NVFP4,GDN 的遞迴 hidden state 損壞,輸出變成垃圾。修法讓 GDN 保持 BF16——正確的行為——但代價是 GDN 跑在沒有特化 kernel 的路徑上。
在 GB10 的 273 GB/s 頻寬下,算法很直接:搬動 61 GB 的 weights 一次需要約 0.22 秒。GB10 上 122B NVFP4 的理論 decode 上限約 30 tok/s。要達到這個上限,每一層都需要高效的 kernel。當一半的架構(GDN)走 generic fallback,吞吐量往一半的上限平均——14 tok/s 就是這個平均的落點。
得到了什麼
結果是 14 tok/s,不是理論上限的 ~30 tok/s。但這個過程沒有白費。
確認了:
- 第一篇的 SM121 fix stack 對 Qwen3.5-122B 是有效的。輸出正確。
SupportsQuant是必須的——沒有它,GDN 層被量化,輸出垃圾。這個 bug 不直觀,從零開始診斷要花好幾個小時。- GB10 上 122B NVFP4 的理論 decode 上限是 ~30 tok/s。等 Marlin 加入 GDN kernel 後,這是要驗證的目標值。
確立了:
- 14 tok/s 是目前的下限,不是 bug。沒有任何設定錯誤。
- 瓶頸是軟體缺口(Marlin 缺少 GDN kernel),不是硬體限制。
- GB10 有足夠的算力跑 Qwen3.5-122B。問題完全在軟體堆疊。
診斷模式: 如果 Qwen3.5-122B 在 SM121 上跑很慢,你已經設了 VLLM_MXFP4_BACKEND=marlin 和 --moe-backend marlin,啟動 log 確認顯示 Using backend: marlin,輸出也正確——你碰到的就是 kernel 缺口。停止調整。等 kernel 來了數字才會動。
結論
套用第一篇的修法後,Qwen3.5-122B 在 DGX Spark 上正確運作。14 tok/s 不是故障——是目前 Marlin 所能支援的軟體上限。
現在如果需要在 GB10 上互動使用:gpt-oss-120B 59 tok/s 是可用的選項。Qwen3.5-122B 14 tok/s 適合離線批量任務,對延遲要求不高的場景。
如果你是因為 Qwen 跑很慢才找到這篇:你沒有漏掉任何 flag。你已經到達上限了。等 Marlin GDN kernel 來了再回來看。