自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

從裸機到700億參數(shù)大模型,這里有份教程,還有現(xiàn)成可用的腳本

人工智能 新聞
這篇文章來自于 AI 初創(chuàng)公司 Imbue,該公司致力于通過理解機器的思維方式來實現(xiàn)通用智能。

我們知道 LLM 是在大規(guī)模計算機集群上使用海量數(shù)據(jù)訓(xùn)練得到的,機器之心曾介紹過不少用于輔助和改進 LLM 訓(xùn)練流程的方法和技術(shù)。而今天,我們要分享的是一篇深入技術(shù)底層的文章,介紹如何將一堆連操作系統(tǒng)也沒有的「裸機」變成用于訓(xùn)練 LLM 的計算機集群。

這篇文章來自于 AI 初創(chuàng)公司 Imbue,該公司致力于通過理解機器的思維方式來實現(xiàn)通用智能。

當(dāng)然,將一堆連操作系統(tǒng)也沒有的「裸機」變成用于訓(xùn)練 LLM 的計算機集群并不是一個輕松的過程,充滿了探索和試錯,但 Imbue 最終成功訓(xùn)練了一個 700 億參數(shù)的 LLM,并在此過程中積累了許多有用的經(jīng)驗。

本文將深入介紹該團隊構(gòu)建自己的 LLM 訓(xùn)練基礎(chǔ)設(shè)施的全過程,并會分享他們?yōu)榉奖惚O(jiān)控、檢查和糾錯而編寫的諸多工具和腳本。

如果你有心構(gòu)建自己的 LLM 訓(xùn)練基礎(chǔ)設(shè)施或好奇 LLM 是如何煉成的,那么這篇文章值得你閱讀和收藏。

以下是 Imbue 團隊文章原文。

引言

我們這個由研究者和工程師組成的小團隊用了幾個月時間在自己的基礎(chǔ)設(shè)施上從頭開始訓(xùn)練了一個 700 億參數(shù)量的模型,并且該模型在推理相關(guān)的任務(wù)上勝過了零樣本的 GPT-4o。

今天,我們要分享的是設(shè)置所需基礎(chǔ)設(shè)施的過程:從組合初始集群和安裝操作系統(tǒng)到設(shè)置在訓(xùn)練期間遭遇錯誤時自動恢復(fù)。我們會詳細說明在每一步遭遇到的難題和解決方法。除了這些心得之外,我們還將發(fā)布我們一路上開發(fā)的許多腳本,以便其他團隊能更輕松地為自己的模型訓(xùn)練創(chuàng)建穩(wěn)定的基礎(chǔ)設(shè)施。

在整個過程中,我們的工程師團隊與 Voltage Park 一起準(zhǔn)備好了計算機集群,構(gòu)建了生產(chǎn)應(yīng)用的基礎(chǔ)。這整個過程包括:

1. 配置各臺機器

2. 配置 InfiniBand

3. 確保機器完全健康

4. 診斷常見的訓(xùn)練問題

5. 改進基礎(chǔ)設(shè)施工具

下面將詳細描述每個步驟。

背景:這是如何煉成的

我們執(zhí)行計算的目標(biāo)是確保能快速實驗大型語言模型。為此,我們需要大量高速 GPU,并且這些 GPU 之間也能高速通信。

本文將重點關(guān)注一個集群,其中包含分散在 511 臺計算機中的 4088 臺 H100 GPU,也就是每臺計算機 8 臺 GPU。之所以有 511 臺帶 GPU 的計算機,是因為需要保留一些連接給統(tǒng)一結(jié)構(gòu)管理器(Unified Fabric Manager)節(jié)點,其作用是管理 InfiniBand 網(wǎng)絡(luò)。在 511 臺帶 GPU 的主機上,每臺 GPU 都直接與一塊 ConnectX-7 網(wǎng)卡相連,其能以 400 Gbps 的速度與該 InfiniBand 網(wǎng)絡(luò)中的任意 GPU 傳輸數(shù)據(jù)。

我們的 InfiniBand 網(wǎng)絡(luò)拓撲結(jié)構(gòu)的形式是「fully non-blocking」,即完全無阻塞;理論上講,這能讓 GPU 以最大速度互相通信。為此,我們使用了一種三層式 InfiniBand 網(wǎng)絡(luò)架構(gòu):三層 InfiniBand 交換機。只要連接正確,便能讓整個網(wǎng)絡(luò)都獲得這樣高水平的吞吐量。下圖展示了這個 InfiniBand 網(wǎng)絡(luò)的概況:

圖片

請注意,訓(xùn)練網(wǎng)絡(luò)時的通信發(fā)生在 InfiniBand 上,而不是以太網(wǎng)上。盡管這些機器也連接了以太網(wǎng),但該網(wǎng)絡(luò)的作用是傳輸數(shù)據(jù)集和檢查點等數(shù)據(jù)。如果使用以太網(wǎng)來發(fā)送數(shù)據(jù),速度會慢得多,因為數(shù)據(jù)會先從 GPU 傳輸?shù)?CPU,然后再通過 100 Gbps 速度的以太網(wǎng)卡發(fā)出去。盡管也可以使用名為 RDMA over Converged Ethernet(RoCE)的技術(shù)基于以太網(wǎng)進行訓(xùn)練,但那需要在硬件和軟件方面都做大量額外工作,并且可靠程度通常也不及 InfiniBand。詳情可參閱這篇論文:https://arxiv.org/pdf/2402.15627

另外還有一個僅用于配置和管理的輔助以太網(wǎng),從而可訪問 BIOS(基本輸入輸出系統(tǒng))、電源和其他低層機器接口的控制界面。如果沒有這個管理網(wǎng)絡(luò),我們就必須通過 USB 驅(qū)動、鍵盤和顯示器來手動設(shè)置每個節(jié)點。對于有幾百臺機器的情況,這并非一種可持續(xù)的方法。

要在這個集群上實現(xiàn)高性能訓(xùn)練,就需要每個組件(InfiniBand、以太網(wǎng)、GPU 和節(jié)點本身)都近乎完美地工作。如果這 12,000 多個連接中有任何一個有點不穩(wěn)定,就會拖慢整體的訓(xùn)練運行速度。

