iT邦幫忙

2026 iThome 鐵人賽

DAY 3
1
AI Engineering

從 LLM 到 Harness: 打造隱私與可信任的繁中進階 OCR Agent系列 第 3

Day 3 - DGX Spark GB10:硬體限制怎麼反過來決定架構

  • 分享至 

  • xImage
  •  

昨天我們看到一顆 26B 的模型直接吃整頁文件會怎麼壞

今天要講的是另一半:就算你想用更大的模型去救它,你的硬體也不會答應

而且不是「跑不動」那種不答應

跑得動,但慢到你不想用那種不答應 😅


先看規格

項目 數字
晶片 GB10 Grace Blackwell Superchip
統一記憶體 128 GB LPDDR5X(CPU + GPU 共享)
記憶體頻寬 273 GB/s
AI 算力 最高 1 PFLOP(FP4,sparse)
CUDA capability 12.1(sm_121)
OS Ubuntu,arm64
上市 2025-10-15,US$3,999
現價 2026-02-23 調漲至 US$4,699(記憶體漲價)

💡Tip: 上面每一行我都標得出來源,但我要你只看其中一行。不是 128GB,不是 1 PFLOP。是 273 GB/s。這 30 天裡有一半的架構決策都是這個數字逼出來的。


為什麼是頻寬,不是容量?

先講一個我自己搞錯過的觀念

我剛拿到這台的時候,滿腦子都是「128GB 欸,那我是不是可以跑 70B 的模型」

可以。裝得下。

然後你會發現它慢到你懷疑人生

原因在 LLM 推論的 decode 階段——就是「一個字一個字吐出來」的那個階段——它是 memory-bound,不是 compute-bound

白話講:

每吐一個 token,GPU 都要把模型權重從記憶體搬到計算單元一次

算得多快不重要,因為它大部分時間都在等資料搬過來

所以單序列的生成速度,物理上限大約就是:

理論上限 tok/s ≈ 記憶體頻寬 ÷ 每個 token 需要讀取的權重量

這條式子很粗糙,但它抓的是對的東西

而我這台的分子是 273 GB/s

對照一下:

裝置 記憶體 頻寬
DGX Spark(GB10) 128GB LPDDR5X 273 GB/s
RTX 5090 32GB GDDR7 1,792 GB/s
H100 SXM5 80GB HBM3 3,350 GB/s

我的頻寬大概是 5090 的 1/6、H100 的 1/12。

關鍵差別在記憶體類型:GB10 用的是 LPDDR5X(就是手機/筆電那種低功耗記憶體),不是顯卡的 GDDR7、更不是資料中心的 HBM

這就是「128GB 統一記憶體」的代價。 你能用消費級的價格拿到 128GB,是因為它用的是便宜、省電、但慢的記憶體

(來源標註:H100 的 3.35TB/s 是 NVIDIA 官方規格頁逐字寫的;5090 的 1,792 GB/s 官方頁沒有直接列出 GB/s,是多個二手來源一致的數字,也跟 GDDR7 × 512-bit 的規格反推吻合)

128GB 買到的是「裝得下」,不是「跑得快」

我 vault 裡當時寫下的一句話是:

容量不缺,缺的是自己設的限制;真正的代價是速度(頻寬)不是容量。


實際算一次:我的 26B 模型能跑多快?

來把上面那條式子套進真實數字。這段值得你跟著算一遍,因為你換到自己的顯卡上也是同一套算法

我跑的是 gemma-4-26b,它是 MoE(Mixture of Experts) 架構:

  • 總參數 25.2B
  • 每個 token 實際活躍 3.8B(所以官方標記叫 26B-A4B)
  • 量化格式 NVFP4 → 每個參數約 0.5 byte

情境 A:如果它是 Dense 模型(每次都讀全部權重)

權重總量 = 25.2B × 0.5 byte = 12.6 GB
理論上限 = 273 GB/s ÷ 12.6 GB ≈ 21.7 tok/s

21.7 tok/s。

那是什麼概念?大概就是你盯著螢幕看它一個字一個字慢慢爬的速度

情境 B:MoE 只讀活躍參數

活躍權重 = 3.8B × 0.5 byte ≈ 1.9 GB
理論上限 = 273 GB/s ÷ 1.9 GB ≈ 143 tok/s

差了 6.6 倍

那實際呢?

我今天為了寫這篇,實際跑了 7 次量測(不同長度的輸出,取 completion tokens ÷ 端到端耗時):

測試 completion tokens 耗時 tok/s
短輸出 141 3.40s 41.5
中輸出 358 7.78s 46.0
中輸出 387 8.11s 47.7
長輸出 459 9.52s 48.2
長輸出 710 14.53s 48.9
長輸出 737 15.18s 48.5
超長輸出 1464 30.15s 48.6

