DeepSeek-V4-Flash on DGX Spark · part 9
[DeepSeek-V4-Flash] 一句好奇,單台 DGX Spark 上白賺半代引擎升級——ds4 換 Entrpi
❯ cat --toc
TL;DR
我只是問 Codex 一句「這個 ds4 repo 有沒有針對單台 GX10 的強化」,結果一個下午,我那台在跑正職的 DGX Spark 就換了引擎(antirez/ds4 的 Blackwell fork,叫 Entrpi)。同一顆 abliterated 模型、什麼都沒換,decode 從 14-16 提到約 20、讀 prompt 快約一倍。沿路還實測收掉三個真問題:投機解碼在 abliterated 上為什麼反而更慢、disk-KV 是不是在省記憶體、managed KV 是不是 swap。
白話版:同一顆模型,換個「引擎」就變快
一個 AI 模型跑起來,分兩層:模型(它的腦,決定它多聰明)跟引擎(跑這顆腦的程式,決定它多快)。大部分人只想著換更大的模型,很少人去換引擎。
這篇是後者。我那台 DGX Spark(一台桌上型的 AI 小主機,單機 128GB 記憶體)本來跑著一顆叫 DeepSeek-V4-Flash 的大模型,速度就那樣。結果我只是隨口問 AI「有沒有人針對我這種單機做過優化」,挖到一個把同一顆模型跑快三成的引擎——模型一個字沒改,只換了跑它的程式。這篇講這趟怎麼換的、快多少,還有沿路我踩到、順手用實測收掉的三個坑。
前言
我在單台 DGX Spark 上養著一顆 ds4(就是 DeepSeek-V4-Flash,一顆會用工具、判斷力夠的大模型),當我整套 agent 的大腦。它跑在上游 antirez 那套引擎上,decode 大概每秒吐 14 到 16 個字,我一直當那就是這台的天花板。
某天我只是請 Codex 幫我查一句:「這個 ds4 的 repo,有沒有人針對『單台 GX10』做過什麼強化?」——純好奇,沒打算幹嘛。結果它翻出一個叫 Entrpi 的東西。
一個下午之後,我那台在跑正職的機器就換了引擎。這篇就是那個下午。
目標:單台 GX10 上,把手上在跑的 ds4 榨快一點
先講清楚我要什麼:不是換更聰明的模型,是同一顆模型跑快一點。而且有個硬性條件——我現在跑的是 huihui 那顆 abliterated(拿掉拒答限制的改版)的 ds4,這顆一定要留著,不能為了快就換回會拒答的標準版。
所以目標很窄:留住這顆 abliterated 模型,只把「跑它的程式」換成更快的,而且不能把我正在服務的 :8000 弄掛太久(它是我整套 agent 在用的)。
好處:留住 abliterated,還白賺半代升級
Entrpi 是 antirez/ds4 的一個 Blackwell CUDA 效能 fork——白話講就是「有人專門為 DGX Spark 這種 Blackwell 晶片,把 ds4 的底層重寫得更快」。重點來了:它變快靠的是引擎這一層,跟你載的是標準版還是 abliterated 版無關。

所以我不用取捨。我留住 abliterated 的 huihui、一個字沒改,只把 binary 換成 Entrpi。同一顆模型:
- decode:14-16 → 約 20 tok/s(兩次量到 20.0 / 20.8)
- prefill(讀 prompt):一個 5511 token 的長 prompt,722 tok/s——大概是舊引擎的兩倍。這塊對我的 agent 最有感,因為我的 system prompt 又臭又長,以前光讀進去就要等半天。
換個引擎、模型不動,就從 14-16 提到 20、讀 prompt 快一倍。這種好康不撿,GPU 都會替我難過。