本文接下來的內(nèi)容就是介紹如何讓這一切都完美且穩(wěn)定地運行。

過程:如何將裸機變成完全可運行的集群

配置各臺機器

在通過管理網(wǎng)絡(luò)建立了與集群的初始以太網(wǎng)連接之后,就獲得了基板管理控制器(BMC/baseboard management controller)的訪問憑證。BMC 是一種遠程監(jiān)控主機系統(tǒng)的專用服務(wù)處理器,并且通常連接到一個分立的網(wǎng)絡(luò)。它能讓我們就像是親身在現(xiàn)場一樣操作機器,并還額外提供了硬件健康狀況、BIOS 設(shè)置和電源管理的 API。

配備好這些組件后,我們就可以擼起袖子,開始設(shè)置集群了。

  • 步驟 0:先配置好一臺機器

我們首先使用 iDRAC(戴爾的基板管理控制器)在一臺服務(wù)器上安裝 Ubuntu 22.04,然后再基于這個操作系統(tǒng)設(shè)置其他一切。iDRAC 的一項能力是允許從本地計算機安裝和啟動 ISO 鏡像,并通過瀏覽器提供一個虛擬控制臺。理想情況下,這是該過程中唯一的手動安裝步驟。

  • 步驟 1:在每臺機器上安裝操作系統(tǒng)

在配置完第一臺機器之后,繼續(xù)安裝 Ubuntu 的 Metal-as-a-Service (MAAS) 軟件以幫助配置剩余的服務(wù)器。使用預(yù)啟動執(zhí)行環(huán)境協(xié)議(PXE)啟動和自動化 iDRAC 工具,可指示每臺機器從網(wǎng)絡(luò)啟動并配置 MAAS 以響應(yīng) PXE 啟動請求。在執(zhí)行初始的網(wǎng)絡(luò)啟動時,服務(wù)器會通過動態(tài) IP 分配協(xié)議 DHCP 從 MAAS 獲得一個 IP 和一個初始內(nèi)核,而無需在本地驅(qū)動器上安裝任何東西。這是用于自動重復(fù)執(zhí)行操作系統(tǒng)安裝的基本環(huán)境。從理論上講,我們只需等待第一次啟動,然后一切都會被處理好。但實際上,MAAS 與 BMC 的整合并不可靠,因此我們使用 iDRAC API 來事先收集每臺機器的 MAC 地址(一種唯一的物理硬件標(biāo)識符)。

在這整個訓(xùn)練過程中,MAAS 通常是椎棧中比較可靠的組件。但是,我們在開始時遇到了一些我們的設(shè)置特有的問題。舉個例子,在配置前幾臺機器時,由于時鐘相差太大,HTTPS 證書驗證問題導(dǎo)致無法通過 apt 安裝任何東西。與此相關(guān)的是,由于 MAAS 服務(wù)器必須負責(zé)很多事情(DHCP 服務(wù)器、用于將主機名解析成 IP 的 DNS 服務(wù)器、主機和官方 Ubuntu 軟件包服務(wù)器之間的 HTTP 代理、NTP 服務(wù)器、cloud-init 配置管理、用于將 MAC 地址連接到 IP 到主機名再到自定義元數(shù)據(jù)的 ground truth 數(shù)據(jù)庫),因此我們很難從根源上解決這些問題。此外,還有 MAAS 配置生命周期的學(xué)習(xí)曲線問題,因為是設(shè)計目標(biāo)是處理管理綠地部署(greenfield deployment)的復(fù)雜性以及節(jié)點的逐步遷移和各種調(diào)試 / 不健康的中間狀態(tài)。

  • 步驟 2:診斷損壞的機器

我們發(fā)現(xiàn)大約 10% 的機器都無法啟動,主要原因是服務(wù)器的物理問題。這是設(shè)置大型 GPU 集群的常見情況。我們遇到的情況包括:沒接網(wǎng)線或接錯了網(wǎng)線、iDRAC 中的硬件問題、電源單元損壞、NVME(快速非易失性內(nèi)存)驅(qū)動損壞、內(nèi)部線路缺失、網(wǎng)卡或 GPU 無法顯示。我們自動檢查了這些問題,將一些機器退回給了戴爾以重新測試,并為數(shù)據(jù)中心工作人員提交相應(yīng)的工單。我們自己上手配置集群的一個優(yōu)勢是:在等待維護某些機器的同時就能立即使用健康的機器。

  • 步驟 3:最小可行可觀察機器

我們繼續(xù)在每臺服務(wù)器上進行如下設(shè)置:

1.Docker(以便更輕松地運行服務(wù)和訓(xùn)練作業(yè))

2. 數(shù)據(jù)中心 GPU 驅(qū)動

3.Prometheus 節(jié)點導(dǎo)出工具(用于導(dǎo)出穩(wěn)定的硬件 / 操作系統(tǒng)指標(biāo)數(shù)據(jù)流)

4.DCGM 導(dǎo)出工具(用于從英偉達 GPU 導(dǎo)出額外的指標(biāo)數(shù)據(jù),如 GPU 狀態(tài)、時鐘、利用率)

5. 所有非操作系統(tǒng)驅(qū)動的 RAIDZ ZFS 池,這讓機器在某個驅(qū)動失效時也能繼續(xù)工作,同時還能免費提供透明的壓縮(這對純文本數(shù)據(jù)集和重復(fù)性日志尤其有用 —— 相比于不使用該工具,使用該工具通常能將可使用的空間增大 10 倍)

然后我們運行基本的 GPU 診斷以確定 GPU 是否大體功能正常 —— 不正常的通常會在幾個小時內(nèi)出現(xiàn)硬件問題。

在此期間,當(dāng)我們試圖同時在全部 400 個節(jié)點上安裝軟件包時,我們遭遇了帶寬瓶頸。這是我們第一次在數(shù)據(jù)中心部署的多個組件上收到高溫過熱警報。這首批發(fā)熱問題基本上都通過固件更新得到了解決。

  • 步驟 4:單節(jié)點的 GPU 訓(xùn)練

