解讀DeepseekV3
我見過的最省的GPT4o,Claude,Gemini2級(jí)別的模型,而且是國內(nèi)唯一有機(jī)會(huì)上桌的,其實(shí)海外目前和這三家有資格掰手腕的也只有它自己,可以負(fù)責(zé)任的說其他的模型不配上桌吃菜(Gemini上個(gè)月都沒資格)。
其實(shí)性能好就不說了,DeepseekR1就還不錯(cuò),國內(nèi)講道理是第一家做inference timing scaling law的模型,阿里是第二家,其他的就不太值得談?wù)摿?,其?shí)國外也只有GPT和Google有資格,沒想到年底還能出個(gè)DeepseekV3,在傳統(tǒng)scaling law這邊還能玩出花活兒,實(shí)屬不易。
FP8混合精度訓(xùn)練框架,并首次驗(yàn)證其在超大規(guī)模模型上的有效性。
它模型下載下來看起來還能行啊,也就不到700G,那正常671B的參數(shù),根本不可能這么點(diǎn)顯存占用,應(yīng)該1.4T左右,這是因?yàn)樗虵P8出的,這大概是我知道的第一個(gè)原生之直接出FP8的模型,Meta說很早就用FP8訓(xùn)練了,那Llama3啥的也默認(rèn)都BF16的,有些特定的模型FP8 GPTQ/AWQ過,像它這么激進(jìn)的應(yīng)該是第一個(gè)。
省錢
只有2.664M GPU小時(shí)的經(jīng)濟(jì)成本,完成了對(duì)14.8萬億tokens的DeepSeek-V3預(yù)訓(xùn)練,預(yù)訓(xùn)練后的進(jìn)一步階段僅需要0.1M GPU小時(shí),因?yàn)镕P8嗎,自然就省算力,也省顯存,還省通信,要不也不能就這么2048張卡就打發(fā)了,預(yù)訓(xùn)練階段,DeepSeek-V3在每萬億tokens上的訓(xùn)練僅需180K H800 GPU小時(shí),即以2048 H800 GPUs集群僅需3.7天的時(shí)間。就能訓(xùn)1萬億的token。因此。預(yù)訓(xùn)練在不到兩個(gè)月內(nèi)完成,總體使用GPU時(shí)間為2664K小時(shí)。加上上下文擴(kuò)展需要的119K GPU小時(shí)以及后續(xù)訓(xùn)練需要的5K GPU小時(shí),總計(jì)2788K GPU小時(shí),約合$5.576M。如果算上其他精細(xì)調(diào)整部分,總成本尚不足$5.576M,看到這心里真的在滴血啊,比起動(dòng)輒幾百億人民幣都聽不出來個(gè)響的公司,它簡直是白蓮花了。(當(dāng)然它家本身不缺錢,做成現(xiàn)在這種各種優(yōu)化能力,也是之前多少錢砸出來的經(jīng)驗(yàn))省錢因?yàn)镕P8這是主要理由,但是光靠FP8是不夠的,我們一會(huì)接著講。
code math很不錯(cuò)
這個(gè)肯定是蒸餾級(jí)別的高級(jí)模型的數(shù)據(jù)了,這個(gè)沒什么可避諱的,Google的gemni2還蒸餾了Athropic的Claude3.5, 現(xiàn)在這也正常,蒸餾出來只是一方面,關(guān)鍵得訓(xùn)到Parameter里才是硬道理,而且為了增加V3的性能,Deepseek團(tuán)隊(duì),還蒸餾了自己的R1的reason能力作為語料和隱式COT給V3灌進(jìn)去。(主要是后訓(xùn)練階段)。
MLA (多頭潛注意力,Multi-HeadLatentAttention)
這個(gè)也是老活兒了,DeepseekV2里就有,但是真的好用,啥叫多頭潛注意力呢?
現(xiàn)規(guī)定幾個(gè)變量啊
- d: 嵌入維度(Embedding dimension),表示詞向量的維度。
- nh: 注意力頭的數(shù)量(Number of attention heads)。
- dh: 每個(gè)注意力頭的維度(Dimension per head)。
- ht: 第t個(gè)token在某個(gè)注意力層的輸入(Attention input for the t-th token)。
MLA 的核心思路就是:
- 先對(duì) token 的特征進(jìn)行一個(gè)“低秩”或“小維度”的壓縮(稱為 latent vector),再通過少量的變換將它還原/擴(kuò)展到各頭所需要的 Key、Value 空間。
- 一部分必要的信息(如旋轉(zhuǎn)位置編碼 RoPE)的矩陣則保持單獨(dú)處理,讓網(wǎng)絡(luò)依然能保留時(shí)序、位置信息。
我們看看它怎么搞的啊。首先定義一個(gè)矩陣潛注意力W^{DKV}。
你就理解成一個(gè)下投影的矩陣,維度是 d x d_c,d_c是非常小的。
原始是啥呢?原始肯定是dh*nh啊,也就是每個(gè)頭的hidden_size,也可以說embedding size,這倆玩意等價(jià)的然后*多少個(gè)頭,也就是等于d。
dh*nh其實(shí)可以理解近似為hidden_size,也就是d,因?yàn)槟愣鄠€(gè)頭就直接對(duì)接了模型的寬度么,那你這倆至少得4096吧(咱哪怕以llama來計(jì)算)。
然后我們搞下面這么個(gè)式子,也就是把你的第t個(gè)token在某個(gè)hidden_layer的輸出你經(jīng)過我剛才說的下投影矩陣給一壓縮,那就變得非常小了。
c_t^{KV} = W^{DKV} h_t
h_t原始維度是啥?是d啊,比如4096,我經(jīng)過一個(gè)d*dc的下投影矩陣。
d矩陣乘于d*d_c, 一出來就變d_c維的向量c_t^{KV} 了,比如d_c是400,那就小10倍,就是這么個(gè)壓縮。
c_t^{KV} 是一個(gè)低維度的向量,是壓縮后的 keys 和 values 的 latent 向量。d_c 表示壓縮后的維度,遠(yuǎn)小于 d_h * n_h,所以你kv對(duì)就小了唄,因?yàn)樾×耍哉硷@存也少了,推理的時(shí)候kv_cache也少,推的也快,這下看懂了吧!
當(dāng)然你肯定還得逆向把你壓縮的回復(fù)到原來的維度,那就乘一個(gè)上矩陣,要不也推不了么,可以簡單認(rèn)為存的時(shí)候存這玩意c_t^{KV} (不占空間),用的時(shí)候還得矩陣乘一個(gè)上矩陣來還原,這塊就不解釋了。
rope也一樣,要被算出來一個(gè)key,最后rope的key和壓縮的key,一起合成一個(gè)key,因?yàn)橐獛е恢镁幋a,這快我也不細(xì)講了,看明白我剛才講的,可以自己去看論文,邏輯是一樣的,微信公眾號(hào)寫數(shù)學(xué)公式太遭罪了,好累,能少寫就少寫點(diǎn)。
剛才講的是對(duì)于推理的時(shí)候優(yōu)化,訓(xùn)練的時(shí)候把Q也順便給優(yōu)化了,道理和剛才的kv一樣,就并不贅述了。
路由專家和共享專家結(jié)合的MOE
路由專家 (Routed Experts) 和共享專家 (Shared Experts) 在 DeepSeekMoE 架構(gòu)中扮演著不同的角色,它們的主要區(qū)別在于如何被激活和利用。
路由專家 (Routed Experts):
- 選擇性激活: 路由專家是按需激活的。對(duì)于每個(gè)輸入的 token,只有一部分路由專家會(huì)被選中并參與計(jì)算。這個(gè)選擇過程由一個(gè)門控機(jī)制 (gating mechanism) 決定,例如 DeepSeekMoE 中使用的基于親和度分?jǐn)?shù)的 Top-K 選擇。
- 專精化: 每個(gè)路由專家都被設(shè)計(jì)為擅長處理特定類型的輸入或?qū)W習(xí)特定的特征。通過選擇性激活,模型能夠?qū)⒉煌妮斎肼酚傻阶詈线m的專家進(jìn)行處理,從而實(shí)現(xiàn)專精化處理。
- 稀疏性: 由于只有一部分路由專家被激活,所以計(jì)算是稀疏的,可以提高模型的效率。
- 負(fù)載均衡: 門控機(jī)制的目標(biāo)之一是實(shí)現(xiàn)專家之間的負(fù)載均衡,確保不同的專家在不同的輸入上被激活,避免某些專家過載。
DeepSeekMoE 使用 稀疏門控 (sparse gating) 的機(jī)制來選擇激活哪些路由專家。只有與當(dāng)前 token 最匹配(親和度分?jǐn)?shù)最高)的個(gè)路由專家才會(huì)被激活并產(chǎn)生非零的Kr門控值。其他路由專家的門控值為 0,意味著它們不參與當(dāng)前 token 的處理。
共享專家 (Shared Experts):
- 全局參與: 共享專家始終參與所有輸入的處理。無論輸入是什么,所有共享專家都會(huì)貢獻(xiàn)它們的力量。
- 通用知識(shí): 共享專家旨在學(xué)習(xí)對(duì)所有輸入都有用的通用知識(shí)或基礎(chǔ)特征。它們可以捕捉到數(shù)據(jù)中普遍存在的模式。
- 促進(jìn)泛化: 由于共享專家對(duì)所有輸入都有貢獻(xiàn),它們有助于模型學(xué)習(xí)更魯棒和泛化的表示,減少過擬合的風(fēng)險(xiǎn)。
- 提高穩(wěn)定性: 共享專家可以為模型的預(yù)測提供一個(gè)更穩(wěn)定的基礎(chǔ),尤其是在路由機(jī)制不夠完美或者某些輸入不適合任何特定的路由專家時(shí)。
那你拿到的最終的outputs是啥呢?
就是路由專家和共享專家的值乘以他們的權(quán)重,然后加權(quán),所以輸入也相當(dāng)是一個(gè)有重點(diǎn),有泛化的輸出。
Auxiliary-Loss-Free Load Balancing(輔助損失無關(guān)的負(fù)載均衡)
這個(gè)設(shè)計(jì)很巧妙,MOE專家就多對(duì)把,那多服務(wù)節(jié)點(diǎn)系統(tǒng)無論是什么都跑不出要做負(fù)載均衡,MOE也一樣,純輪訓(xùn)肯定是開玩笑。
傳統(tǒng)怎么做的呢?
依賴于輔助損失 以避免不平衡的負(fù)載。然而,過大的輔助損失會(huì)損害模型性能,輔助損失是什么呢?
訓(xùn)練機(jī)器學(xué)習(xí)模型時(shí),除了主要的損失函數(shù)(用于衡量模型在主要任務(wù)上的性能)之外,額外引入的損失函數(shù)。 你可以把它理解為一個(gè)次要的、額外的優(yōu)化目標(biāo)。
在MOE領(lǐng)域輔助損失主要干這些事:
- 衡量負(fù)載不均衡程度: 輔助損失通常會(huì)定義一個(gè)指標(biāo)來衡量當(dāng)前專家負(fù)載的均衡程度。常見的指標(biāo)包括:
- 專家被選擇的頻率差異: 計(jì)算每個(gè)專家被路由到的輸入數(shù)量,并衡量這些數(shù)量之間的差異。差異越大,不均衡程度越高。
- 每個(gè)專家的平均負(fù)載: 衡量每個(gè)專家處理的輸入的復(fù)雜度或計(jì)算量,并確保這些平均負(fù)載相對(duì)均勻。
- 作為懲罰項(xiàng)添加到總損失中: 將衡量到的負(fù)載不均衡程度轉(zhuǎn)化為一個(gè)損失值,并將其添加到模型的主要任務(wù)損失中。這樣,在訓(xùn)練過程中,模型不僅要努力完成主要任務(wù),還要努力減少負(fù)載不均衡帶來的額外損失。
- 鼓勵(lì)更均勻的路由決策: 通過反向傳播,負(fù)載均衡輔助損失會(huì)影響模型中門控網(wǎng)絡(luò)的參數(shù)。門控網(wǎng)絡(luò)負(fù)責(zé)決定將哪些輸入路由到哪些專家。輔助損失會(huì)促使門控網(wǎng)絡(luò)學(xué)習(xí)更均勻的路由策略,避免過度集中到某些專家。
傳統(tǒng)都是這么做的,但是如上文我們提到的,你怎么定義輔助損失?如果定義的有問題,會(huì)影響模型
Deepseek就不用輔助損失了,那么怎么實(shí)現(xiàn)的呢?
偏差項(xiàng): 為每個(gè)路由專家引入一個(gè)偏差項(xiàng),將其添加到相應(yīng)的親緣度得分中,以確定最終選擇的專家。
動(dòng)態(tài)調(diào)整偏差項(xiàng): 在訓(xùn)練過程中,模型會(huì)持續(xù)監(jiān)控每個(gè)專家的負(fù)載情況。如果某個(gè)專家過載,則降低其偏差項(xiàng);如果某個(gè)專家負(fù)載不足,則增加其偏差項(xiàng)。
消除輔助損失: 通過這種動(dòng)態(tài)調(diào)整偏差項(xiàng)的方法,DeepSeek-V3 能夠在不使用輔助損失函數(shù)的情況下保持專家負(fù)載均衡,從而最大程度地減少了對(duì)模型性能的負(fù)面影響。
在無輔助損失的前提下呢,它又?jǐn)U展了一下Complementary Sequence-Wise Auxiliary Loss(補(bǔ)充性的序列級(jí)輔助損失)。
盡管 DeepSeek-V3 主要依靠無輔助損失策略來實(shí)現(xiàn)負(fù)載均衡,但為了防止任何單個(gè)序列中出現(xiàn)極端不平衡的情況,它還使用了一種補(bǔ)充性的序列級(jí)平衡損失。該損失函數(shù)鼓勵(lì)每個(gè)序列上的專家負(fù)載均衡,并使用一個(gè)極小的平衡因子來確保其對(duì)模型性能的影響最小化。
節(jié)點(diǎn)受限路由:
為了進(jìn)一步降低訓(xùn)練成本,DeepSeek-V3 還采用了節(jié)點(diǎn)受限路由機(jī)制,限制每個(gè)令牌最多只能發(fā)送到四個(gè)節(jié)點(diǎn)進(jìn)行處理。這種機(jī)制有效地減少了跨節(jié)點(diǎn)通信的開銷,并使模型能夠?qū)崿F(xiàn)更高的訓(xùn)練效率。
更高的訓(xùn)練效率: 通過采用更細(xì)粒度的專家和節(jié)點(diǎn)受限路由,DeepSeek-V3 能夠更高效地利用計(jì)算資源,并降低訓(xùn)練成本。
你們以前玩過hadoop,不有就近計(jì)算么,和那玩意差不多,就是降低通信導(dǎo)致的計(jì)算代償,也沒啥好解釋的。
另外就是MTP了,也是今天講的最后一個(gè)吧!
這張圖展示了 DeepSeek-V3 中使用的 Multi-Token Prediction (MTP) 的實(shí)現(xiàn)方式。我們可以把它分解開來理解:
核心思想:
MTP 的核心思想是在訓(xùn)練過程中,模型不僅預(yù)測下一個(gè) token (像傳統(tǒng)的語言模型一樣),還同時(shí)預(yù)測序列中后續(xù)的幾個(gè) token。這可以為模型提供更豐富的訓(xùn)練信號(hào),幫助它更好地理解上下文和長距離依賴關(guān)系。
圖中的組成部分:
Input Tokens (輸入 Tokens): 圖的底部顯示了輸入到模型中的 token 序列,例如 t?, t?, t?, t?。
Target Tokens (目標(biāo) Tokens): 圖的頂部顯示了模型需要預(yù)測的目標(biāo) token 序列。注意,不同的模塊對(duì)應(yīng)的目標(biāo) token 是不同的。
Main Model (主模型): 這部分代表了模型的核心結(jié)構(gòu),通常是一個(gè) Transformer 模型的堆疊。
(Next Token Prediction) (下一個(gè) Token 預(yù)測): 說明主模型的任務(wù)是預(yù)測序列中的下一個(gè) token。
Embedding Layer (嵌入層): 將輸入的 token 轉(zhuǎn)化為向量表示。
Transformer Block × L (Transformer 模塊 × L): L 代表 Transformer 模塊的層數(shù),是模型進(jìn)行上下文理解和特征提取的核心部分。
Output Head (輸出頭): 將 Transformer 模塊的輸出轉(zhuǎn)化為預(yù)測下一個(gè) token 的概率分布。
Cross-Entropy Loss (交叉熵?fù)p失): 計(jì)算主模型預(yù)測結(jié)果與實(shí)際下一個(gè) token 之間的損失,這是訓(xùn)練主模型的標(biāo)準(zhǔn)損失函數(shù)。
MTP Module 1 (MTP 模塊 1): 這是第一個(gè) MTP 模塊。
(Next2 Token Prediction) (下第二個(gè) Token 預(yù)測): 說明這個(gè)模塊的任務(wù)是預(yù)測輸入序列中下第二個(gè) token。例如,當(dāng)輸入為 t?, t?, t?, t? 時(shí),它預(yù)測 t?。
Embedding Layer (嵌入層): 與主模型共享 (Shared) 嵌入層,這可以節(jié)省參數(shù)并學(xué)習(xí)通用的 token 表示。
Transformer Block (Transformer 模塊): 與主模型類似,用于處理輸入并提取特征。
Linear Projection (線性投影) 和 RMSNorm (RMS 歸一化): 這些是 Transformer 模塊內(nèi)部的常見組件,用于調(diào)整維度和穩(wěn)定訓(xùn)練。這沒啥可講的。
Concatenation (拼接): 這里將 Embedding Layer 的輸出與 Transformer Block 的輸出拼接起來,為預(yù)測提供更豐富的上下文信息。
Output Head (輸出頭): 將 Transformer 模塊的輸出轉(zhuǎn)化為預(yù)測下第二個(gè) token 的概率分布。
它輸出那肯定也是交叉熵?fù)p失,計(jì)算 MTP 模塊 1 預(yù)測結(jié)果與實(shí)際下第二個(gè) token 之間的損失。
MTP Module 2 (MTP 模塊 2): 這是第二個(gè) MTP 模塊。(Next3 Token Prediction) (下第三個(gè) Token 預(yù)測): 說明這個(gè)模塊的任務(wù)是預(yù)測輸入序列中下第三個(gè) token。例如,當(dāng)輸入為 t?, t?, t?, t? 時(shí),它預(yù)測 t?。
結(jié)構(gòu)與 MTP Module 1 類似: 它也共享嵌入層,并包含 Transformer Block、線性投影、RMS 歸一化和輸出頭,不講了和前面一樣。
以此類推可以有更多的 MTP 模塊,每個(gè)模塊預(yù)測序列中更遠(yuǎn)的后續(xù) token。
Shared (共享): 虛線箭頭標(biāo)明了不同模塊之間共享的組件,例如嵌入層。
工作流程和意義:
輸入: 一個(gè) token 序列被輸入到模型中。
主模型預(yù)測: 主模型基于輸入預(yù)測下一個(gè) token。
MTP 模塊預(yù)測: 同時(shí),不同的 MTP 模塊基于稍微偏移的輸入分別預(yù)測下第二個(gè)、下第三個(gè)以及更遠(yuǎn)的 token。
損失計(jì)算: 每個(gè)模塊都計(jì)算其預(yù)測結(jié)果與實(shí)際目標(biāo) token 之間的交叉熵?fù)p失。
聯(lián)合訓(xùn)練: 所有模塊(主模型和 MTP 模塊)的損失會(huì)被聯(lián)合起來進(jìn)行反向傳播,更新模型的參數(shù)。
MTP 的優(yōu)勢:
更豐富的訓(xùn)練信號(hào): 模型不僅學(xué)習(xí)預(yù)測下一個(gè) token,還學(xué)習(xí)預(yù)測更遠(yuǎn)的未來 token,這有助于模型理解更長期的依賴關(guān)系和上下文信息。(上下文感知能力的提升)
潛在的加速收斂: 通過提供額外的預(yù)測任務(wù),模型可能更快地學(xué)習(xí)到有效的表征。
提高生成質(zhì)量: 學(xué)習(xí)預(yù)測多個(gè)未來 token 可能有助于生成更連貫和有意義的文本,這個(gè)對(duì)續(xù)寫任務(wù)是很有用的,當(dāng)然有人測試,它文科任務(wù)一般,估計(jì)是語料的問題。對(duì)code也同樣有用,尤其是多行代碼(它的code不錯(cuò))
剩下什么強(qiáng)化PP流水線降低Bubble時(shí)間啥的我就不講了,大家自己下去看看論文吧
最后補(bǔ)一下訓(xùn)練方式,準(zhǔn)確說是4階段:
2階段預(yù)訓(xùn)練,第一階段32k;
第二階段補(bǔ)到128k,擴(kuò)展上下文;
SFT和RLHF的后訓(xùn)練;
訓(xùn)練方式中規(guī)中矩,傳統(tǒng)scaling law打法。
本文轉(zhuǎn)載自??熵減AI??,作者:周博洋