怎麼達成:換 binary,難的不是換、是先讀懂它
換的動作本身很無聊:它有個一鍵安裝,clone、build、下載模型檔,然後把服務跑起來。真正花我時間的是兩件事。
第一件:先讀懂它是什麼,別信轉述。 Codex 說這是 v0.3.0;我去讀 repo 的 README,上面寫 v0.2.2,一度以為 Codex 亂講。結果我去讀實際會被執行的那個 install.sh,它 pin 的就是 v0.3.0——README 只是還沒更新。教訓:要驗版本、看的是會被跑的那個檔,不是給人讀的敘述檔。
第二件:在 production 上動手,得有安全網。 我這台 128GB 統一記憶體塞不下兩顆 80GB 的模型,所以沒辦法「新舊並行 A/B」——一定要先停掉正在跑的 :8000,才有記憶體載 Entrpi。而我在停之前,踩了兩個蠢雷:
- 一個是我的腳本用
ls *.gguf | head -1挑模型檔,結果挑到旁邊的 MTP 草稿檔、不是主模型; - 一個是我在 ssh 指令裡寫
$HOME,它在我本機展開成/Users/coolthor,不是機器上的/home/coolthor。
兩次都是「起不來」。但因為我腳本先做了一件事——動手前先把正在跑的那份完整啟動指令存下來,再殺;然後掛一個『出錯就自動把舊服務救回來』的 trap——所以兩次踩雷,我的 :8000 都在大概五分鐘內自己回來了,我完全沒手動救。
要動別人的、或自己正在用的 production,安全網是標配、不是可有可無。「先存後殺、出錯自還原」這個 trap 就救了我兩次。
debug 一:投機解碼在 abliterated 上,越用越慢
引擎換好、跑到 20 之後,我很自然想再貪一點:開投機解碼(speculative decoding)。這招是拿一顆小的「草稿模型」提前猜主模型接下來會吐什麼 token,主模型再並行驗證、接受猜對的——猜得準就快。Entrpi 支援兩種:MTP 跟 DSpark。
結果全敗。同一顆 huihui,實測:
| 設定 | decode tok/s | 每步接受幾個 token |
|---|---|---|
| 純引擎(關投機) | 約 20 | 1.0 |
| MTP 草稿深度 1 | 20.1(打平) | 1.62 |
| MTP 草稿深度 2 | 15.8(更慢) | 1.57 |
| MTP 草稿深度 3 | 17.1(更慢) | 1.61 |
| DSpark | 16.5(更慢) | 1.11 |

DSpark 每步只接受 1.11 個 token——幾乎每次草稿都被主模型拒絕。原因不難懂:現有的草稿模型全是配「標準」DeepSeek-V4-Flash 訓的,而我這顆是 abliterated、行為分布被改過了,草稿自然猜不準。draft 加 verify 的 overhead,反而把 20 拖到 16.5。MTP 也一樣,加大草稿深度只是讓每步做更多投機、但接受數沒跟著升,深度 2、3 都掉到純引擎以下。

說穿了:abliteration 讓模型的行為分布變了,剛好足以讓「配標準模型」的草稿猜不準。 想在 abliterated 上吃到投機加速,唯一的路是自己訓一顆配這顆模型的草稿——我認真查過,那要幾十 TB 的 teacher cache 加多卡訓練,還有個沒人寫過的格式轉換,為了那 30% 不划算。所以結論很乾脆:abliterated 模型,關掉投機、純引擎最快。
debug 二:disk-KV 不是省記憶體,managed 也不是 swap
搞定速度後,我想把 context 從 256K 推到 512K。這裡連踩兩個「以為是這樣、其實不是」。
以為 disk-KV 會省記憶體——其實它是拿來存 checkpoint、之後直接還原。 我搬引擎時漏了舊設定的 --kv-disk-dir。直覺上,「把 KV 放硬碟」聽起來就是把記憶體卸到硬碟、好塞下更大的 context。所以我把它加回來,再開 512K——結果 boot log 還是走 managed KV。實測證明:ds4 的 disk-KV 是把 KV 存成 checkpoint、之後直接還原(把長 prompt 的穩定開頭存硬碟,下次重送同樣的 prompt 87ms 還原、不用重算,對 agent 超有用),但它不會把當下在用的 KV offload 到硬碟來省記憶體。512K 的 KV 就是得塞進那 128GB。