下一步是確保每臺機器都能夠單獨處理真實的 GPU 工作負載。很多機器都無法做到這一點,問題包括:

  • GPU 相關(guān)的錯誤,這類問題基本都可通過將 GPU 卡重新插入卡槽來解決:將 200 磅重的服務(wù)器從機架上滑出來,移除機蓋和 GPU 之間的所有線纜,然后取出 GPU,再重新裝上 GPU,之后再重新接上線纜并把服務(wù)器推回機架。
  • 根據(jù) Ubuntu 服務(wù)器日志,GPU 和 PCIe 總線或網(wǎng)卡之間的許多線纜都發(fā)出了這樣的報錯:「limited width: x4 < x16」。在更新 PCIe 交換機總線固件后,我們發(fā)現(xiàn)大約四分之一的主機需要重新安裝內(nèi)部 PCIe 線纜 —— 大概是因為外殼和 GPU 之間的線纜相當(dāng)脆弱,這意味著每當(dāng)對 GPU 進行維護時,這些線纜都會被推擠或拔掉。
  • 還有一些雜項故障也影響了幾臺主機。戴爾通過固件升級幫助我們解決了一些問題:
  • NVMe 驅(qū)動器沒有顯示故障,但觸摸時會鎖定整臺機器。
  • 硬盤驅(qū)動器在 Linux 下以隨機順序顯示,這給 MAAS 造成了混亂,并會導(dǎo)致操作系統(tǒng)被安裝在錯誤的驅(qū)動器上。
  • 溫度讀數(shù)錯誤,這會導(dǎo)致風(fēng)扇一直全速運轉(zhuǎn)。其原因可能是英偉達驅(qū)動有問題,這通過降級驅(qū)動版本而得到了解決。
  • CPU 的動態(tài)調(diào)頻失控,將工作內(nèi)核限制為 2 GHz。
  • 直接的 GPU-GPU 通信(GDR 或 GPUDirect RDMA Peer Memory Client)無法成功應(yīng)用。

配置 InfiniBand

  • 步驟 0:安裝 UFM

InfiniBand 的一個優(yōu)勢是其中心化的設(shè)計,這樣一來整個網(wǎng)絡(luò)就有了一個大腦。因此,對于整個網(wǎng)絡(luò)結(jié)構(gòu)中的 320 個網(wǎng)絡(luò)交換機,我們只需處理其中一個實例。我們的首個任務(wù)是搞清楚哪臺交換機連接了哪些機器,然后將其與接線圖關(guān)聯(lián)起來,并根據(jù)交換機的物理位置重新命名它們。

  • 步驟 1:重新布線

一開始,UFM 無法檢測到那 320 臺交換機,更別說本應(yīng)出現(xiàn)在網(wǎng)絡(luò)結(jié)構(gòu)中的主機了。在與我們的數(shù)據(jù)中心合作伙伴商討之后,我們確認這些交換機已通電并接好了線,但依然無法檢測到。在檢查網(wǎng)絡(luò)布線列表后,我們注意到該網(wǎng)絡(luò)結(jié)構(gòu)的頂層設(shè)計有誤:這個結(jié)構(gòu)不是統(tǒng)一的,而是分成了八個沒有公共路由路徑的互相脫離的網(wǎng)絡(luò)。在重新接線之后,我們添加了檢查步驟,以驗證所有物理連接是否與新設(shè)計一致。

  • 步驟 2:一萬次溫度告警(alert)

在解決了物理接線問題之后,InfiniBand 成功建立了與網(wǎng)絡(luò)結(jié)構(gòu)中所有 InfiniBand 交換機的聯(lián)系。但是,幾乎每個交換機端口都開始報告溫度過高,有時候超過 70 ℃,即便它們還沒有傳輸數(shù)據(jù)。我們發(fā)現(xiàn)這個問題源自同一機架中交換機之間的開放空間,這導(dǎo)致熱空氣回流到了前面。我們的數(shù)據(jù)中心合作伙伴幫助我們快速診斷出了該問題并制定了合適的解決方法。

  • 步驟 3:1800 次告警

許多端口還有很高的錯誤率,或在正常和損壞狀態(tài)之間來回變動,這被稱為「抖動(flapping)」。這些問題只有在實際使用這些端口時才會出現(xiàn),所以很難預(yù)先檢測,因為我們的整個結(jié)構(gòu)由 10,000 條高度冗余的鏈路組成。我們的數(shù)據(jù)中心合作伙伴幫助清潔和重新安裝告警的端口,我們在等待替換時禁用了剩余的警報收發(fā)器。

盡管 InfiniBand 能彈性地應(yīng)對硬件故障,但一旦大約 10% 的結(jié)構(gòu)開始出現(xiàn)問題,自適應(yīng)路由等功能就無法可靠地運行,無法解決偶爾丟失鏈路的問題。

在此期間,我們成功使用 100 到 200 臺機器運行了多節(jié)點訓(xùn)練。我們的流程比較即興:我們有時會隨機啟動一組節(jié)點,觀察它們的性能,然后盡力讓其中盡可能多的節(jié)點保持運行。該方法可讓我們找到該 InfiniBand 網(wǎng)絡(luò)結(jié)構(gòu)中一組可靠的子集,但難度卻很大,因為每次都需要改變用于訓(xùn)練的節(jié)點集合,由此改變默認的 InfiniBand 鏈路。

  • 步驟 4:InfiniBand 瘋狂燃燒

為了更高效地診斷 InfiniBand 問題,我們專門為整個集群設(shè)計了一個工作負載,其作用是同時將盡可能多的數(shù)據(jù)推送經(jīng)過整個結(jié)構(gòu)中的每個端口。這不同于在整個集群上運行一個大型的 all-reduce 工作負載,這需要使用 NCCL 來優(yōu)化各個節(jié)點之中的通信,方法是使用 NVLink 經(jīng)由 Server PCIe Module (SXM) 插槽來實現(xiàn) GPU 通信。

相反,我們選擇了一種蠻力方法,并輕松取得了成功。UFM 會在大多數(shù)端口的數(shù)據(jù)傳輸量超過理論容量的 97% 時開始發(fā)出警報,同時一些交換機會暫時宕機。我們認為能堅持到當(dāng)天結(jié)束時的每個端口都是足夠穩(wěn)健的,其余的都被禁用或移除以待維修。

  • 步驟 5:GPUDirect RDMA

