DeepInfer Field Notes 獨立 / 粉絲製作
筆記 / 生產缺口

DeepInfer 的生產缺口:KV Cache、PD 與負載平衡

DeepInfer 交付的是堆疊中負責算出 token 的那部分,針對 DeepSeek V4.1-Flash。一門服務生意還需要負責記憶、路由與平衡的那部分。本篇細看三個缺口——以及它們為何比看起來更難。

深入分析/12 分鐘閱讀/README + Q&A

DeepInfer 是 DeepSeek 的 V4.1-Flash 推理引擎,不是完整的服務堆疊。README 的「不包含」清單很短:KV cache 系統、VE/Prefill/Decode 分離,以及資料平行副本之間的負載平衡。每一項都是子系統,不是一個功能開關。三者合起來,就是「跑一個模型」與「跑一個服務」的差別。

引擎 vs 服務

引擎接收一批已分詞的請求,回傳生成的 token。服務接收來自眾多使用者的 HTTP 請求,驗證身分、路由、維持上下文溫熱、執行配額、處理故障,還要計費。引擎是昂貴的運算;服務是昂貴的營運。

DeepInfer 是引擎。DeepSeek 的 Q&A 異常詳細地描述了圍繞它的服務,讓缺口一目了然。以下走過最大的三塊。

KV cache:讓長上下文付得起的記憶體

模型讀取 prompt 時,會為每個 token、每一層存下 key 與 value。這個快取讓 decode 不必重讀整段 prompt 就能生成下一個 token。跨請求重用 prefix,是服務中最大的成本槓桿之一:冗長的系統提示、共用文件或多輪 agent 歷史,可以算一次、用很多次。

樸素版本——在 GPU 記憶體裡放一個字典——在大規模下會崩潰。GPU 記憶體相對於需求太小,某個快取項目可能需要由另一台機器取用,而運算節點比儲存節點更常故障。DeepSeek 的生產設計分成三層:

層級存放什麼媒介生命週期 / 策略
執行中作用中的 block KV + state KVGPU HBM請求存續期間
SWA 池作用中 session 的滑動視窗 KV主機 DRAM(每台機器 10%)數分鐘;TTL 約 180 秒
持久 block KV供重用的 prefix 快取專用 3FS 叢集agent 流量 3 天、chatbot 流量 7 天

生產數字大到足以改變你對這個問題的想法:

  • 約 100 PiB 的 SSD 用於 KV cache。
  • 每張 GPU 約 14.4 TB 邏輯 KV;實體容量更大。
  • 每 8 張 GPU 約 400 Gbps 互連。
  • 3FS 採 10+2 erasure coding;每個 EC 群組可容忍兩個節點同時故障。
  • 峰值總讀取約 10 TiB/s;寫入約 850 GiB/s。

為何用專用儲存叢集,而不是本機記憶體或分層快取?Q&A 給了三個理由:

  1. 任何 prefill 機器都能命中任何 prefix。 若快取在本機,路由就得做 prefix 親和,這與負載平衡衝突。
  2. 儲存與運算可獨立擴充。 你可以只加快取容量而不加 GPU,反之亦然。
  3. 運算故障不會丟失快取。 依 DeepSeek 說法,運算節點的故障頻率比儲存節點高一個數量級。

一次快取命中分三個階段:比對、取回、換入。只有比對在關鍵路徑上;從 3FS 取回到主機共享記憶體,是在另一個行程中非同步進行;從共享記憶體換入 HBM,則與前向運算逐層重疊。DeepSeek 用 GDR/RDMA 做換入,因為 CUDA 複製引擎對細粒度的 KV block 複製效率不佳。

若要自己打造這套東西,你需要 prefix 比對、metadata 服務、分散式儲存、淘汰/TTL、跨機器傳輸、容錯,以及一套能與負載平衡配合的路由策略。這是一個儲存團隊的工作量,不是週末項目。

不在本次發佈中

3FS 設計、100 PiB 這個數字,以及 3/7 天 TTL,描述的都是 DeepSeek 的生產系統。DeepInfer 本次發佈不包含 KV cache 系統。沒有它你仍可跑離線推理;但只靠這個儲存庫,無法重現生產環境的快取行為。

Prefill/decode 分離:兩種工作負載,兩個資源池

