一、背景
本著求真務(wù)實的態(tài)度,我們這里詳細(xì)介紹一下 DeepSeek V3 技術(shù)報告中的關(guān)鍵技術(shù),也補充了一些細(xì)節(jié);考慮到已經(jīng)很多文章提到 DeepSeek V3 的各種評估指標(biāo),我們這里就不再贅述,聚焦在模型結(jié)構(gòu)和 Infra 建設(shè)兩個部分。
對應(yīng)的論文為:[2412.19437] DeepSeek-V3 Technical Report [1]
對應(yīng)的代碼庫為:GitHub - deepseek-ai/DeepSeek-V3 [2]
DeepSeek-V3 是一個 MoE(Mixture-of-Experts)語言模型,總參數(shù)量 671B,每個 Token 激活的參數(shù)量為 37B。為實現(xiàn)高效訓(xùn)練與推理,DeepSeek-V3 延續(xù)了 DeepSeek-V2 的 MLA(Multi-head Latent Attention)及 DeepSeekMoE 架構(gòu)。此外,DeepSeek-V3 首創(chuàng)了無需輔助損失的負(fù)載均衡策略,還使用了多 Token 預(yù)測訓(xùn)練目標(biāo)以增強性能。
作者在 14.8T 高質(zhì)量 Token 上對 DeepSeek-V3 進行預(yù)訓(xùn)練,隨后通過監(jiān)督微調(diào)與強化學(xué)習(xí)階段充分挖掘其潛力。全面評估顯示,DeepSeek-V3 超越了其他開源模型,性能與領(lǐng)先的閉源模型相當(dāng)。盡管表現(xiàn)出色,DeepSeek-V3 的完整訓(xùn)練僅需 2.788M H800 GPU 小時,且訓(xùn)練過程異常穩(wěn)定,整個過程沒有遭遇不可恢復(fù)的 Loss Spike 或進行任何回滾操作。
如下圖 Figure 2 所示,DeepSeek-V3 的模型結(jié)構(gòu)與 DeepSeek-V2 一致,依然是 MLA + DeepSeekMoE,總參數(shù) 671B,激活參數(shù) 37B??偣?61 層,Hidden 維度為 7168:
MLA:
Attention Head 個數(shù) nh:128
每個 Head 的維度 dh:128(需要說明的是,非 MLA 時,一般 nh * dh = Hidden 維度;而 MLA 中并不是這樣,dh 會大于 Hidden 維度 / nh,比如這里 128 > 7168/128 = 56)
KV 壓縮維度 dc:512
Q 壓縮維度 d’c:1536
解耦的 Q 和 K(RoPE)的維度 dRh:64
MoE:
前 3 層 Transformer Layer 的 FFN 保持為 Dense 結(jié)構(gòu)(1 個專家),后續(xù) Layer 的 FFN 替換為 MoE 結(jié)構(gòu)。
MoE 中包含 1 個共享專家(Share Expert)和 256 個路由專家(Routed Expert),每個專家的 Hidden 維度為 2048。每個 Token 激活 8 個路由專家,并且確保每個 Token 最多被發(fā)送到 4 個節(jié)點。
MTP:
MTP 的深度 D 為 1,也就是除了精確預(yù)測下一個 Token 外,每個 Token 還額外預(yù)測一個 Token。
如下圖公式 1-11 列出了 MLA 中的關(guān)鍵公式,我們在這里標(biāo)注了相應(yīng)的 Shape 信息,以便與上圖中相對應(yīng):
如上圖可知,對于每一個 Token,推理時在每一個 Transformer Layer 需要需要緩存的 Cache 為藍(lán)色的兩個方塊,大小為 512+64=576。而標(biāo)準(zhǔn) MHA 需要緩存的大小為 2 * Hidden 維度 ,即 2*7168=14336,也就是 DeepSeek V3 的 MLA 的 Cache 大小只有 MHA 的 1/25。
具體來說,作者采用了 DeepSeek AI 論文 [2408.15664] Auxiliary-Loss-Free Load Balancing Strategy for Mixture-of-Experts [3] 中的負(fù)載均衡策略,具體來說,其通過動態(tài)更新每個專家的偏置(b)來維持專家的負(fù)載均衡,而不會引入額外的干擾梯度。如下圖公式 16 和 Figure 1 所示:
盡管 DeepSeek-V3 主要依賴于無輔助損失的策略來實現(xiàn)負(fù)載平衡,但為了防止在任何單一序列中出現(xiàn)極端的不平衡,作者采用了一種補充的序列級均衡損失:
其中,α 為平衡因子超參數(shù),T 表示序列中 Token 個數(shù),Nr 表示專家個數(shù),Topk 表示選擇分?jǐn)?shù)最大的 Kr 個專家,
實際上,Pi 可以理解為每個專家在所有 Token 上的平均分?jǐn)?shù),fi 表示第 i 個專家在整個序列中的“被選中”頻率,用來衡量它的負(fù)載相對于其他專家的分布情況。這種序列級均衡損失的目的是鼓勵每個序列中的專家負(fù)載更加均衡,避免負(fù)載集中在少數(shù)專家上,從而提高模型的效率和公平性。
與 DeepSeek-V2 所采用的設(shè)備約束路由類似,DeepSeek-V3 同樣使用了一種約束路由機制以控制訓(xùn)練過程中的通信開銷。簡而言之,作者確保每個 Token 最多被發(fā)送至 M 個節(jié)點,這些節(jié)點的選擇依據(jù)是分布在各節(jié)點上的專家中,其親和度得分最高的 Kr/M 項之和。在此約束下,MoE 訓(xùn)練框架幾乎能夠?qū)崿F(xiàn)計算與通信的完全重疊。
得益于高效的負(fù)載均衡策略,DeepSeek-V3 在整個訓(xùn)練過程中保持了良好的負(fù)載平衡。因此,DeepSeek-V3 在訓(xùn)練期間未丟棄任何 Token。此外,作者還實施了特定的部署策略以確保推理過程中的負(fù)載均衡,故 DeepSeek-V3 在推理階段同樣不會丟棄 Token。
受 Meta 的 [2404.19737] Better & Faster Large Language Models via Multi-token Prediction [4](如下圖所示,我們之前也介紹過)的啟發(fā),作者在 DeepSeek V3 中使用了多 Token 預(yù)測(Multi Token Predicton,MTP)目標(biāo),該目標(biāo)將預(yù)測范圍擴展到每個位置上的多個未來 Token。有兩個好處:
增強了訓(xùn)練信號的密度,可能提升數(shù)據(jù)利用效率。
或許能使模型預(yù)先規(guī)劃其表征,以便更好地預(yù)測未來 Token。
如下圖 Figure 3 展示了 MTP 的具體實現(xiàn)。與上圖 Meta 論文中采用獨立輸出 Head 并行預(yù)測 D 個額外 Token 不同,作者采用順序預(yù)測額外 Token 的方式,并在每一預(yù)測深度保持完整的因果鏈。
其中的 Main Model 就是標(biāo)準(zhǔn)的 Next Token Prediction。
MTP Module 1 用于預(yù)測下下一個 Token,MTP Module 2 用于預(yù)測下下下一個 Token(與 LLM 推理中常見的多頭投機采樣思路一致)。
MTP Module 中的輸入都包含兩個部分,一個是上一個 Module 的 Output Head 的輸入,以及上一個輸入 Token,并且其中的 Embedding Layer 和 Output Head 都是共享自 Main Model,只有新增的 RMSNorm + Linear Projection 和一個 Transformer Block。由于這里有兩個輸入分別經(jīng)過 RMSNorm 后 Concat 到一起,因此需要一個額外的 Linear Projection 進行降維,保持維度一致。
MTP 策略主要用于提升 Main Model 的性能,因此在推理階段,可以直接舍棄 MTP Module,Main Model 仍能獨立且正常運行。此外,還可將這些 MTP Module 用于投機解碼,以進一步降低生成延遲。
DeepSeek V3 在包含 2048 H800 GPU 的集群上訓(xùn)練,每個節(jié)點包含 8 個 H800 GPU,并使用 NVLink + NVSwitch 實現(xiàn)全互聯(lián)(需要說明的是,H800 的 NVLink 帶寬為 400 GB/s,而 H100 的 NVLink 帶寬為 900 GB/s,這也是 H800 與 H100 的主要區(qū)別)。此外,節(jié)點間通過 IB 網(wǎng)絡(luò)實現(xiàn)互聯(lián)。
PS:作者在后文中提到其 NVLink 提供了 160 GB/s 的通信帶寬,大約是 IB(50 GB/s)的 3.2x。其 160 GB/s 與實際的 400 GB/s(雙向)不符,推測這里是單向?qū)崪y帶寬。如下圖所示,我們在 8*H100 GPU 上實測單向的 device to device Memory 帶寬,大約為 900 GB/s * 80% / 2 = 360 GB/s。而 160 GB/s 為 400 GB/s * 80% /2 = 160 GB/s。
而 IB(50 GB/s)可以理解為理論或?qū)嶋H NIC 帶寬,H100/H800 上后向網(wǎng)絡(luò)通常都會采用 400 Gb/s 的 NIC。如下圖所示(使用 ib_write_bw 和 ib_read_bw 測試),當(dāng) Message 比較大時,發(fā)送或者接收實測帶寬最大都能達到 400 Gb/s,雙向總帶寬可以達到 800 Gb/s(這一點與 NVLink 口徑不同)。另外,也可以推測每個節(jié)點包含 8 個 400 Gb/s 的 NIC。
DeepSeek V3 使用自研的 HAI-LLM 框架訓(xùn)練(在幻方 AI 的技術(shù)博客有介紹:HAI-LLM:高效且輕量的大模型訓(xùn)練工具 [5]),其相應(yīng)的分布式策略為:16 PP(Pipelining Parallelism),64 EP(Expert Parallelism)以及 ZeRO-1 DP(Data Parallelism)。此外,64 EP 分布在 8 個節(jié)點上。
為了高效訓(xùn)練,作者實施了精細(xì)的工程優(yōu)化:
設(shè)計了 DualPipe 算法以實現(xiàn)高效的流水線并行。與現(xiàn)有 PP 方法相比,DualPipe 具有更少的 PP Bubble。更重要的是,它在 Forward 和 Backward 過程中 Overlap 了計算與通信,從而解決了跨節(jié)點 EP 引入的高通信開銷問題。
開發(fā)了高效的跨節(jié)點 All2All 通信 Kernel,以充分利用 IB 和 NVLink 帶寬,并節(jié)省專用于通信的 SM。
精心優(yōu)化了訓(xùn)練過程中的內(nèi)存開銷,從而能夠在無需使用昂貴的 TP(Tensor Parallelism)的情況下訓(xùn)練 DeepSeek-V3。
對于 DeepSeek V3 而言,跨節(jié)點 EP 引入的通信開銷導(dǎo)致計算與通信比約為 1:1,效率很低。為了應(yīng)對這一挑戰(zhàn),作者設(shè)計了一種創(chuàng)新的流水線并行算法 DualPipe。
DualPipe 的核心思想在于將一對獨立的 Forward 與 Backward Chunk 內(nèi)的計算與通信進行 Overlap。具體而言,將每個 Chunk 劃分為四個組件:Attention、All2All Dispatching、MLP 及 All2All Combining。
其中的 All2All Dispatching 和 All2All Combining 如下所示,就是 MoE Block 之前和之后的兩個 All2All 通信:
特別地,對于 Backward Chunk,作者借鑒了 ZeroBubble([2401.10241] Zero Bubble Pipeline Parallelism [6]),如下圖 Figure 1 所示,Attention 與 MLP 均可進一步分為兩部分:Backward for Input 及 Backward for Weight。此外,還有一個 PP 通信組件。
如下圖 Figure 4 所示,針對一對 Forward 與 Backward Chunk,重新排列這些組件,并手動調(diào)整 GPU SM 在通信與計算間的分配比例。在此 Overlap 策略下,能夠確保 All2All 和 PP 通信在執(zhí)行過程中完全隱藏,其中:
橙色表示 Forward
綠色表示 Backward for Input
藍(lán)色表示 Backward for Weight
紫色表示 PP 通信
紅色表示 Barrier 同步
完整的 DualPipe 調(diào)度如下圖 Figure 5 所示,其采用雙向 PP 調(diào)度,同時從流水線兩端輸入 Micro Batch,使得大部分通信得以完全 Overlap(PS:8PP,雙向 20 Micro Batch,反方向 10-19 的 10 個 Micro Batch 并沒有列出來,因此我們用紅色 10-19 補充了部分 Micro Batch)。這種 Overlap 還確保了隨著模型進一步擴展,只要保持恒定的計算與通信比,仍可在跨節(jié)點部署細(xì)粒度專家的同時,實現(xiàn)近乎零的 All2All 通信開銷。
PS:正常來說是無法實現(xiàn)雙向 PP 調(diào)度的,主要是因為 Forward 執(zhí)行順序是從前往后,比如從 Layer 0,1,2,...,14,15,而 Backward 執(zhí)行順序是從后往前,比如 Layer 15,14,...,2,1,0。而常見 PP 中的 Layer 只會在某一個 PP Stage,比如 8 PP,那么:
Stage 0 上有 Layer 0 和 1 的權(quán)重
Stage 1 上有 Layer 2 和 3 權(quán)重
Stage 7 上有 Layer 14 和 15 的權(quán)重
Forward 的順序也只能從 Stage 0 到 Stage 7,不能從 Stage 7 到 Stage 0。
而 DeepSeek V3 的雙向 PP 調(diào)度中,還是 8 PP 為例:
Stage 0 上有 Layer 0, 1 以及 Layer 14, 15 的權(quán)重
Stage 1 上有 Layer 2, 3 以及 Layer 12, 13 的權(quán)重
Stage 7 上有 Layer 14, 15 以及 Layer 0, 1 的權(quán)重
相當(dāng)于有 2 份相同的模型副本,Forward 的順序可以從 Stage 0 到 7,也可以從 Stage 7 到 0。
此外,即便在通信負(fù)擔(dān)不重的更一般場景下,DualPipe 仍展現(xiàn)出效率優(yōu)勢。如下圖 Table 2 所示,作者總結(jié)了不同 PP 方案下的 PP Bubble 與內(nèi)存使用情況。與 ZB1P 相比,DualPipe 在減少 PP Bubble 及優(yōu)化內(nèi)存占用方面表現(xiàn)更佳。其中的 Parameter x2 是正如上述所示,存儲了 2 份相同的模型參數(shù),也就需要占用更大的內(nèi)存(激活的占用也會稍微增加),相當(dāng)于用空間換時間;然而,因為作者訓(xùn)練時采用了比較大的 EP,整體來說并不會增加太多內(nèi)存占用。此外,DualPipe 僅要求 PP Stage 和 Micro Batch 可被 2 整除,無需 Micro Batch 可被 PP Stage 數(shù)整除。
PS:對于一個內(nèi)部框架(HAI-LLM)而言,完全可以針對自己的硬件環(huán)境(集群)以及模型場景(MLA + MoE)制定專有化的優(yōu)化方案,比如手動調(diào)整 SM 在計算和通信中的比例,從而獲得比開源方案更優(yōu)的性能。
為了確保 DualPipe 具有足夠的計算性能,作者定制了高效的跨節(jié)點 All2All 通信 Kernel(包括 Dispatching 和 Combining),以節(jié)省專用于通信的 SM 數(shù)量。Kernel 的實現(xiàn)與 MoE Gating 算法及集群的網(wǎng)絡(luò)拓?fù)涔餐O(shè)計。
具體來說,在作者的集群中,跨節(jié)點 GPU 與 IB 完全互連,節(jié)點內(nèi)通信通過 NVLink 處理。NVLink 提供 160 GB/s 帶寬,大約是 IB(50 GB/s)的 3.2x。
為了有效利用 IB 和 NVLink 的不同帶寬,作者將每個 Token 限制為最多被發(fā)送到 4 個節(jié)點,從而減少 IB 流量。
對于每個 Token,在做出路由決策時,首先通過 IB 傳輸?shù)狡淠繕?biāo)節(jié)點上具有相同節(jié)點內(nèi)索引的 GPU。一旦到達目標(biāo)節(jié)點,將努力確保它通過 NVLink 立即轉(zhuǎn)發(fā)到承載目標(biāo)專家的特定 GPU,而不會被隨后到達的 Token 阻塞。(PS:比如說,節(jié)點 A 上 GPU 0 的 Token 要發(fā)送到節(jié)點 B 上的 GPU 3,則對應(yīng)的路徑為:節(jié)點 A GPU 0 -> 節(jié)點 B GPU 0 -> 節(jié)點 B GPU 3。這樣做是因為高性能 GPU 訓(xùn)練集群往往會采用軌道優(yōu)化,同號 GPU 在一個 Leaf Switch 下,如下圖所示,因此可以利用高速的 NVLink 來代替從 Leaf Switch 到 Spine Switch 的流量,從而降低 IB 通信時延,并且減少 Leaf Switch 和 Spine Switch 之間的流量)
通過上述方式,IB 和 NVLink 的通信也可以完全 Overlap,每個 Token 可以有效地為每個節(jié)點平均選擇 3.2 個專家,而不會產(chǎn)生 NVLink 的額外開銷。這意味著,盡管 DeepSeek V3 在實踐中只選擇了 8 個路由專家,但它可以將這個數(shù)字擴展到最多 13 個專家(4 個節(jié)點 × 3.2 個專家/節(jié)點),同時保持相同的通信成本??偟膩碚f,在這樣的通信策略下,只用 20 個 SM 足以充分利用 IB 和 NVLink 的帶寬。
具體而言,作者采用了 warp specialization 技術(shù),并將 20 個 SM 劃分為 10 個通信通道。
在 All2All Dispatching 過程中,(1)InfiniBand(IB)發(fā)送、(2)IB 至 NVLink 轉(zhuǎn)發(fā),以及(3)NVLink接收分別由相應(yīng)的 warp 處理。分配給每項通信任務(wù)的 warp 數(shù)量會根據(jù)所有 SM 的實際工作負(fù)載進行動態(tài)調(diào)整。
同樣,在 All2All Combining 過程中,(1)NVLink 發(fā)送、(2)NVLink 至 IB 轉(zhuǎn)發(fā)與累加,以及(3)IB 接收與累加也由動態(tài)調(diào)整的 warp 負(fù)責(zé)處理。
此外,Dispatching 與 Combining Kernel 均與計算流 Overlap 執(zhí)行,因此作者也考慮了它們對其他 SM 計算 Kernel 的影響。特別地,作者使用定制化的 PTX 指令,自動調(diào)整通信 Chunk 大小,從而顯著減少 L2 Cache 的使用量及對其他 SM 的干擾。
為降低訓(xùn)練過程中的內(nèi)存占用,作者采用了以下技術(shù)手段。
RMSNorm 與 MLA 上投影重計算。在 Backward 階段,對所有 RMSNorm 操作及 MLA 上投影進行重計算,從而無需持久化存儲其輸出激活值。此策略雖引入少量額外計算開銷,卻顯著減少了存儲激活值所需的內(nèi)存空間。
CPU 中的指數(shù)移動平均(EMA)。訓(xùn)練期間,為了在學(xué)習(xí)率衰減后盡早評估模型性能,作者保留了模型參數(shù)的 EMA。這些 EMA 參數(shù)存儲于 CPU 內(nèi)存中,并在每一步訓(xùn)練后異步更新。該方法使作者能在不增加額外內(nèi)存或時間開銷的前提下維護 EMA 參數(shù)。
MTP 的共享 Embedding 與輸出 Head。采用 DualPipe 策略,作者將模型的最淺層(含 Embedding)與最深層(含輸出 Head)部署于同一 PP Stage 上。這種安排使得 MTP Module 與 Main Model 之間能夠物理共享 Embedding 與輸出 Head 的參數(shù)及梯度。這一物理共享機制進一步提升了內(nèi)存使用效率(PS:也就是 Huggingface Transformers 中的 tie_word_embeddings)。
NVIDIA 和零一萬物等都介紹過在 Hopper GPU 上使用 FP8 訓(xùn)練來提升訓(xùn)練速度的方案(我們在之前的文章中也有詳細(xì)的介紹)。受此啟發(fā),作者也在訓(xùn)練 DeepSeek V3 的過程中采用了 FP8 的細(xì)粒度混合精度訓(xùn)練。
作者通過與兩種不同規(guī)?;€模型的 BF16 訓(xùn)練進行對比,驗證了提出的 FP8 混合精度框架的有效性。
在小規(guī)模實驗中,訓(xùn)練了一個包含約 16B 總參數(shù)的基線 MoE 模型,使用約 1.33T Token。
在大規(guī)模實驗中,訓(xùn)練了一個包含約 230B 總參數(shù)的基線 MoE 模型,使用約 0.9T Token。
如下圖 Figure 10 展示了其訓(xùn)練曲線,證明采用高精度累加和細(xì)粒度量化策略后,相對誤差始終保持在 0.25% 以下。
作者的 FP8 混合精度訓(xùn)練框架中,大多數(shù)計算密集型操作以 FP8 執(zhí)行,而少數(shù)關(guān)鍵操作則保留其原始數(shù)據(jù)格式,以平衡訓(xùn)練效率與數(shù)值穩(wěn)定性。整體框架如下圖 Figure 6 所示。
首先,為加速模型訓(xùn)練,關(guān)鍵計算 Kernel(比如,GEMM 操作)大多采用 FP8 精度實現(xiàn)。這些 GEMM 操作接受 FP8 Tensor 作為輸入,并輸出 BF16 或 FP32 格式的結(jié)果。如下圖 Figure 6 所示,與線性算子相關(guān)的三個 GEMM 操作,包括 Forward(Fprop)、激活 Backward(Dgrad)和權(quán)重 Backward(Wgrad),均以 FP8 執(zhí)行。這一設(shè)計理論上使計算速度較原 BF16 方法提升一倍。此外,FP8 Wgrad GEMM 允許激活值以 FP8 存儲,供 Backward 使用,從而顯著降低內(nèi)存消耗。
盡管 FP8 格式具有效率優(yōu)勢,但某些算子因?qū)Φ途扔嬎惚容^敏感仍需更高精度。同時,一些低成本算子也可采用更高精度,對整體訓(xùn)練性能的影響微乎其微。因此,作者對以下組件保持原始精度(如 BF16 或 FP32):Embedding Module、輸出 Head、MoE 門控模塊、歸一化算子及 Attention 算子。這些有針對性的高精度保留確保了 DeepSeek-V3 的訓(xùn)練動態(tài)穩(wěn)定性。為進一步保證數(shù)值穩(wěn)定性,作者將主權(quán)重、權(quán)重梯度和優(yōu)化器狀態(tài)以更高精度存儲。盡管這些高精度組件帶來一定的內(nèi)存開銷,但通過分布式訓(xùn)練系統(tǒng)中跨多個 DP Rank 的有效分片,其影響很小。
作者還引入了若干策略以提升低精度訓(xùn)練的準(zhǔn)確性,重點在于量化方法與乘法過程的優(yōu)化。
細(xì)粒度量化。由于 FP8 格式動態(tài)范圍有限,上溢和下溢是常見的挑戰(zhàn)。標(biāo)準(zhǔn)做法是 Per Tensor 量化,會導(dǎo)致低精度訓(xùn)練對激活異常值極為敏感,嚴(yán)重降低量化精度。為解決此問題,作者提出了一種細(xì)粒度量化方法。如下圖 7a 所示:
對于激活值,以 1x128 的 Tile 為單位(比如,每 Token 每 128 Channel)進行分組與縮放;
對于權(quán)重,以 128x128 的 Block 為單位(即,每 128 輸入 Channel 每 128 輸出 Channel)進行分組與縮放。
此方法通過更小的元素組調(diào)整縮放比例,確保量化過程能更好地適應(yīng)異常值。
該方法的關(guān)鍵改進是在 GEMM 操作中引入按組縮放因子。不過,這一功能在標(biāo)準(zhǔn)的 FP8 GEMM 中并未直接支持。然而,結(jié)合精確的 FP32 累加策略,它可以被高效實現(xiàn)。值得注意的是,這里的細(xì)粒度量化策略與 Microscaling Format([2310.10537] Microscaling Data Formats for Deep Learning [7])的理念高度一致,而 NVIDIA 下一代 GPU(Blackwell 系列)的 Tensor Core 已宣布支持具有更小量化粒度的 Microscaling Format。
提升累加精度。低精度的 GEMM 操作常面臨下溢問題,其準(zhǔn)確性很大程度上依賴于高精度的累加,通常采用 FP32 進行。然而,作者觀察到,在 NVIDIA H800 GPU 上,FP8 GEMM 的累加精度僅能保留約 14 位,遠(yuǎn)低于 FP32 的累加精度。當(dāng)內(nèi)部維度 K 較大時,這一問題更加突出,這在大規(guī)模模型訓(xùn)練中尤為常見。以 K=4096 的兩個隨機矩陣的 GEMM 操作為例,在作者的初步測試中,Tensor Core 受限的累加精度導(dǎo)致最大相對誤差接近 2 %。盡管如此,有限的累加精度仍是部分 FP8 框架的默認(rèn)選項,嚴(yán)重制約了訓(xùn)練精度。
為解決此問題,作者采用了 Cutlass(GitHub - NVIDIA/cutlass: CUDA Templates for Linear Algebra Subroutines [8])中的方案,借助 CUDA Core 以獲取更高精度。具體來說,該過程如上圖 7b 所示,在 Tensor Core 上執(zhí)行 MMA,中間結(jié)果以有限位寬累加。一旦達到 Nc 間隔,這些中間結(jié)果將被復(fù)制到 CUDA Core 的 FP32 寄存器中,進行全精度的 FP32 累加。然后可以結(jié)合前面的細(xì)粒度量化,沿內(nèi)部維度 K 應(yīng)用每組的縮放因子。這些縮放因子在 CUDA Core 上高效地作為反量化過程進行乘法運算,額外計算成本極低。
值得注意的是,這一修改會降低單個 WGMMA(Warpgroup Level 矩陣乘加)指令發(fā)射率。但在 H800 架構(gòu)上,通常兩個 WGMMA 會同時存在:當(dāng)一個 Warpgroup 執(zhí)行 promotion 操作時,另一個可執(zhí)行 MMA 操作。此設(shè)計實現(xiàn)了兩個操作的 Overlap 執(zhí)行,確保了 Tensor Core 的高利用率。根據(jù)實驗數(shù)據(jù),設(shè)定 Nc 為 128 個元素,相當(dāng)于 4 次 WGMMA 操作構(gòu)成最小累加間隔,這一設(shè)置能在不引入顯著開銷的前提下顯著提升計算精度。
尾數(shù)優(yōu)先于指數(shù)。與先前研究采用的混合 FP8 格式不同,該格式在前向傳播中使用 E4M3(4 位指數(shù)和 3 位尾數(shù)),在數(shù)據(jù)梯度和權(quán)重梯度中使用 E5M2(5 位指數(shù)和 2 位尾數(shù)),作者則對所有 Tensor 采用 E4M3 格式以追求更高精度。此方法可行主要是使用了細(xì)粒度的量化策略,通過對更小的元素組進行操作,可以有效地在這些分組元素間共享指數(shù)位,從而緩解了有限動態(tài)范圍的影響。
在線量化。常見的 Tensor level 量化框架中采用 Delayed Scaling,通過保留先前迭代中的 amax(最大絕對值)history 來推斷當(dāng)前值。為了確保量化 Scale 準(zhǔn)確并簡化框架,作者在線計算每個 1x128 激活 Tile 或 128x128 權(quán)重 Block 的 amax,基于此推導(dǎo)出 scaling 因子,隨后在線將激活或權(quán)重量化為 FP8 格式。
如下圖為 NVIDIA Transformer Engine 中的 Delayed Scaling 實現(xiàn)方案,其 amax history 最多可以存儲 1024 個 history。在進行當(dāng)前 Tensor 的 Scaling 操作時,會使用當(dāng)前 Tensor 之前的 amax history 來預(yù)測當(dāng)前的 amax(比如之前 history 的最大值),然后進行 Scaling 操作;Scaling 操作的同時會計算當(dāng)前的 amax,并更新 amax history。
作者還通過將緩存的激活值和優(yōu)化器狀態(tài)壓縮為低精度格式,進一步減少內(nèi)存消耗和通信開銷。
低精度優(yōu)化器狀態(tài)。采用 BF16 而非 FP32 來存儲 AdamW 優(yōu)化器中的一階矩和二階矩,而不會引起可觀察到的性能下降。然而,主權(quán)重(由優(yōu)化器存儲)和梯度仍使用 FP32 存儲,以確保整個訓(xùn)練過程中的數(shù)值穩(wěn)定性。
低精度激活。如上圖 Figure 6 所示,Wgrad 操作使用 FP8 執(zhí)行。為了減少內(nèi)存消耗,作者將激活值以 FP8 格式緩存用于線性算子的 Backward。不過,對于低成本高精度訓(xùn)練,會對幾個算子特殊處理:
Attention 算子后的線性算子輸入。這些激活值也用于 Attention 算子的 Backward,其對精度比較敏感。作者專門為這些激活值定制了 E5M6 數(shù)據(jù)格式。此外,在 Backward 過程中,這些激活值將從 1x128 量化 Tile 轉(zhuǎn)換為 128x1 Tile。為了避免引入額外的量化誤差,所有縮放因子均為四舍五入的 2 的整數(shù)冪。
MoE 中 SwiGLU 算子的輸入。為了進一步降低內(nèi)存成本,作者緩存了 SwiGLU 算子的輸入,并在 Backward 時重新計算其輸出。這些激活值也以 FP8 格式存儲,采用細(xì)粒度量化方法,可以在內(nèi)存效率和計算精度之間取得平衡。
低精度通信。在 MoE 模型訓(xùn)練中,通信帶寬是一個關(guān)鍵瓶頸。為緩解這一挑戰(zhàn),作者在 MoE 上投影前將激活量化為 FP8,隨后應(yīng)用 Dispatching,這與 MoE 上投影中的 FP8 Forward 兼容。如同 Attention 算子后線性層的輸入,此激活的縮放因子為 2 的整數(shù)冪,類似策略也應(yīng)用于 MoE 下投影前的激活梯度。對于 Forward 和 Backward 的 Combining,保持其 BF16 格式,以確保訓(xùn)練流程關(guān)鍵部分的訓(xùn)練精度。
作者在 H800 集群上部署 DeepSeek-V3,其中每個節(jié)點內(nèi)的 GPU 通過 NVLink 互連,而集群中的所有 GPU 則通過 IB 實現(xiàn)全互聯(lián)。為了同時確保在線服務(wù)的 SLO 和高吞吐量,作者采用了以下部署策略,該策略將 Prefill 階段和 Decoding 階段分離。
Prefill 階段的最小部署單元由 4 個節(jié)點組成,共 32 個 H800 GPU。
Attention 部分采用 4 TP 結(jié)合 SP(Sequence Parallelism),并與 8 DP 相結(jié)合。其較小的 TP 規(guī)模(4)限制了 TP 通信的開銷。
MoE 部分采用 32 EP,確保每個專家處理足夠大的 Batch Size,從而提升計算效率。
在 MoE 的 All2All 通信中,采用與訓(xùn)練階段相同的方法:首先通過 IB 在節(jié)點間傳輸 Token,然后通過 NVLink 在節(jié)點內(nèi)的 GPU 間轉(zhuǎn)發(fā)。特別地,對于淺層密集 MLP,采用 1TP 以節(jié)省 TP 通信開銷。
為了實現(xiàn) MoE 部分不同專家間的負(fù)載均衡,需確保每個 GPU 處理大致相同數(shù)量的 Token。作者引入了一種冗余專家部署策略,即對高負(fù)載專家進行復(fù)制并冗余部署。高負(fù)載專家基于在線部署期間收集的統(tǒng)計數(shù)據(jù)檢測并定期調(diào)整(如每 10 分鐘一次)。確定冗余專家集合后,根據(jù)觀察到的負(fù)載情況,在節(jié)點內(nèi)的 GPU 間精心重新安排專家,力求在不增加跨節(jié)點 All2All 通信開銷的前提下,盡可能平衡各 GPU 的負(fù)載。對于 DeepSeek-V3 的部署,作者為 Prefill 階段設(shè)置了 32 個冗余專家。每個 GPU 除了原本承載的 8 個專家外(256/32),還將額外承載一個冗余專家。
此外,在 Prefill 階段,為了提高吞吐量并隱藏 All2All 和 TP 通信的開銷,作者同時處理兩個計算工作量相近的 Micro Batch,將一個 Micro Batch 的 Attention 和 MoE 計算與另一個 Micro Batch的 Dispatching 和 Combining Overlap 執(zhí)行。
最后,作者還在探索一種動態(tài)專家冗余策略,其中每個 GPU 承載更多專家(例如,16 個專家,每次推理步驟僅激活 9 個。在每層 All2All 操作啟動前,實時計算全局最優(yōu)路由方案。鑒于 Prrefill 階段涉及大量計算,計算此路由方案的開銷幾乎可忽略不計。
在 Decoding 過程中,將共享專家視為路由專家之一。由此視角出發(fā),每個 Token 在路由時會選擇 9 個專家,其中共享專家被視為高負(fù)載專家,始終被選中。Decoding 階段的最小部署單元由 40 個節(jié)點組成,共 320 H800 GPU。
Attention 部分采用 4 TP 結(jié)合 SP,并與 80 DP 協(xié)同工作,而 MoE 部分則采用 320 EP。
MoE 部分,每個 GPU 僅承載一位專家,其中 64 個 GPU 負(fù)責(zé)承載冗余專家及共享專家。Dispatching 與 Combining 部分的 All2All 通信通過 IB Direct P2P 傳輸實現(xiàn),以實現(xiàn)低延遲。此外,還利用 IBGDA 技術(shù)進一步降低延遲,提升通信效率。
與 Prefill 階段類似,基于在線服務(wù)的專家負(fù)載統(tǒng)計數(shù)據(jù),在特定間隔內(nèi)定期確定冗余專家集合。然而,由于每個 GPU 僅承載一位專家,因此無需重新安排專家。作者也在探索 Decoding 階段的動態(tài)冗余策略,但這需要對計算全局最優(yōu)路由方案的算法進行更為精細(xì)的優(yōu)化,并與 Dispatching Kernel 融合以減少開銷。
此外,為提升吞吐量并掩蓋 All2All 通信的開銷,作者還在探索 Decoding 階段同時處理兩個計算負(fù)載相近的 Micro Batch。與 Prefill 階段不同,Attention 機制在 Decoding 階段占據(jù)更大比例的時間消耗。因此,將一個 Micro Batch 的 Attention 計算與另一個 Micro Batch 的 Dispatching + 專家混合 + Combining Overlap。在 Decoding 階段,每位專家處理的 Batch 規(guī)模相對較小(通常不超過 256 個 Token),此時瓶頸在于內(nèi)存訪問而非計算本身。鑒于專家混合部分僅需加載單一專家的參數(shù),內(nèi)存訪問開銷極低,故減少 SM 的使用不會顯著影響整體性能。因此,為避免對 Attention 部分的計算速度造成影響,作者僅需為 Dispatching + 專家混合 + Combining 分配少量 SM 資源。
DeepSeek V3 的訓(xùn)練成本很低,如下圖 Table 1 所示,總共訓(xùn)練 2788K H800 小時,按照每個 H800 每小時 2 美元的成本,總成本大約為 560 萬美元。
然而我們也看到很多文章中聲稱 “DeepSeek 把訓(xùn)練成本打下來 99%”,如下圖所示,其聲稱 “LLaMA-3.1 的訓(xùn)練成本超過 5 億美元”,Meta 真的這么拉胯嗎?
如下圖為 LLaMA 3.1 的訓(xùn)練成本(來自 meta-llama/Llama-3.1-8B · Hugging Face [9]),以 LLaMA 3.1 405B 為主,其總共的訓(xùn)練成本為 30.84M H100 GPU 小時:
H800 相比 H100 主要是閹割了 NVLink 的通信帶寬,整體成本并不會相差太大,比如 Pricing | Lepton AI [10] 每個 H100 每小時 3 美元。自建集群或者大規(guī)模租賃通常會低于這個數(shù)值,假設(shè)為 2.5 美元,那么 LLaMA 3.1 405B 的訓(xùn)練成本應(yīng)該為 30.84M * 2.5 = 7710 萬美元,聲稱 LLaMA 3.1 的訓(xùn)練成本為 5 億美元確實非常不妥。
除此之外,LLaMA 3.1 的訓(xùn)練成本應(yīng)該還包含實驗、以及故障等問題導(dǎo)致的成本開銷,如果只考慮有效訓(xùn)練時長,上述成本應(yīng)該會更低。
其實根據(jù)計算量也可以簡單預(yù)估出成本差距應(yīng)該在 10 倍左右,而不是 100 倍。
LLaMA 3.1 405B 和 DeepSeek V3 都是 15T 左右 Token 訓(xùn)練。
H100 與 H800 算力相同,成本相差不大。
MoE 的訓(xùn)練 MFU 通常會比 Dense 模型更低,但是考慮 DeepSeek 使用了 FP8 混合精度訓(xùn)練,假設(shè)其等效 MFU 相同,也就是 FP8 混合精度訓(xùn)練的加速抵消了 MoE 的降速。
核心的成本差異應(yīng)該是激活參數(shù)的差異 405B vs 37B,大約是 11 倍。
根據(jù)每個 Token 計算量(6N)、總的 Token 數(shù),以及計算資源就可以大概預(yù)估出訓(xùn)練的總時長。如下所示:
訓(xùn)練天數(shù) = Token 數(shù) * Ctoken / (GPU 數(shù) * GPU FLOPs * MFU * 3600 * 24)
根據(jù)以上公式可以預(yù)估使用 8192 H100-80G GPU(BF16 FLOPs 為 989T),10T Token 數(shù)據(jù)訓(xùn)練 175B 模型的天數(shù)為 30 天,其中假設(shè) MFU 為 50%:
10T*6*175B/(8192*989T*50%)/3600/24=30 天
DeepSeek V3 模型比較特殊,包含了 MLA 和 MoE,統(tǒng)計每個 Token 的詳細(xì)計算量也相對復(fù)雜。然而,考慮到其中最主要的計算仍是矩陣乘法,依然可以用 6N 來近似,不過這里的 N 為每個 Token 的激活參數(shù),而不是總參數(shù)量。
根據(jù)上述公式也可以大概推出 DeepSeek V3 預(yù)訓(xùn)練的 MFU:
MFU = (Token 數(shù) * Ctoken) / (訓(xùn)練天數(shù) * GPU 數(shù) * GPU FLOPs * 3600 * 24)
MFU = (Token 數(shù) * Ctoken) / (訓(xùn)練 GPU 小時數(shù) * GPU FLOPs * 3600)
而 DeepSeek-V3 預(yù)訓(xùn)練 14.8T Token,在 2048 H800 GPU 訓(xùn)練了不到 2 個月(2664K GPU 小時, 3.7*24*2048*14.8=2692K),如果上述訓(xùn)練時長是純粹的有效訓(xùn)練時長,則可以估算其 MFU 為(按 BF16 計算):
(14.8T*37B*6) / (2664K*989T*3600) = 34.7%
除此之外,作者也提到其采用了 FP8 混合精度訓(xùn)練,其訓(xùn)練速度通常至少是純 BF16 訓(xùn)練速度的 1.2x-1.3x,則對應(yīng) BF16 訓(xùn)練的 MFU 很可能在 20%-30% 之間。對于 DeepSeek V3 這種 MLA + 細(xì)粒度 MoE 的模型,也算是一個很不錯的性能。
相應(yīng)地,LLaMA 3.1 70B 總共訓(xùn)練了 15T Token,訓(xùn)練了 7.0M H100 小時,如果按照上述方式推導(dǎo)出的 MFU 為:
(15T*70B*6) / (7000K*989T*3600)= 25.2%
同理,推算出 LLaMA 3.1 405B 的 MFU 為:
(15T*405B*6) / (30.84M*989T*3600)= 33.2%
然而,作者在技術(shù)報告 The Llama 3 Herd of Models | Research - AI at Meta [11] 中提到,405B 模型訓(xùn)練的 MFU 也能達到 40% 左右。此外,根據(jù)我們的經(jīng)驗,70B Dense 模型預(yù)訓(xùn)練的 MFU 應(yīng)該在 40% 以上的水平。而上述計算出 LLaMA 3.1 70B 的 MFU 只有 25% 左右,那么很可能的原因是上述 7.0M H100 小時包含了實驗,容錯等時間。
https://arxiv.org/abs/2412.19437
https://github.com/deepseek-ai/DeepSeek-V3
https://arxiv.org/abs/2408.15664
https://arxiv.org/abs/2404.19737
https://www.high-flyer.cn/blog/hai-llm/
https://arxiv.org/abs/2401.10241
https://arxiv.org/abs/2310.10537
https://github.com/NVIDIA/cutlass
https://huggingface.co/meta-llama/Llama-3.1-8B
https://www.lepton.ai/pricing
https://ai.meta.com/research/publications/the-llama-3-herd-of-models/