要讓 GPU 通信時不產(chǎn)生 CPU 計算開銷,我們啟用了一個名為 GPUDirect RDMA 的功能,其允許 InfiniBand 網(wǎng)卡之間直接通信。這涉及兩個關(guān)鍵步驟:

1. 啟動一個額外的核模塊

2. 確保 PCIe Access Control Service (ACS) 被禁用,以防止 immediate hangs(立即掛起)

  • 步驟 6:擴增「黃金」服務(wù)器

要使用最新硬件構(gòu)建 GPU 集群,一個經(jīng)驗法則是:每周都有大約 3% 的機器出問題,要做好準(zhǔn)備。

但是,需要說明一點:并不是每臺機器都統(tǒng)一有 3% 的幾率發(fā)生故障,而是少量不對付的機器反復(fù)出現(xiàn)各種不同問題,直到將它們妥善修復(fù)。這就凸顯了在同一網(wǎng)絡(luò)結(jié)構(gòu)中配備大量機器的優(yōu)勢。因此,我們的做法不是隨便找些機器來運行大規(guī)模訓(xùn)練,就像打地鼠一樣看哪些出問題,而是專注于擴增已知可靠的服務(wù)器,也就是「黃金」服務(wù)器。

  • 步驟 7:維護

InfiniBand 的維護主要涉及到響應(yīng) UFM 警報、更換故障線纜和收發(fā)器,以及偶爾診斷更困難的錯誤(比如交換機故障)。導(dǎo)致大規(guī)模維護的因素通常有兩個:

1. 固件更新,尤其是集群中僅有一半完成更新時,這可能導(dǎo)致 UFM 狀態(tài)損壞并必需重啟所有 InfiniBand 交換機上的 UFM。

2.GPU 盒同時大規(guī)模重啟,這可能會向 UFM 狀態(tài)灌入大量更新,并同樣需要重啟 UFM 服務(wù)。

確保機器完全健康

在此過程中,我們發(fā)現(xiàn)了單臺機器的多種故障或減慢訓(xùn)練速度的方式。其中許多故障模式并不會立即顯現(xiàn),因此我們編寫了許多健康檢查腳本,以檢查主機是否足夠健康。我們在這里發(fā)布了這些代碼:https://github.com/imbue-ai/cluster-health

請注意,這些健康檢查中的很多都特定于我們的運行時環(huán)境,并不一定與基礎(chǔ)硬件相關(guān),也不一定容易修復(fù)或自動化。這是設(shè)計決定的:為了實現(xiàn)讓我們的機器準(zhǔn)備好訓(xùn)練的總體目標(biāo),我們想要一個可以直接了當(dāng)?shù)鼗卮稹甘恰够颉阜瘛沟膯我蝗肟邳c,并且可以概括總結(jié)任意數(shù)量的細微細節(jié)。

  • GPU 健康檢查

我們檢查了 GPU 數(shù)量是否正確、ECC(錯誤更正代碼)檢查是否已啟用以及是否存在 ECC 錯誤。我們還檢查了 NVLink 拓撲(將 GPU 彼此連接起來)是否已啟動且無錯誤。

  • 磁盤空間健康檢查

我們檢查了主機的磁盤空間利用率是否超過 95%。

  • Docker 健康檢查

我們檢查了 Docker 能否在連接了 GPU 的情況下運行容器(即 NVIDIA Container Runtime 是否正常工作),還檢查了與監(jiān)控 / 分析相關(guān)的 Docker 容器是否已激活并獲得了正確的主機權(quán)限。

  • Dmesg 健康檢查

我們檢查了 dmesg 中是否存在硬件 Xids 或 SXid 錯誤(由 NVIDIA GPU 或 GPU 間 NVIDIA 交換機引發(fā)的故障)。我們還讀取了所有 dmesg 日志行,以驗證它們是否都可以歸類到「常見 / 預(yù)期日志行」列表中。

  • iDRAC 健康檢查

我們檢查了機器上的 iDRAC 錯誤,其中忽略了非致命錯誤消息。這是戴爾計算機特有的檢查,所以沒有被包括在我們開源的代碼中。

  • 磁盤健康檢查

我們檢查了 zpool 是否已安裝,Docker 是否已正確連接到它,以及它是否真的可以在不鎖定 CPU 的情況下觸及它。

  • InfiniBand 健康檢查

我們檢查了 InfiniBand 的錯誤率是否會增加和 / 或驅(qū)動固件是否過時。

  • Nvlink 健康檢查

我們檢查了機器上的 NVLink 錯誤。實踐中看,這似乎不會導(dǎo)致訓(xùn)練失敗,但可能會降低訓(xùn)練速度。

  • GDR 健康檢查

我們檢查了機器上的 GDR 是否已啟用。

  • VBIOS 健康檢查

我們檢查了 GPU 的 VBIOS 版本以及 H100 基板固件是否是最新的。

  • Flint 健康檢查

我們使用 flint 和 hca_self_test 檢查了 Mellanox OFED 驅(qū)動、網(wǎng)卡固件和收發(fā)器固件的版本是否正確,以及它們是否針對英偉達驅(qū)動進行了正確編譯。

  • PSB 健康檢查

我們查詢了 PCIe 設(shè)備,以檢查 GPU、PSB(PCIe 交換機總線)和網(wǎng)卡之間的連接速度和寬度是否符合我們的預(yù)期。我們還檢查了交換機固件是否為最新版本。該腳本由戴爾而非 Imbue 開發(fā),所以我們目前無法共享它。

除了這些快速健康檢查,我們還進行了一些更復(fù)雜的健康檢查,包括:

  • 通過 PyTorch 初始化矩陣計算,以及測量 NVLink 帶寬和 GPU 計算速度和內(nèi)存。我們設(shè)置了適當(dāng)?shù)?GDR 標(biāo)志來測試 InfiniBand 和 NVLink。
  • 使用 ib_write_bw 和 –use_cuda 通過 IB 卡發(fā)送數(shù)據(jù)并測量 PCIe 和 InfiniBand 卡帶寬。這個過程持續(xù)了較長時間(約 15 分鐘),以確保能找出抖動的 InfiniBand 鏈路。
  • 運行多節(jié)點診斷運行以檢查 NCCL 初始化能力以及它是否會隨機停頓。如有停頓,則我們的分叉版 NCCL 代碼會添加額外的日志記錄。這需要 12 到 24 小時才能檢測到問題,因此我們通常只對新節(jié)點或我們懷疑存在問題時運行此操作。
  • 檢查 DCGM 導(dǎo)出是否存在任何 GPU 時鐘節(jié)流事件(不包括預(yù)期的 gpu_idle 和 power_cap)。為了檢查這些電源事件,最好的方法是運行多節(jié)點訓(xùn)練,以同時檢查所有 GPU、InfiniBand 卡以及 CPU 和磁盤。

