大模型并行訓(xùn)練指南:通俗理解Megatron-DeepSpeed之模型并行與數(shù)據(jù)并行(下)
共 7557字,需瀏覽 16分鐘
·
2024-04-18 20:11
文末《大模型項目開發(fā)線上營》秒殺倒計時↓↓↓
接前文:
(上)篇>>>大模型并行訓(xùn)練指南:通俗理解Megatron-DeepSpeed之模型并行與數(shù)據(jù)并行(上)
06
BF16Optimizer/CUDA 融合核函數(shù)/數(shù)據(jù)集/嵌入LayerNorm/位置編碼
6.1 優(yōu)先使用BF16 Optimizer,而非FP16
BF16Optimizer,如果您不熟悉這種數(shù)據(jù)格式,請查看它的 位布局
BF16 格式的關(guān)鍵是它的指數(shù)位數(shù)與 FP32 相同,因此不會溢出,但 FP16 經(jīng)常溢出
FP16 的最大數(shù)值范圍為 64k,您只能進行較小數(shù)的乘法。例如你可以做 250*250=62500,但如果你嘗試 255*255=65025,你就會溢出,這是導(dǎo)致訓(xùn)練出現(xiàn)問題的主要原因。這意味著你的權(quán)重必須保持很小。一種稱為損失縮放(loss scaling)的技術(shù)有助于緩解這個問題,但是當(dāng)模型變得非常大時,F(xiàn)P16 較小的數(shù)值范圍仍然是一個問題
BF16 沒有這個問題,你可以很容易地做 10_000*10_000=100_000_000有意思是的,我司七月審稿項目組在用一萬多條paper-review數(shù)據(jù)微調(diào)llama2 7B時也遇到了這個問題,即
“原本的LongQLoRA源碼訓(xùn)練參數(shù)指定使用fp16數(shù)據(jù)類型,但是訓(xùn)練可能會很不穩(wěn)定 具體而言,可能會出現(xiàn)數(shù)值溢出問題,初期就出現(xiàn)loss嚴(yán)重震蕩,甚至高達上百,并在數(shù)步后返回模型已收斂(但實際并未)的提示而中斷訓(xùn)練,故要設(shè)置使用bf16數(shù)據(jù)類型進行訓(xùn)練,loss就能穩(wěn)定從4.多開始收斂”
更多詳見此文《七月論文審稿GPT第2版:用一萬多條paper-review數(shù)據(jù)集微調(diào)LLaMA2 7B最終反超GPT4》的5.1節(jié)LLaMA2 7b chat + LongQLoRA訓(xùn)練
-
當(dāng)然,由于 BF16 和 FP16 的大小相同,均為 2 個字節(jié),因此,沒有免費的午餐,當(dāng)使用 BF16 時,代價就是它的精度非常差。然而,你應(yīng)該還記得我們在訓(xùn)練時采用的隨機梯度下降法及其變體,該方法有點像蹣跚而行,如果你這步?jīng)]有找到完美的方向其實沒關(guān)系,你會在接下來的步驟中糾正自己 -
無論使用 BF16 還是 FP16,都有一個權(quán)重副本始終在 FP32 中 —— 這是由優(yōu)化器更新的內(nèi)容。因此 16 位格式僅用于計算,優(yōu)化器以全精度更新 FP32 權(quán)重,然后將它們轉(zhuǎn)換為 16 位格式以用于下一次迭代 所有 PyTorch 組件都已更新,以確保它們在 FP32 中執(zhí)行任何累加,因此不會發(fā)生精度損失 一個關(guān)鍵問題是梯度累積,它是流水線并行的主要特征之一,因為每個 micro batch 處理的梯度都會累積。在 FP32 中實現(xiàn)梯度累積以保證訓(xùn)練的精確性至關(guān)重要,這正是
BF16Optimizer所做的
除了其他改進之外,我們認(rèn)為使用 BF16 混合精度訓(xùn)練將潛在的噩夢變成了一個相對平穩(wěn)的過程,這可以從以下 lm 損失圖中看出:
6.2 CUDA 融合核函數(shù)
GPU 主要做兩件事。它可以將數(shù)據(jù)寫到顯存或從顯存讀數(shù)據(jù),并對這些數(shù)據(jù)執(zhí)行計算。當(dāng) GPU 忙于讀寫數(shù)據(jù)時, GPU 的計算單元就會空閑。如果我們想有效地利用 GPU,我們希望將空閑時間降至最低
-
核函數(shù)是一組實現(xiàn)特定 PyTorch 操作的指令。例如,當(dāng)你調(diào)用 torch.add 時,它會通過一個 PyTorch 調(diào)度器,它會根據(jù)輸入張量及其他變量的取值來決定它應(yīng)該運行哪些代碼,最后運行它。CUDA 核函數(shù)使用 CUDA 來實現(xiàn)這些代碼,因此只能在 NVIDIA GPU 上運行 比如舉個例子,當(dāng)使用 GPU 計算 c = torch.add (a, b); e = torch.max ([c,d]) 時
一般情況下,PyTorch 將執(zhí)行的操作是啟動兩個單獨的核函數(shù),一個執(zhí)行 a 和 b 的加法,另一個執(zhí)行取 c 和 d 兩者的最大值。在這種情況下,GPU 從其顯存中獲取 a 和 b,執(zhí)行加法運算,然后將結(jié)果寫回顯存(一次對a b的讀取 一次對c的寫入)。然后它獲取 c 和 d 并執(zhí)行 max 操作,然后再次將結(jié)果寫回顯存(再一次對c d的讀取 一次對max[c d]結(jié)果的寫入)
但如果我們要融合這兩個操作,即將它們放入一個 “融合核函數(shù)” 中,然后啟動那個內(nèi)核,我們不會將中間結(jié)果 c 寫到顯存中,而是將其保留在 GPU 寄存器中(僅一次對 a b的讀取),并且僅需要獲取 d 來完成最后的計算(一次對d的讀取 一次對max[c d]結(jié)果的寫入)。這節(jié)省了大量開銷并防止 GPU 空閑,因此整個操作會更加高效
融合核函數(shù)就是這樣。它們主要將多個離散的計算和進出顯存的數(shù)據(jù)移動替換為有很少數(shù)據(jù)移動的融合計算。此外,一些融合核函數(shù)會對操作進行數(shù)學(xué)變換,以便可以更快地執(zhí)行某些計算組合July注:這其實有點類似flash attention的思想,詳見此文:通透理解FlashAttention與FlashAttention2:全面降低顯存讀寫、加快計算速度 -
為了快速高效地訓(xùn)練 BLOOM,有必要使用 Megatron-LM 提供的幾個自定義 CUDA 融合核函數(shù)。特別地,有一個 LayerNorm 的融合核函數(shù)以及用于融合縮放、掩碼和 softmax 這些操作的各種組合的核函數(shù)。Bias Add 也通過 PyTorch 的 JIT 功能與 GeLU 融合。這些操作都是瓶頸在內(nèi)存的,因此將它們?nèi)诤显谝黄鹨赃_到最大化每次顯存讀取后的計算量非常重要。因此,例如,在執(zhí)行瓶頸在內(nèi)存的 GeLU 操作時同時執(zhí)行 Bias Add,運行時間并不會增加。這些核函數(shù)都可以在 Megatron-LM repository 代碼庫 中找到
6.3 數(shù)據(jù)集
Megatron-LM 的另一個重要特性是高效的數(shù)據(jù)加載器。在首次訓(xùn)練啟動前,每個數(shù)據(jù)集中的每個樣本都被分成固定序列長度(BLOOM 為 2048)的樣本,并創(chuàng)建索引以對每個樣本進行編號?;谟?xùn)練超參,我們會確定每個數(shù)據(jù)集所需要參與的 epoch 數(shù),并基于此創(chuàng)建一個有序的樣本索引列表,然后打亂它
舉個例子,如果一個數(shù)據(jù)集中有 10 個樣本并應(yīng)參與 2 個 epoch 的訓(xùn)練,則
-
系統(tǒng)首先按 [0, ..., 9, 0, ..., 9] 順序排好樣本索引,然后打亂該順序為數(shù)據(jù)集創(chuàng)建最終的全局順序 請注意,這意味著訓(xùn)練不會簡單地遍歷整個數(shù)據(jù)集然后重復(fù),你有可能在看到另一個樣本之前看到同一個樣本兩次,但在訓(xùn)練結(jié)束時模型將只看到每個樣本兩次。這有助于確保整個訓(xùn)練過程中的訓(xùn)練曲線平滑。這些索引,包括每個樣本在原始數(shù)據(jù)集中的偏移量,被保存到一個文件中,以避免每次開始訓(xùn)練時都重新計算它們 -
最后,可以將其中幾個數(shù)據(jù)集以不同的權(quán)重混合到訓(xùn)練最終使用的數(shù)據(jù)中
6.4 嵌入LayerNorm
在我們努力阻止 104B 模型發(fā)散的過程中,我們發(fā)現(xiàn)在第一個層詞嵌入層之后添加一個額外的 LayerNorm 可以使訓(xùn)練更加穩(wěn)定
StableEmbedding 操作,它是一個帶有 LayerNorm 的普通嵌入,其使用均勻 xavier 函數(shù)來初始化
6.5 位置編碼
07
其他事項:訓(xùn)練中的困難與重要資源
在訓(xùn)練開始之前,有很多問題需要弄清楚。特別是,我們發(fā)現(xiàn)了幾個問題,這些問題只有在我們開始在 48 個節(jié)點上進行訓(xùn)練后才會出現(xiàn),而不會在小規(guī)模時出現(xiàn)
例如,需要設(shè) CUDA_LAUNCH_BLOCKING=1 來防止框架掛起,我們需要將優(yōu)化器組分成更小的組,否則框架會再次掛起。你可以在訓(xùn)前編年史 中詳細了解這些內(nèi)容
訓(xùn)練期間遇到的主要問題類型是硬件故障。由于這是一個擁有大約 400 個 GPU 的新集群,平均每周我們會遇到 1-2 個 GPU 故障。我們每 3 小時 (100 次迭代) 保存一個檢查點。因此,我們每周因硬件崩潰平均損失 1.5 小時的訓(xùn)練成果。Jean Zay 系統(tǒng)管理員隨后將更換有故障的 GPU 并恢復(fù)節(jié)點。與此同時,我們有備用節(jié)點可供使用。
我們還遇到過多次導(dǎo)致 5-10 小時停機的各種其他問題,其中一些與 PyTorch 中的死鎖錯誤有關(guān),另一些則是由于磁盤空間不足。如果您對具體細節(jié)有興趣,請參閱 訓(xùn)練編年史
在對訓(xùn)練這個模型進行可行性分析時,所有這些停機時間都被計劃在內(nèi)了,我們也據(jù)此選擇了合適的模型大小和我們希望模型消耗的數(shù)據(jù)量。因此,即使存在這些停機問題,我們還是成功地在預(yù)計時間內(nèi)完成了訓(xùn)練。如前所述,它需要大約 100 萬個計算時才能完成
另一個問題是 SLURM 并非設(shè)計為供一組人使用。SLURM 作業(yè)由單個用戶擁有,如果他們不在身邊,則該組的其他成員無法對正在運行的作業(yè)執(zhí)行任何操作。我們制定了一個終止方案,允許組中的其他用戶終止當(dāng)前進程,而不需要啟動該進程的用戶在場。這在 90% 的問題上都很有效。如果 SLURM 設(shè)計者讀到這篇文章,請?zhí)砑右粋€ Unix 組的概念,這樣一個 SLURM 作業(yè)就可以由一個組擁有
由于訓(xùn)練是全天候 24/7 進行的,我們需要有人隨叫隨到,但由于我們在歐洲和加拿大西海岸都有人,因此不需要有人攜帶傳呼機,我們能很好地互相備份。當(dāng)然,周末的訓(xùn)練也得有人看著。我們自動化了大部分事情,包括自動從硬件崩潰中恢復(fù),但有時仍需要人工干預(yù)
7.2 重要鏈接
-
主訓(xùn)練文檔 -
Tensorboard -
訓(xùn)練用的 slurm 腳本 -
訓(xùn)練記錄
7.3 論文與文章
我們不可能在本文中詳細解釋所有內(nèi)容,因此如果此處介紹的技術(shù)激起你的好奇心,使你想了解更多信息,請閱讀以下論文:
-
Efficient Large-Scale Language Model Training on GPU Clusters. -
Reducing Activation Recomputation in Large Transformer Models
-
ZeRO: Memory Optimizations Toward Training Trillion Parameter Models -
ZeRO-Offload: Democratizing Billion-Scale Model Training -
ZeRO-Infinity: Breaking the GPU Memory Wall for Extreme Scale Deep Learning -
DeepSpeed: Extreme-scale model training for everyone
-
Using DeepSpeed and Megatron to Train Megatron-Turing NLG 530B, A Large-Scale Generative Language Model.
-
Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation -
What Language Model to Train if You Have One Million GPU Hours? - 你會在那里找到最終選擇 ALiBi 的實驗
-
8-bit Optimizers via Block-wise Quantization (使用了該論文中的嵌入 LaynerNorm,但是論文的其他部分及其技術(shù)也很妙,沒用 8 位優(yōu)化器的唯一原因是我們已經(jīng)使用 DeepSpeed-ZeRO 節(jié)省了優(yōu)化器內(nèi)存)
課程進度:已直播前27課(都有回放),每周兩到三次課,均在晚8-10點上課。
校長July寄語
“
為何講大模型商用項目的課程很罕見
一方面,即便在大廠,雖有技術(shù)但沒法講其內(nèi)部項目,而專門搞應(yīng)用開發(fā)的小廠,很難將其賴之生存的項目拿出來講
二方面,一般職業(yè)講師 背后沒有項目團隊 只能搞個demo,至于一般教育機構(gòu)也很難再搞個項目團隊,成本大 招人難 做出成果更難
而我司教育團隊外,我司去年專門成立了大模型項目開發(fā)團隊(由我?guī)毢驮诖髲S的兼職組成)
一者,for b端做一系列大模型解決方案,正在逐一上線一系列大模型產(chǎn)品(每個項目均由各個項目組迭代好幾個月)
二者,很多項目開發(fā)/落地經(jīng)驗、數(shù)據(jù)/代碼都放到了這個線上營中,如表現(xiàn)突出邀請加入至對應(yīng)項目組且給報酬 ”
① 一年GPU,封裝了諸如ChatGLM3等各大主流大模型
② 一個VIP年卡「200多個AI小課、4個大模型小課(即ChatGPT原理、類ChatGPT微調(diào)實戰(zhàn)、SD及其二次開發(fā)、垂直大模型實戰(zhàn))」