穩定落在 48.5 tok/s 左右(短輸出那次偏低是因為 prefill 跟網路往返還沒被攤薄掉,輸出越長越收斂)

把三個數字放在一起看:

tok/s
情境 A:Dense 假設(讀全部權重)的理論上限 21.7
實測 48.5
情境 B:MoE 只讀活躍權重的理論上限 143

實測是 Dense 上限的 2.2 倍 → MoE 的稀疏讀取確實有效,它真的沒在讀全部權重

但實測只有 MoE 上限的 34% → 中間有一大段損耗

那 66% 去哪了?attention 層是 dense 的(每個 token 都要全讀)、KV cache 要來回搬、MoE 的 router 每步都要算、kernel 效率本身也不是 100%。我沒有拆到那麼細,這裡只能說「式子給你的是天花板,不是預期值」

💡Tip: 這條式子的正確用法是算天花板。如果你算出來 143,實測 48,那還有調校空間;但如果你算出來 21,那就不用調了,換架構或換量化才是唯一的路。這就是昨天講的「調參救不回來」的量化版本。

一個我自己踩到的誠實時刻

我原本這篇是要寫「實測 150 tok/s,跟理論 143 幾乎貼合,完美驗證」的

因為我的舊筆記裡確實記著「decode 速度正常,約 150 tok/s」

然後我今天重測,只有 48.5。

差了三倍

那筆舊記錄我已經沒辦法還原它當時的條件了——而且更糟的是,那則筆記的主機型號本身我就記錯過一次(寫成 5090,後來 2026-08-04 驗證才發現那台其實就是 GB10)

所以我選擇:以今天實測為準,舊數字不引用。

💡Tip: 這件事的教訓比那個數字重要——你自己的舊筆記也是二手資料。尤其是那種「順手記一下」的效能觀察值,沒有記錄當時的量化格式、context 長度、batch 大小、有沒有其他服務在搶記憶體,事後就沒有任何解釋力了。Day 26 講記錄設計的時候,我會回來講這一刀該怎麼記才不會白記。


所以,這個限制決定了什麼?

這才是今天的重點。我把這台機器逼我做的決定整理成一張表

硬體限制 逼出來的架構決策
頻寬 273 GB/s 是硬瓶頸 單序列速度撞物理上限,調參救不回來,只剩量化跟推測解碼兩條路(Day 4、Day 5)
Dense 模型在這台上太慢 優先選 MoE 架構,或接受 Dense 模型只用在慢速但精準的區塊(Day 9、Day 10)
CPU/GPU 共享同一塊記憶體 多個推論服務會互相排擠,實務做法是「一次只起一個」
統一記憶體沒有獨立 VRAM 概念 不要用 --kv-cache-memory-bytes 自設容量上限,那是自己給自己設瓶頸
sm_121 太新 PyTorch 會對 sm_121 噴 warning,套件相容性要逐個試
arm64 架構 很多預編譯的 wheel 沒有 arm64 版,得自己編或找對的 image

那個 --kv-cache-memory-bytes 的坑

這條我特別想講,因為它是**「用 x86 顯卡的直覺去操作統一記憶體」**的典型錯誤

我一開始寫了 --kv-cache-memory-bytes 3G,想說先限制一下免得吃太多

然後算一下就發現不對勁:

KV cache ≈ 79 KB / token(fp8)
64K context 的單一 request = 65536 × 79 KiB ≈ 4.9 GiB

我設 3G,連一個 64K 的 request 都裝不下。

💡Tip: 那個 79 KB / token 本身是換算估算值(跟層數、head 數、KV dtype 都有關),所以這篇跟後面幾天所有 KV cache 的數字,請當量級看,不要當精確值。我統一用 GiB(1024 進位)算,因為記憶體慣例是這樣。差個 3–5% 不影響「裝不裝得下」的判斷,但差一個數量級就會。

這行的正確做法是整行刪掉,讓 gpu-memory-utilization 自己去分配

💡Tip: 順便講一個更常見的誤解——--gpu-memory-utilization總預算(weights + activations + KV cache + CUDA graph 全部算在內),不是「只給 KV cache 的比例」。方向搞反的話你會一直往錯的方向調。

記憶體分配失敗那次

還有一次更蠢的。我設 --gpu-memory-utilization 0.3,想說 128GB 的 30% 也有 36GB 應該夠了吧

啟動直接失敗

  • 0.3 × 121.63 GiB = 要 36.49 GiB
  • 實際只剩 28.4 GiB(另一個容器佔走了)