診斷常見的訓(xùn)練問題

一旦硬件能正常工作,就可以開始訓(xùn)練了。

這一節(jié)將基于我們在我們的集群上運行大型語言模型訓(xùn)練的經(jīng)驗,分享一些具體的調(diào)試步驟和見解。

  • 啟動時崩潰

從某種程度上講,這是所能遇到的最好的錯誤,因為其(理論上)很容易重現(xiàn)和迭代。

我們首先檢查了我們的代碼是否在正確的版本、配置和環(huán)境變量上運行。雖然很基礎(chǔ),但我們發(fā)現(xiàn)這一點至關(guān)重要:確保啟動訓(xùn)練過程是可復(fù)現(xiàn)且容易檢查的。一大原因是 Docker 鏡像緩存或不透明秘密配置等中間抽象可能會造成混淆。

我們執(zhí)行的另一個基礎(chǔ)檢查是確保所有機器都在線,并且可以輕松地聚合和檢查所發(fā)出的棧跟蹤記錄或日志。我們使用了 Loki、Prometheus 和 Grafana 軟件棧,但任何合適的日志聚合或跟蹤 SaaS 的工具都可以。由于這些訓(xùn)練運行過程本質(zhì)上是同步的和分布式的,因此第一個錯誤往往就會導(dǎo)致一連串的不相關(guān)錯誤。在這里,健康檢查還可以幫助立馬檢測出硬盤驅(qū)動器損壞或 GPU 缺失或無效等錯誤。

我們構(gòu)建了一個在發(fā)生故障時自動重啟的系統(tǒng),這使得日志和錯誤聚合變得更加重要,以避免混淆來自不同重啟的錯誤。我們遇到的一些常見錯誤包括:

1.「Forward order differs across ranks: rank 0 is all-gathering 43 parameters while rank 1228 is all-gathering 1 parameters」這樣的錯誤。我們發(fā)現(xiàn)這是 PyTorch 完全分片數(shù)據(jù)并行(FSDP)實現(xiàn)的一個奇怪特性,可通過重啟解決。

2.GPU 內(nèi)存不足(OOM)錯誤,看起來像這樣:「CUDA out of memory. Tried to allocate …」通過多次檢查我們的配置和代碼并撤銷近期的代碼修改(由于啟動期間 PyTorch 設(shè)備規(guī)格不正確而導(dǎo)致過多使用 GPU#0),我們解決了這些問題。

3.CPU/RAM 內(nèi)存不足(OOM)錯誤,這些錯誤在錯誤日志中不太容易發(fā)現(xiàn),并且通常能通過 Docker 容器外的主機的 dmesg 日志檢測出來。當(dāng) OOM Killer 調(diào)用停止一個分叉進程或同級網(wǎng)絡(luò)(network peer)時,我們可以看到它們主要表現(xiàn)為 CalledProcessError 或 ConnectionError。當(dāng)從 dmesg 檢測到了 OOM Killer 調(diào)用時,我們更傾向于直接放棄健康檢查,并重啟該機箱。我們還檢查了我們的代碼路徑是否有足夠的手動垃圾收集(下面有一部分介紹了如何禁用它),并還檢查了是否有意外嘗試進行計算或?qū)埩恳苿拥?CPU 上。

  • 在訓(xùn)練過程中崩潰

首要任務(wù)是讓系統(tǒng)能自動運行,讓其能自動重新運行所有健康檢查,然后在沒發(fā)現(xiàn)不健康主機時重啟運行。我們遇到了一些隨機的硬件錯誤,包括 Xid 和 SXid 錯誤;這些錯誤可能會導(dǎo)致運行崩潰,卻不會發(fā)出有意義的 Python 棧跟蹤記錄。行重映射等一些問題可通過重啟恢復(fù)。不可糾正的 ECC 錯誤等另一些問題則往往需要硬件維護或更換零件。

此外,我們還觀察到格式錯誤的訓(xùn)練數(shù)據(jù)也會導(dǎo)致崩潰。舉個例子,如果語料庫中有一個非常大的單個文檔,就可能導(dǎo)致 GPU 或 CPU 出現(xiàn)內(nèi)存不足錯誤。為了防止出現(xiàn)這個問題,我們采用了完全確定式的數(shù)據(jù)加載器 —— 通過與 epoch 或步數(shù)相關(guān)聯(lián),讓每一次崩潰都可輕松復(fù)現(xiàn)。我們發(fā)現(xiàn)禁用數(shù)據(jù)加載或替換假數(shù)據(jù)(例如全零數(shù)據(jù))有助于確認錯誤的根本原因是否是數(shù)據(jù)。

最后,通過指標(biāo)聚合方法記錄網(wǎng)絡(luò)和一般節(jié)點的健康統(tǒng)計數(shù)據(jù)也很有幫助。以太網(wǎng)短暫斷開或磁盤空間不足等問題可能不會顯示為有用的錯誤消息,但卻可以很輕松地與已收集的數(shù)據(jù)相關(guān)聯(lián)。

  • 沒有棧跟蹤信息的掛起(之后可能會有超時問題)

由于這些問題缺乏有幫助的信息,加上很難可靠地復(fù)現(xiàn),因此這類錯誤的調(diào)試工作著實讓人沮喪。

其中最令人難忘的錯誤類型伴隨著這樣的報錯信息:

Watchdog caught collective operation timeout:WorkNCCL (SeqNum=408951, OpType=_ALLGATHER_BASE, … , Timeout (ms)=600000) ran for 600351 milliseconds before timing out

并且訓(xùn)練運行中的所有 GPU 工作器都發(fā)出了這樣的報錯信息。