以為 managed KV 是 swap——其實沒在 swap。 512K 的 KV 大概 11.3GB(256K 才 5.9GB),native 那條路第一次啟動直接 out of memory,ds4 自己退到 managed KV cache,boot log 還很誠實地寫「可能降速」。我當下也以為這就是在 swap。實測打臉:512K 跑起來,系統 swap 只用了 464Mi、ds4 的 process 被 swap 出去的只有 75MiB——根本沒在 swap。 managed KV 是 CUDA 的統一管理記憶體,讓驅動自動分頁、能超額配置;那句「降速」是分頁管理的 overhead,不是硬碟 swap。只有你真的把 512K 塞爆、超過實體,才會 spill 到 swap。

所以最後我留 512K:平常對話沒那麼長時,decode 一樣有 20、也完全沒在 swap;只有 context 真的塞得很滿,才可能開始碰到 managed memory 的限制。context 翻倍,平常幾乎沒感覺到成本。
收穫
最花時間的不是換引擎,是搞清楚「以為」跟「其實」的差距。 換 binary 十分鐘的事。真正吃時間的是三個「我以為」被實測一一打臉:以為投機能再加速(結果更慢)、以為 disk-KV 省記憶體(結果是存 checkpoint 還原)、以為 managed 是 swap(結果沒在 swap)。每一個都是「別猜、量一次就知道」。
這招在別的場景也用得上:分清「理論風險」跟「實際狀態」。 managed KV「可能 swap」是理論;實際量一下 swap 只用了 464Mi,就知道沒事。很多「聽起來很可怕」的降級警告,量完發現當下根本沒觸發。別被 log 的措辭嚇到,看實際數字。
通用原則一句話: 大家都盯著換更大的模型,但換引擎常常是白賺的半代升級——同一顆腦,換個跑得更快的身體,decode 提三成、prefill 翻倍,而且完全不用動你的模型。
收工前的四條 checklist
- 先看看有沒有人為你的硬體寫過 fork。 我這趟的起點只是問一句「有沒有針對單台 GX10 的強化」。引擎層的優化常常藏在小 repo 裡。
- 驗版本看會被執行的檔,不看敘述檔。 README 說 v0.2.2、install.sh pin v0.3.0,信 install.sh。
- 在 production 上換東西,先存啟動指令、掛自動還原的 trap。 我踩兩個雷都靠它自己救回,沒手動介入。
- 投機解碼先量接受狀況再決定開不開。 abliterated / 特殊 fine-tune 的模型,配標準草稿每步接受的 token 數可能很低,開了反而更慢。純引擎不見得輸。
這是「DeepSeek-V4-Flash on DGX Spark」系列的一篇。工具:Entrpi/ds4-on-spark、上游 antirez/ds4。
常見問題
- 換引擎不換模型,為什麼速度就變快?
- 因為變快的是引擎這一層,模型本身沒動。Entrpi 是 antirez/ds4 的 Blackwell CUDA 效能 fork,重寫了 prefill 的 tensor-core kernel、decode 的 CUDA graph、還有壓縮 KV。這些加速跟你載的是標準版還是 abliterated 版無關。所以我留住原本 abliterated(拿掉拒答的改版)的 huihui 模型、一個字都沒改,只是把 binary 換成 Entrpi,同一顆模型 decode 就從 14-16 提到約 20 tok/s、讀 prompt(prefill)快了約一倍。
- 投機解碼(speculative decoding)為什麼在 abliterated 模型上反而更慢?
- 投機解碼靠一顆小的『草稿模型』提前猜主模型接下來的 token,主模型再並行驗證、接受猜對的。問題是現有的草稿模型(DSpark drafter、MTP)都是配『標準』DeepSeek-V4-Flash 訓的;abliteration 把模型的行為分布改過了,草稿就猜不準。實測 DSpark 每步只接受 1.11 個 token(幾乎每次都被拒),draft 加 verify 的 overhead 反而把速度從 20 拖到 16.5。MTP 加大草稿深度也一樣,深度 2、3 都掉到純引擎以下。所以在 abliterated 模型上,純引擎、關掉投機才是最快的。
- disk-KV cache 是把記憶體卸到硬碟、讓大 context 塞得下嗎?
- 不是,這個我實測踩過。ds4 的 disk-KV 是把 KV 存成 checkpoint、之後直接還原——把長 prompt 的穩定開頭存到硬碟,下次重送同樣的 prompt 時 87ms 還原、不用重算,對 agent 場景很有用。但它不會把當下正在用的 KV offload 到硬碟來省記憶體。我把 disk-KV 加回來、再開 512K context,boot log 還是走 managed KV cache,證明它跟『塞不塞得下大 context』無關。
- 512K context 用的 managed KV cache 是 swap 嗎?
- 不是。managed KV 就是 CUDA 的 unified memory(cudaMallocManaged),讓 driver 自動做 paging、可以 overcommit,跟 swap 是兩回事。實測 512K 跑起來,系統 swap 只用了 464Mi、ds4 的 process 被 swap 出去的只有 75MiB,等於沒在 swap。那句『可能降速』來自 managed 記憶體的 paging overhead,不是 swap。只有你真的把 512K 塞爆、超過實體記憶體,才會 spill 到 swap。
接著讀
- 2026-07-09[本地 LLM] 我把 FlashMemory 重訓到自己的 Q2 build 上,它還是改善不了 V4-Flash 的 native lightning indexer
DeepSeek-V4-Flash 本來就有一套 native lightning indexer,追真實 attention 追到 93–96%。FlashMemory 會先把候選 chunk 篩小一圈,但直接拿來用跟亂猜沒兩樣;我重訓到自己的 Q2 build 上,也只爬到 89–92%。GB10 上 NO-GO。
- 2026-07-07[地端 LLM] 284B 塞得進 128GB、長 context 還跑得動:DeepSeek-V4-Flash 打的是 KV cache,不是參數量
DeepSeek-V4-Flash 是 284B 的 MoE,長 context 還能在 128GB 的 GB10 上跑得動,靠的不是權重小,是它天生就在打 KV cache:混合式 attention(SWA + CSA + HCA)把 KV 壓到 64K 只剩 871MiB;lightning indexer 挑的是壓過的 entry、一步只讀幾百列。這篇拆 ds4 的實作,順便講為什麼你沒辦法再靠量化 KV 省記憶體。
- 2026-07-06[本地 LLM] V4-Flash 的 depth-1 MTP:agent 回合 +9%、散文 −4%——推測解碼要看工作型態決定開不開
推測解碼常被當成免費加速,但在 bandwidth-bound 的 GB10 上,它其實是個會變負的取捨。depth-1 MTP 在 DeepSeek-V4-Flash 上無損,但看工作型態:agent 回合 +9.4%、程式碼 +6.5%,散文 −3.6%、中文閒聊 −3.7%。正負號跟著接受率走,因為這裡的吐字卡在驗證(108ms 驗證 vs 4ms 草稿)。不是全域開關,看工作型態開。
- 2026-07-05[本地 LLM] 養了一個月,我的 284B agent 悄悄不再快取——ds4 的 evict 風暴,跟每輪重付的 prefill
Part 2 誇的『快取命中就順』hot path,一個月重度 agent 用下來悄悄失效。ds4 的 disk-KV cache 在 GB10 上被兩件事餓死:預算填滿的 evict 風暴,加上 tool-call 那輪根本沒存 checkpoint。一段 14K token 的對話只認得 268 個字,剩下整段重 prefill。這篇拆 log 指紋、上游 PR #489、跟一張證明機制修好的 A/B 驗收。
不想錯過新文章?
訂閱我確保不漏接!
隨時一鍵退訂。