Prefill 與 decode 的瓶頸不同。Prefill 受運算限制:它一次處理大量 prompt token,受益於大型矩陣乘法。Decode 受記憶體頻寬限制:每一步為每個請求生成一個 token,並讀取 KV cache。把它們放在同一個資源池,會在硬件、平行策略與批次大小上處處妥協。

分離把它們拆成各自的資源池:

  • Prefill 資源池:8-GPU 機器,EP2–8 / DP2–8,依非快取 token 數調整規模。
  • Decode 資源池:64–128 GPU 超級節點,EP64–128 / DP64–128(Wide-EP),依執行中請求數調整規模。
  • 視覺編碼器:每個實例一張 GPU,通常用較便宜的卡。
  • 儲存:專用 KV cache 節點,與運算分開。

DeepSeek 說 P:D 比例約為 1:1,並把 64 張 prefill 加 64 張 decode GPU 稱為最小的有效單位。1P + 1D 的配置可以部署,但建議的 decode 配置是 EP64 以上。

難處在交接。請求進來、完成 prefill、產生 KV cache,然後必須被路由到能看到這份快取的 decode 引擎。這需要傳輸路徑、一份快取所在位置的目錄,以及同時考量快取位置與 decode 負載的路由決策。DeepSeek 為每 8 張 GPU 編列約 400 Gbps 互連,並指出 P 與 D 可以位於相鄰的資料中心,但要付出一些可靠性代價。

本次發佈針對分離說「多數必要的引擎功能已實作」,但完整方案並未包含。若你想要生產環境的形態,編排層得由你來建。

負載平衡:兩個維度,四個平衡器

DeepSeek 描述了四個平衡器:prefill、decode、視覺編碼器與專家平行。

Prefill 負載平衡器

請求依總上下文長度分成四級:<16K、16–64K、64–256K、≥256K。分配給各級的引擎數量,依上一輪的運算配額需求重新分配。在 DP 群組內,每個請求送往當前配額負載最低的 rank。在單張 GPU 內,請求以 FIFO 出列,chunk 大小則用擬合的二次成本模型、依時間預算求解。

這比輪詢精細得多,因為 prefill 成本對請求數並非線性;單一個 256K token 的 prompt 就可能主導一整批短請求。

Decode 負載平衡器

Decode 路由平衡兩個維度:請求數(決定每步批次大小)與 KV cache 總長度(決定注意力成本)。其啟發式做法是把短請求送往併發低但 KV 長度大的 GPU,把長請求送往 KV 長度小的 GPU。目標是讓批次與注意力工作量都保持平衡。

專家平行負載平衡器

EPLB 加入冗餘專家,並依近期負載定期把專家重新指派到 GPU。DeepSeek 回報 decode 的 moe_lb 約 1.090——最慢的 rank 比平均多做了約 9% 的工作。prefill 的數字在英文 Q&A 與中文文章之間略有差異,但機制相同。

80% 的現實檢驗

Q&A 裡最有用的一句話或許是:生產環境的負載平衡大約達到完美平衡的離線 benchmark 的 80%。

這意味著,即使是擁有自訂平衡器、完全掌控整個堆疊的 DeepSeek,也只達到離線 benchmark 吞吐量的約 80%。把簡單路由器接上 DeepInfer 的團隊,不該期待更好的結果。這也意味著離線 Pareto 圖是上限:它們是在受控環境下量測的,不是在生產路由偏斜之下。

這不是批評,而是校準:分散式服務本來就混亂,而最後那 20% 正是大量工程所在。

自建 vs 採用

若你需要一個能服務的 API,大致有三條路:

路徑你得到什麼你要自己負責什麼
採用成熟的服務框架(vLLM、SGLang、TensorRT-LLM)API 層、batching、快取、廣泛的模型支援對 DeepSeek 專屬調校的控制較少;請確認 V4.1-Flash 支援
在 DeepInfer 上自建DeepSeek 的 kernel 與排程KV cache、PD 分離、負載平衡、API、驗證、計費、可觀測性
等 DeepSeek 開放更多可能更完整的堆疊時程不確定;Q&A 沒有給日期

對多數團隊來說,第一條路最務實。DeepInfer 適合有硬件、有工作負載、也有工程能量自己扛服務層的團隊——或者想了解 DeepSeek 怎麼做的工程師。

一句話說完缺口

DeepInfer 開放了引擎;服務仍是一個自建項目。這次發佈之所以有價值,正因為它讓這個區別看得見,而不是藏在一個 demo 後面。

回到限制頁,或讀引擎如何運作。

↑