這意味著一臺或多臺主機未能完成 NCCL 操作或者 NCCL 和 InfiniBand 連接崩潰,導(dǎo)致其他所有主機同時卡在了某個張量運算上,直到達到 NCCL_TIMEOUT 超時時間。不幸的是,受 NCCL 軟件庫本質(zhì)所限,我們很難找到究竟是哪臺主機出了問題。

我們對 NCCL 軟件庫的日志記錄做了一些修改,參見我們的分叉版:https://github.com/boweiliu/nccl 。從而在崩潰發(fā)生時可能更好地揭示正在執(zhí)行的消息或操作,從而確定阻止運行的可能是哪臺主機或 GPU。

請注意,為了識別行為不當(dāng)?shù)闹鳈C,我們通常需要搞清楚哪些主機沒有生成某些日志消息。缺少此類消息表明該主機上的工作器已落后或已崩潰。

其他沒有可用錯誤消息的無響應(yīng)情況通常與硬件相關(guān)問題有關(guān),比如之前提到的 Xid/SXid/ECC 錯誤會導(dǎo)致英偉達驅(qū)動或英偉達 Docker 通信驅(qū)動鎖定。為了區(qū)分 NCCL 掛起與驅(qū)動掛起以及 Python 代碼中的競爭條件或死鎖,我們使用 Py-Spy 和 GNU Project Debugger(GDB)等工具來實時調(diào)試遇到的停滯進程。使用此方法可發(fā)現(xiàn)一個特定問題:由于 Python 線程設(shè)置中的配置錯誤,我們無法在某些主機上正確啟動八個多線程 NCCL GPU 進程,這些進程在 PyTorch 之前的初始化代碼階段遇到了競爭條件。

  • 訓(xùn)練減速(由 MFU 測量)

缺乏工具讓這類問題比前一類更讓人沮喪。除了使用 Py-Spy、棧跟蹤檢查和 GDB 之外,我們還采用了 NVIDIA Nsight 和 profiling 工具,其中一些工具在高度分布式的設(shè)置中很難使用。

遺憾的是,導(dǎo)致一般減速或讓速度低于之前演示的模型浮點數(shù)利用率(MFU)的原因有很多。

首先,事實證明多次檢查配置、代碼和環(huán)境變量是有用的。我們經(jīng)歷過的錯誤包括:運行了錯誤的模型、批量大小錯誤、UFM 或 NCCL 設(shè)置出錯、CUDA_DEVICE_MAX_CONNECTIONS 出錯。這都會導(dǎo)致性能無法達到最優(yōu)。

我們還發(fā)現(xiàn)測量瞬時(即每批次)MFU(而不是平滑或窗口平均值)很有用,因為未平滑處理的 MFU 曲線通常有助于診斷問題類別。導(dǎo)致訓(xùn)練速度下降的問題包括:

  • 從非常低的 MFU(低于預(yù)期的十分之一)立即開始訓(xùn)練并保持穩(wěn)定

這多半是 InfiniBand 網(wǎng)絡(luò)連接的硬件問題,例如 T2 或 T3 層的交換機死機。GPU 和 NIC 之間的硬件問題也可能導(dǎo)致該情況,對此 dmesg 會這樣報錯:PCIe x16 lanes limited by …

  • 從預(yù)期 MFU 的 30% 立即開始訓(xùn)練并保持穩(wěn)定

其原因可能是一臺主機的 GDR 設(shè)置不正確(NVIDIA 對等內(nèi)存)或 GDR 環(huán)境變量不正確。

  • 從預(yù)期 MFU 的約 60-80% 立即開始訓(xùn)練并保持穩(wěn)定

最常見的原因是 InfiniBand 鏈路質(zhì)量不行或故障,尤其是單臺 GPU 出現(xiàn)了與 InfiniBand NIC 相關(guān)的故障,導(dǎo)致 NCCL 嘗試經(jīng)由本地 NVLink 路由流量并在同一主機上的另一臺 GPU 上使用 NIC。CPU 節(jié)流也可能導(dǎo)致該問題,這需要調(diào)整某些主機的 BIOS 設(shè)置。

  • 在處理某些數(shù)據(jù)批次時突然大幅減速(下降 10 倍),并且經(jīng)常發(fā)生這種情況

這基本上都與檢查點或評估有關(guān) —— 可通過檢查 epoch 數(shù)或步數(shù)來驗證。惱火的是,如果設(shè)置了在 MFU 異常時自動告警,就會出現(xiàn)許多誤報。

  • 在處理某些數(shù)據(jù)批次時突然大幅減速(下降 10 倍)

這種情況是隨機發(fā)生的并且相當(dāng)罕見(大概每 15 分鐘一次),并且之后馬上就會完全恢復(fù)到良好的 MFU。

最常見的原因似乎是其他需要大量 CPU 計算的工作負載被調(diào)度到了一臺運行中的主機上。我們發(fā)現(xiàn),與其構(gòu)建分析工具來識別特定的主機,通過 PID 來粗略地監(jiān)控 CPU 會更容易。其原因可能是偶爾出現(xiàn)的網(wǎng)絡(luò)連接問題,比如數(shù)據(jù)加載器遭遇瓶頸。我們監(jiān)控了數(shù)據(jù)加載、檢查點和任何非 NCCL 代碼的指標(biāo)數(shù)據(jù)并添加了 Python 代碼計時日志,事實證明這非??煽?。

  • MFU 在運行過程中逐漸減慢,但每次重啟后又會回到 100%

理論上講,其原因可能是交換機上的熱量積累,但我們從未見過這種情況。不過,我們使用 Python 和 NVIDIA 分析器確定:性能下降的原因似乎是自動垃圾收集。

圖片

在調(diào)試解決這些減速問題時,我們發(fā)現(xiàn)吞吐量幾乎必然會周期性地下降。隨著訓(xùn)練地推進,這種下降會對分布式運算帶來越來越多的影響。這讓我們猜想下降的原因可能與自動垃圾收集有關(guān) —— 我們通過分析和測試驗證了這個猜想。當(dāng)我們禁用了自動垃圾收集,并在所有主機上設(shè)定只在特定的間隔內(nèi)收集垃圾,這種吞吐量「下降」就消失了。

