改裝 2080 Ti 22G · part 9
[趣味競賽 進階 #9] 我想幫 2080 Ti 降壓省電,結果發現 decode 根本不在乎瓦數
❯ cat --toc
TL;DR
我本來想幫這張 22G 改裝 2080 Ti 降壓,讓常駐 agent 腦更安靜。結果 decode 時的狀態很清楚:記憶體時脈死頂、核心沒頂滿、溫度約 50°C。這代表它卡在 ~616 GB/s 記憶體頻寬,不是卡在瓦數。誠實講:那次降壓沒有生效,所以不是 220W vs 280W paired 實測。實務結論:別拿功耗追 decode token;先看頻寬,還有真正影響體感的 TTFT/快取。
白話版:我想省電,結果卡告訴我瓦數從來不是瓶頸
把這張改裝 2080 Ti 掛上去當 24 小時 agent 腦之後(#1),我清單上第一件事就是降壓。邏輯看起來理所當然:一張全天候開著的卡,降壓能壓低功耗跟發熱,而 Turing 卡降壓通常幾乎不付速度代價。免費的安靜、免費的省電。
於是我去查到底要犧牲多少速度。結果答案是:幾乎沒有——但理由跟我想的不一樣。理由是,對這張卡一整天主要在做的那件事來說,瓦數從一開始就不是那根旋鈕。
這是短篇,重點就一句話、值得記著:decode 是 bandwidth-bound。 一旦這句話內化了,一整串 GPU 調校的直覺——降壓會掉速、超核心會加速、拉功耗上限換更多 token——就會安安靜靜地全部重新排列。
⚠️ 誠實的部分,先講在最前面: 我很想宣稱「我降壓到 220W,測出來沒變慢」。我不能。等我回頭去看,卡是在 250W default 跑的——我以為自己設好的降壓根本沒生效。 所以我沒有一組乾淨的 220W vs 280W decode paired 對照。我有的,是這張卡在負載下到底在做什麼的現場畫面,而這個畫面已經足夠拿來推理瓶頸卡在哪。每一個「這是推理、不是量測」的地方,我都會當場標出來。
我一開始的直覺(以及它為什麼在這裡是錯的)
大部分人心裡那套 GPU 的常民模型大概是:功耗越高 → 時脈越高 → 每秒做的事越多。降壓就鎖住時脈,所以變慢;超頻、拉高功耗上限,就變快。對很多 GPU 負載——遊戲、算圖、訓練——這大致成立,因為那些是 compute-bound:晶片的算術單元才是瓶頸,所以餵它更多功耗跟時脈,真的能換到吞吐。
LLM 的 decode 不是這種負載。
模型生成文字的時候,是一個 token 一個 token 產出的,而每吐一個 token,它都得把整套作用中的權重從 VRAM 讀出來、乘過一遍、吐出一個 token。然後下一個 token 再來一次。每個 token 的算術量很小,每個 token 要搬的資料量卻很大。所以卡住你的不是核心算得多快,而是權重從記憶體搬出來能多快。 那就是記憶體頻寬。被這樣卡住的負載叫 bandwidth-bound,再多核心時脈、再多瓦數都加不了速,因為核心早就坐在那邊等記憶體了。
decode 的時候,這張卡其實在做什麼
真正翻轉我直覺的是這個:我盯著模型生成時的現場 GPU 狀態,它看起來完全不像一張在硬撐功耗的卡,而像一張在等記憶體的卡。
- 功耗上限是 active 的——卡確實被頂在上限——但核心(SM)時脈在 1665–1845MHz 之間亂跳,離天花板還遠。核心沒頂滿這件事,單獨不能證明 bandwidth-bound(一張被功耗封頂的卡,也可能因為別的原因落在 boost 天花板底下)——但配上下面兩個訊號,就對得起來了。
[memory] - 記憶體時脈死頂在 ~6800MHz
[memory]——基本上吃滿了,頂在這張卡額定的記憶體時脈天花板 7000MHz 邊上[live]。記憶體子系統已經盡力,核心卻沒有。 - 晶片只有 47–52 度。涼。離過熱牆遠得很——這代表我降壓純粹是為了安靜/省電,不是為了讓卡別降頻。
[memory]
三個湊起來,故事自己就寫好了:記憶體是瓶頸、核心不是、晶片連熱都還沒熱起來。 這就是 bandwidth-bound 負載的標準長相。
我把出處講清楚,因為這篇誠實這件事很要緊。本次現場驗到的([live]):250W default、100–280W 的功耗上下限、額定記憶體時脈天花板 7000MHz,以及下面那張閒置快照。來自 [memory] 的(前一次調校 session、寫這篇時沒重測):負載下的核心/記憶體時脈——包括那個 ~6800MHz——跟 47–52 度。我沒為這篇重抓負載下的時脈,因為我不想為了重截一個數字,就硬塞一堆 inference 去操那顆還在服役的腦。
一個我可以現場驗的東西
我至少能確認功耗設定就是誠實聲明講的那樣。直接問卡:
$ nvidia-smi --query-gpu=name,power.limit,power.default_limit,power.min_limit,power.max_limit,clocks.max.memory --format=csv
NVIDIA GeForce RTX 2080 Ti, 250.00 W, 250.00 W, 100.00 W, 280.00 W, 7000 MHz
所以:功耗上限是 250W,而這也正是 default——證明我以為設好的降壓沒生效。 可調範圍是 100–280W,額定記憶體時脈上限是 7000MHz(我負載下看到的 ~6800 就頂在它旁邊)。[live] 這是閒置時的快照;我不是宣稱這是負載下重抓的時脈,只是功耗的框架跟上下限。
為什麼 decode 不動,但 prefill 可能有救
如果 decode 是 bandwidth-bound,那加功耗到底哪裡幫得上忙?prefill——模型在吐出第一個 token 之前,先把你整段 prompt 一口氣讀進去的那一段。
prefill 是另一種形狀的運算。它不是一次一個 token,而是把一整批 token 平行處理,這會讓算術單元真的忙起來。所以 prefill 是 compute-bound(至少遠比 decode 偏算力)。原則上,加功耗、拉高核心時脈,可以幫 prefill 削掉一點時間。[memory]
但洩氣的點在這:prefill 也正是在這顆 hybrid 腦上,一旦 cache miss 就得把整段 prompt 從頭重算的那一段——而在 45–50K token 的時候,那是兩百秒的等待,任何實際的時脈微調都碰不到(#5 整篇就在講這個)。真正能撥動 prefill 的旋鈕是快取行為,不是瓦數。所以就算在這唯一一段功耗可能有意義的地方,它跟快取問題比起來也只是個零頭。
結論:整個負載裡,沒有任何一段是「拉高功耗上限」這根旋鈕該出手的地方。
第二個徵兆:decode 速度根本不理會 context 長度
「bandwidth-bound」還有一個乾淨、獨立的佐證,就躺在前一篇的資料裡,而且完全不用盯時脈。
如果 decode 是 compute-bound,你會預期 context 越長就越慢——KV cache 裡 token 越多、每一步要算的注意力就越多。但實際不是這樣。在我量到的整個範圍裡,不管 context 是 4K 還是 110K,decode 都守在 ~32 tok/s。 [memory]
這正是 bandwidth-bound 過程的指紋:每個 token 的成本是被「搬權重」主宰的——那是固定的一份資料,跟你對話多長無關——所以吞吐隨 context 變長還是平的。(講精確點:讀 KV cache 的量確實會隨 context 長,所以不是字面上的「固定工作量」;只是在這張卡、這個範圍裡,搬權重那一項把它壓過去了,曲線才看起來平。)prefill 那段偏算力,剛好相反——它的吞吐隨 prompt 變長而往下掉,從 4K 的 ~624 tok/s 掉到 110K 的 ~360 tok/s。[memory] 兩段、兩種完全不同的縮放行為——而 decode 那段是平的,這就是頻寬的簽名。
所以我有兩個獨立的徵兆指向同一個結論——現場的時脈/溫度長相,跟那條平的 decode-vs-context 曲線——而它們一致。兩個都不是 paired 功耗實驗,但合起來就讓「bandwidth-bound」這個讀法很難反駁。
這對調這種卡的意義
一旦你接受 decode 是 bandwidth-bound,實務建議自己就掉出來了:
- 降壓應該幾乎免費。 如果核心在 decode 時本來就在天花板底下閒晃、晶片才 50 度,那只要調低之後記憶體時脈還是頂在天花板附近,把功耗上限調低對你最常跑的那段負載就幾乎沒代價——安靜跟省電你拿到了,卻不必用 token 去換。我還欠自己一組真正的 paired 測試來證明代價是零(見前面那條誠實標);每個指標都指向可以忽略,但我確實還沒測過。
- 別拿瓦數去追 token。 把功耗上限拉到 280W 不會讓 decode 變快,因為記憶體時脈早就死頂了。你只是在付一堆用不到的熱。
- 真想要 decode 更快,唯一真正的旋鈕是頻寬本身——一張 GB/s 更高的卡。這張 2080 Ti 的改裝翻倍的是 VRAM 容量(11→22GB),但頻寬沒動,還是 ~616 GB/s(#1)。塞 context、塞更大的模型的空間變多了——但 decode 的天花板沒變。容量跟頻寬是兩條不同的軸,而這次改裝只動了其中一條。
- 真正決定 agent 體感的那個數字根本不是時脈——是 TTFT,是 prefill 的快取行為(#5)。瓦數跟它比起來只是配角。
結算
我進去的時候,是想降壓省電、心裡準備好要掉一點速度。卡自己的行為告訴我:幾乎沒什麼好掉的。decode 是 bandwidth-bound,卡在權重從 VRAM 搬出來的速度,而生成時核心本來就在天花板底下滑行、記憶體時脈死頂、晶片還涼著。加瓦數不會幫忙;減瓦數也不太會痛。
把這篇的邊界講白: 我那次降壓其實沒生效(卡一直頂在 250W),所以我沒辦法給你一組乾淨的 220W vs 280W decode paired 對照——那還在待辦清單上。我能給你的,是從時脈跟溫度的讀數、加上那條平的 decode-vs-context 曲線看出來的瓶頸形狀,而兩者講的是同一件事。所以放心去幫你那張全天候的卡降壓求安靜跟省電;只是別指望瓦數是那根「讓 token 吐更快」的旋鈕。在一個 bandwidth-bound 的負載上,那根旋鈕幾乎沒接到任何東西。
同系列其他篇:
常見問題
- 幫 2080 Ti 降壓會不會讓 LLM 的 decode 變慢?
- 幾乎不會——但我得先說清楚,這是推理、不是量測。decode(一個字一個字吐)是 bandwidth-bound:每吐一個 token,都得把整套權重從 VRAM 搬一遍,所以瓶頸是記憶體頻寬(這張卡 ~616 GB/s),不是算力。decode 的時候核心時脈本來就在天花板底下亂跳、功耗上限也已經 active——晶片不是缺瓦數,是在等記憶體。所以只要把上限調低之後,記憶體時脈還是頂在它的天花板附近,decode 就幾乎不該動。誠實標:這件事我其實沒測過——我那次降壓根本沒生效,卡從頭到尾都在 250W default 跑,所以沒有一組 paired 的前後對照可以指。
- 把功耗上限拉高,本地模型會吐得更快嗎?
- 對 decode 來說,幾乎不會。如果記憶體時脈已經死頂(我這張 decode 時 ~6800MHz,而額定上限是 7000MHz),頻寬就吃滿了,加功耗只是讓核心時脈再往上爬一點點、卻沒地方花。prefill 才是 compute-bound 的那一段——它一次嚼一整段 prompt——所以加功耗對它可能有點用。但你每天真正感覺到的數字,是被 prefill 的快取行為(TTFT)主宰的,不是 decode 的瓦數。
- 怎麼判斷我的 GPU decode 是不是 bandwidth-bound?
- 兩個徵兆。第一個在模型生成時用 nvidia-smi 看得到:記憶體時脈頂在最高、而核心(SM)時脈在天花板底下亂跳。第二個要看你的 benchmark / server log:不管 context 是 4K 還是 100K,decode 的 tok/s 幾乎不變——每個 token 的成本被「搬權重」(固定的一份資料)主宰,所以吞吐隨 context 變長還是平的。我這張 2080 Ti 兩個都中。compute-bound 的負載會偏向相反:核心時脈頂得高、而且對功耗更敏感。
接著讀
- 2026-07-09[趣味競賽 進階 #10] 0xc0000409:當我的 AI 服務靜默暴斃,而 log 把死因吃掉了
一台 headless Windows AI 主機上的本地腦,偶發在真實負載下無聲無息地死掉:client 吃到短暫 503,服務自己又活回來,應用程式 log 一片空白。最氣的是真兇不是模型本身,是我自己——重啟前 log 把 crash 當下那行死因截掉了。這篇是把死因從『被自己的 log 掩埋』裡挖出來的偵察故事:為什麼會自我重啟的服務最會掩埋自己的死因、為什麼要先看 OS 層的 Event Log、以及 0xc0000409 到底是什麼。誠實在先:根因我還沒 100% 確認,這是還在查的紀錄,不是結案報告。
- 2026-07-03[趣味競賽 進階 #8] 為什麼 30 tok/s 體感比 14 還慢:TTFT 才是你真正感覺到的速度
我把家裡那顆 agent 腦的 decode 從別台的 14 tok/s 換成這台 30,結果它感覺更慢。tok/s 這個數字我盯了一年,原來它量的是「吐字多快」,不是「多久才開始吐」。在一顆 hybrid 模型上,一次 cache miss 就把整段 prompt 從頭重算——同一台機、同一顆腦,暖機 2.6 秒、冷掉 216 秒。這篇用 Hina 自己的 log 講:為什麼該盯的是 TTFT。
- 2026-07-02[趣味競賽 進階 #7] 在慢腦上開漸進式串流,我把自己撞進了 Telegram 的 flood control
我想讓慢吞吞的本地 agent 少一點等待焦慮,於是開了 Telegram 的「逐字浮現」串流——每隔幾百毫秒就改寫一次訊息。結果一個一百多秒的回應發出上百次編輯請求,正面撞進 Telegram 的 flood control,被罰等兩百多秒,整個 bot 卡死,連最終答案都送不出去。這篇講一個短而毒的教訓:慢模型不該開漸進式串流,一次性送最終答案反而穩。附 log 實證。
- 2026-06-27[趣味競賽 進階 #6] 工具定義稅:還沒開口,就先吃掉 17K token——而且每次重算都重來一遍
我數了一下家裡那個 AI 助理每次回話前的開銷:還沒開始處理我輸入的文字,就先吃掉約 23K token,其中 17K 只是『工具的使用說明書』。更慘的是它是 hybrid 模型,快取一沒命中就把這 17K 從頭重算——一個對話回合可能重算十幾次。這篇講一個被嚴重低估的成本:模型開口前的「打底開銷」。解法不是砍工具,是像技能那樣『用到才載』。
不想錯過新文章?
訂閱我確保不漏接!
隨時一鍵退訂。