因為是統一記憶體,別的服務吃掉的量會直接從你的預算裡扣。x86 上你有獨立 VRAM,這事不會這樣發生

後來的保守值:降到 0.18–0.20,或如果確定整台機器只跑這一個服務,設 0.5–0.7


Context 長度:那個我被官方規格騙到的地方

Gemma 4 的 config.json 裡寫 max_position_embeddings: 32768

原生 context 就是 32K。

但我的文件情境要跑到 64K 以上(一份年報章節動輒好幾萬 token)

解法是開 YaRN rope scaling:

rope_scaling:
  rope_type: yarn
  factor: 2.0

32K × 2.0 = 64K

而我今天去問了一下現在線上這個服務實際吃到多少:

curl -s http://10.0.0.220:8004/v1/models -o models.response.json
curl -s http://10.0.0.220:8004/version  -o version.response.json
// models.response.json(節錄)
{
  "id": "gemma-4-26b",
  "root": "/models/gemma4",
  "max_model_len": 131072
}
// version.response.json
{ "version": "0.19.1.dev6+g6d4a8e6d2" }

131072,也就是 128K。

比我筆記裡寫的 64K 又多了一倍——顯然我後來又調過一次但沒回去更新筆記 😅(同上一節的教訓,我的筆記也是二手資料)

順便你也看到我跑的是 vLLM 0.19.1.dev6dev 版。這件事 Day 4 講版本衝突的時候會解釋為什麼

💡Tip: 注意我這兩行 curl 都加了 -o 把回應存成檔案,沒有只讓它印在終端上。這是我自己吃過虧才養成的習慣——寫文章、寫報告的時候,「我記得我查過」跟「這是回應存檔」是兩件完全不同的事。這篇稿子在校對階段,就有一段因為只跑在終端裡沒落檔,被判定成「無法核實」打回來重做。跑過的每個測試都留檔,成本幾乎是零,省下的是之後的爭論。

💡Tip: 這裡有個實務提醒——max_model_len 開得大不代表你該用得滿。KV cache 是按實際 context 長度吃記憶體的,128K 的單一 request 光 KV cache 就要 將近 10 GiB(按前面 79 KB/token 換算)。開大是為了不被擋住,不是為了每次都塞滿。

順便講一個真的發生過的低級錯誤:我有一次 max_model_len 多打了幾個零,寫成 131072000

服務當然起不來

但更糟的是它的錯誤訊息不會告訴你「你多打了零」,它會噴一串記憶體相關的錯,讓你往完全錯誤的方向查


環境安裝清單

我的實際環境,給你對照用:

項目
主機 gx10@10.0.0.220
GPU NVIDIA GB10(不是 5090,我的舊筆記記錯過一次,Day 5 會講這個教訓)
推論框架 vLLM
服務埠 8004(gemma-4-26b
模型格式 NVFP4(ModelOpt export)
Python 環境 native venv,不是 NGC container

為什麼不用 NGC container?

因為版本打架:

  • vLLM 把 transformers 鎖在 <5
  • Gemma 4 需要 transformers >= 5.5.0

在容器裡處理這個衝突比自己開 venv 還麻煩,所以我直接走 native venv

💡Tip: 如果你看到這裡想說「那我用 Ollama 不就好了」——我試過。這台上 host 層的 Ollama 跑 gemma4:26b 會 crash(journalctl 顯示 llama runner segfault,exit status 2),疑似跟 vLLM container 同時佔用 unified memory 有關。這也是統一記憶體的副作用之一。


小結:限制不是壞事

我知道這篇通篇都在講「不能」

但我想講的其實是反過來的事

如果我有一台 8 卡 H100,我根本不會想做這 30 天要做的東西。

我會直接丟一顆最大的模型上去,一次吃整頁,跑得又快又準,然後這系列就沒什麼好寫的了

正是因為 273 GB/s 這個數字擋在那邊,我才被迫去想:

  • 哪些區塊真的需要大模型?(Day 10)
  • 能不能讓小模型先做、大模型只做難的?(Day 18 的 Region Routing)
  • 驗證能不能用便宜的方式做?(Day 22 的四重驗證)

這些問題的答案,最後就長成了 Harness。

架構不是設計出來的,是被限制逼出來的

明天我們就從第一個「被逼出來的選擇」開始:量化


上一篇
Day 2 - 單一模型 baseline:Gemma 4 直接跑整頁會怎樣
下一篇
Day 4 - vLLM 部署與量化格式選擇
系列文
從 LLM 到 Harness: 打造隱私與可信任的繁中進階 OCR Agent5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
justin_log
iT邦新手 5 級 ‧ 2026-09-17 13:32:58

期待明天的量化!!

我要留言

立即登入留言