我們使用了一種基于 ZeRO-3 的同步分布式訓(xùn)練算法 FSDP。在阻塞操作期間,運行垃圾收集的單個工作器進程可能會減慢其他所有工作器的速度。如果有數(shù)百個工作器進程,就可能導(dǎo)致速度大幅下降。

一開始性能良好,然后突然下降(達到預(yù)期的 70%),并且以高頻持續(xù)(每 15 秒)

我們觀察到這與英偉達 GPU 的「時鐘節(jié)流原因」相關(guān),這可通過對英偉達 DCGM 進行適當(dāng)?shù)脑O(shè)置來解決。發(fā)熱問題(GPU 高溫或主機冷卻風(fēng)扇故障 / 效果下降)或電源故障會導(dǎo)致該問題。另外,當(dāng)我們同時最大化所有 8 臺 GPU 利用率和 8x NIC InfiniBand 利用率以及 CPU/RAM/ 磁盤時,我們的一些具有特定電源硬件的主機會出現(xiàn)電壓問題,但只有全部使用它們(通常只在實際訓(xùn)練運行期間)時才會出現(xiàn)這種情況。

  • 性能優(yōu)良但噪聲比平常情況多(高頻白噪聲方差在預(yù)期 MFU 的 90% 和 100% 之間)

這也與 InfiniBand 硬件有關(guān),但通常是由于網(wǎng)絡(luò)中較高層的鏈路出現(xiàn)一定程度的性能下降或抖動,而不是冗余度較低的主機到 T2 層。

不幸的是,很多這類問題都難以定位到某臺具體主機,而與 InfiniBand 相關(guān)的問題尤其難以定位,這是由于 InfiniBand 交換機技術(shù)的拓撲感知特性。InfiniBand 似乎更偏好 InfiniBand fat-tree 設(shè)計中的相鄰主機,而 UFM 能以不對稱的鏈路速度路由數(shù)據(jù)包。

以下是用于調(diào)試吞吐量問題的簡單摘要 / 流程圖 / 完備性檢查表:

  • 這套系統(tǒng)之前能正常工作嗎?
  • 你最近做了什么修改(比如合并代碼、更新驅(qū)動)?
  • 你運行的主機是否健康?你的所有依賴服務(wù)是否都運行正常,包括第三方的 SaaS,比如 Docker Hub、GitHub 等等?
  • 你能確定現(xiàn)在運行的代碼、環(huán)境、配置、版本、主機列表、排名順序、隨機種子與上次完全相同嗎?(如果能實現(xiàn)這樣的檢查的話。)
  • 問題可復(fù)現(xiàn)嗎?
  • 與其他事物有何關(guān)聯(lián)?其他進程?每日 crontab 定時任務(wù)?主機或 DCGM 或 UFM 指標(biāo)?
  • 你的工具是否能正確度量這些指標(biāo)?
  • 在運行約簡版的代碼(使用更小的模型、假數(shù)據(jù)、不保存或加載檢查點)時,問題是否依然存在?

改進基礎(chǔ)設(shè)施工具

完成了以上步驟之后,就能在訓(xùn)練模型時實現(xiàn)優(yōu)良性能了…… 至少在某個地方出故障之前是這樣。

本節(jié)將介紹一些用于確保訓(xùn)練持續(xù)穩(wěn)定的工具和系統(tǒng),同時最好盡可能地少地需要人類干預(yù)。由于我們這個團隊很小,因此我們沒有足夠的人手來進行人工維修,所以我們也希望能盡可能地自動化這個過程。

我們在訓(xùn)練過程中遇到的所有問題幾乎都可歸因于機器或網(wǎng)絡(luò)組件故障。這類故障在大型集群中很常見,因此我們的做法是自動禁用出故障的機器和網(wǎng)絡(luò)組件并發(fā)送維修請求。

  • 機器故障

我們開發(fā)了一個系統(tǒng),可在運行崩潰時自動從最近的檢查點重啟。在這個重啟過程中,首先是對每臺可用機器進行健康檢查,然后基于其傳遞的健康檢查結(jié)果對每臺機器進行分類;然后嘗試在最健康的機器上重啟訓(xùn)練。

  • 網(wǎng)絡(luò)組件故障

我們觀察到的所有網(wǎng)絡(luò)故障都可通過 UFM 檢測到,并會被記錄到 UFM 事件日志中,因此響應(yīng)方式也很簡單:解析 UFM 日志并采取相應(yīng)措施。

UFM 事件系統(tǒng)非常復(fù)雜,包含數(shù)十種事件類型。但在實踐中,我們發(fā)現(xiàn)只有少數(shù)事件有問題,主要與鏈路故障或符號錯誤技術(shù)較高有關(guān)。在識別出這些事件后,我們可以編寫腳本來解析 UFM 事件日志、禁用與最近事件相關(guān)的鏈路和端口、為這些網(wǎng)絡(luò)組件申請維護工單、維護完成后重新啟用這些組件。

  • 本地鏡像文件系統(tǒng)

對于這些大型分布式訓(xùn)練,人們很早就發(fā)現(xiàn)集群與以太網(wǎng)的數(shù)據(jù)交換速度是一大瓶頸。一條共享以太網(wǎng)連接的帶寬大約為 10Gbit/s;如果有數(shù)百個工作器同時下載數(shù)據(jù)集和模型檢查點,那么這點帶寬會很快飽和。

為此,我們決定在我們集群內(nèi)部構(gòu)建一個本地文件系統(tǒng),以作為云存儲的鏡像,其本質(zhì)上就是一個緩存空間,可以減少從 S3 讀取的文件量。為了解決集群流失問題(即因為維修原因而禁用或更換機器的情況),我們?yōu)槊糠菸募紲?zhǔn)備了三個副本,并使用了一致性哈希以均勻分配負載,從而在集群流失期間最大限度地減少文件移動。由于集群的磁盤空間有限,所以我們必須開發(fā)多種工具來跟蹤文件的生命周期和清除不再有用的文件。

  • 本地分布式 Docker 注冊表

我們使用了 Kraken,這是一個可點對點傳輸 Docker 鏡像的出色開源軟件。這個軟件幾乎沒出現(xiàn)過任何問題,我們還是挺驚訝的,畢竟我們的任務(wù)和實現(xiàn)都很復(fù)雜。工具地址:https://github.com/uber/kraken

  • 各種性能監(jiān)控工具

我們設(shè)置了默認的 Torch 分析器以及英偉達的 Nsight Systems。后者可幫助我們了解前向 / 反向通過以及 NCCL 通信所需的確切時間,并進一步幫助我們確定給定的模型大小和工作器數(shù)量是否會成為瓶頸。然而,Nsight Systems 有點難用,因為其需要在特權(quán)模式下運行 Docker,這需要禁用與性能監(jiān)控事件相關(guān)的安全檢查,并且保存其配置時往往需要停止整個訓(xùn)練進程。

此外,我們也編寫了工具來檢測訓(xùn)練速度慢的數(shù)據(jù)批次并理解其可能原因。我們發(fā)現(xiàn)這很有用。其中最有用的工具的作用是監(jiān)控每一批次所需的時間并在某批次過于慢時丟棄該工作器的棧跟蹤 —— 這讓我們可以更輕松地找到硬件或軟件有些小問題的主機。

  • 將機器分成不同的組別以定位故障主機

在使用該集群的前幾個月(那時候健康檢查還不如現(xiàn)在這般透徹),我們經(jīng)常遇到這種情況:在一組機器上訓(xùn)練時出現(xiàn)故障,但并不清楚究竟是哪臺機器有問題。為了找到故障主機,我們開發(fā)了一些工具,可輕松地把一組機器分成不同的小組,然后在每個機器小組上運行更小的訓(xùn)練。

舉個例子,如果一個在 48 臺機器上運行的訓(xùn)練失敗了,那么就在 6 組各 8 臺機器上進行更小規(guī)模的訓(xùn)練,然后在 8 組各 6 臺機器上運行更小規(guī)模的訓(xùn)練。通常情況下,這兩個階段中只有一次運行會失敗,這讓我們有信心得出結(jié)論:在兩個階段中都出問題的機器是有問題的。

反思和學(xué)習(xí)到的經(jīng)驗教訓(xùn)

在設(shè)置和維護基礎(chǔ)設(shè)施的過程中,我們獲得了一些有用的經(jīng)驗教訓(xùn):

  • 一種有用的做法是交換機器的位置。在運行時,使用多于所需機器數(shù)量 10-20% 的機器會很有幫助,這樣就能在機器故障時輕松重啟訓(xùn)練了。設(shè)置集群網(wǎng)絡(luò)連接時讓每臺機器都與其他每臺機器緊密相連,這樣一來我們就能使用這些機器中任意可工作的子集。
  • 對遇到的每一個硬件或軟件故障,編寫測試和自動化解決方案是值得的,因為訓(xùn)練中遇到的每一個問題都會再次出現(xiàn)。類似地,對于每一個含混不清的報錯消息,都值得編寫更能解釋該錯誤的工具。
  • 可重復(fù)性是優(yōu)秀科研的關(guān)鍵。我們立馬就采用的一大原則是:「一次只修改一個地方」,即便最簡單的地方也是如此。
  • 信任,但也要驗證。每當(dāng)我們引入外部工具或加入新人員(無論是來自公司內(nèi)還是公司外)時,我們都會仔細檢查他們聲稱的東西,尤其是當(dāng)后續(xù)步驟依賴于這些聲稱的東西時。

總結(jié)

訓(xùn)練大型語言模型一開始就需要復(fù)雜的基礎(chǔ)設(shè)施。我們之所以選擇深入?yún)⑴c基礎(chǔ)設(shè)施的設(shè)置細節(jié),是因為我們相信完全理解我們操作的系統(tǒng)是非常重要的,也因為我們認為這樣做的效率更高。

現(xiàn)在,經(jīng)歷過整個流程之后,我們很高興我們采用了這樣的方法 —— 事實證明,能完全控制我們的基礎(chǔ)設(shè)施以及有能力輕松地在每個抽象層級上進行調(diào)試具有至關(guān)重要的價值。雖然這個過程需要大量的監(jiān)督和迭代,但它讓我們可以深入地理解其底層工作流程、構(gòu)建一系列用于確保主機健康的工具、學(xué)習(xí)如何讓系統(tǒng)自動運行以確保訓(xùn)練持續(xù)平滑,最終構(gòu)建起一套讓我們可以快速迭代訓(xùn)練前沿語言模型的基礎(chǔ)設(shè)施。

這個基礎(chǔ)設(shè)施構(gòu)建流程體現(xiàn)了我們研究和構(gòu)建 AI 智能體的基礎(chǔ)方法論:探究細枝末節(jié),不斷改進現(xiàn)有流程,并構(gòu)建有用的工具和系統(tǒng)使我們這個積極奮進的團隊能夠應(yīng)對更大的挑戰(zhàn)。

責(zé)任編輯:張燕妮 來源: 機器之心
相關(guān)推薦

2024-01-02 09:49:19

AI研究調(diào)查

2019-08-16 09:20:39

數(shù)據(jù)清理數(shù)據(jù)集分析數(shù)據(jù)

2017-07-28 10:20:47

深度學(xué)習(xí)自然語言神經(jīng)機器

2017-07-28 15:45:43

深度學(xué)習(xí)自然語言神經(jīng)網(wǎng)絡(luò)

2023-09-04 12:58:05

2020-11-04 14:42:09

5G套餐iPhone 125G手機

2019-11-21 15:35:28

機器學(xué)習(xí)人工智能計算機

2019-10-11 08:04:48

網(wǎng)絡(luò)安全信息安全數(shù)據(jù)泄露

2024-12-23 00:27:40

2025-02-20 09:27:46

2023-12-13 12:55:39

模型數(shù)據(jù)

2024-11-11 17:16:44

2022-04-04 17:52:20

模型計算DeepMind

2025-02-14 08:40:57

2022-08-20 07:52:56

語言模型參數(shù)PaLM

2023-11-21 08:00:20

AI模型

2015-09-22 13:08:42

戴爾云計算

2019-08-16 09:55:22

Pandas編程語言代碼
點贊
收藏

51CTO技術(shù)棧公眾號