JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

經營叢集:排程、檢查點與容錯

在千卡規模下,每隔幾小時就有一個節點故障。我們從單一工作走向經營一支機隊:排程、切片檢查點、彈性復原與混合硬體。

從一份工作到一支機隊

前面幾篇讓單次訓練跑得快。這一篇要在共享硬體上讓上千次訓練存活。在規模之下,統計會反過來對付你:若單張 GPU 有一個微小的故障率,一份橫跨上千張的工作就保證每隔幾小時撞上一次硬體故障。一次耗時數週的前沿訓練必然會被打斷數十次。於是基礎設施不再是關於峰值速度,而變成關於有效產出(goodput):實際時鐘時間中真正在取得進展、而非等待、重啟或重算遺失工作的比例。系統面的擴展律唯有在有效產出維持高檔時才會兌現。

\mathrm{MTBF}_{\mathrm{job}} \approx \frac{\mathrm{MTBF}_{\mathrm{node}}}{N}

為什麼大規模會讓統計學與你為敵:當有 N 個節點時,作業的平均無故障間隔縮小為單節點 MTBF 除以 N——所以在千卡規模下故障每隔幾小時就會發生。

排程:在搶用的叢集上放置工作

GPU 叢集排程器(Slurm、Kubernetes 或自製系統)決定哪份工作在哪些加速器上、何時執行。分散式訓練施加了兩個一般排程器忽略的硬性約束。第一,成組排程(gang scheduling):一份工作的全部 N 個 worker 必須一起啟動,否則誰也無法前進——一個只配到一半的 all-reduce 工作就直接死鎖。第二,拓撲感知:排程器應把一份工作的 GPU 裝箱到同一個 NVLink 島嶼與相鄰的網路骨幹上,因為如上一篇所示,放置決定通訊成本。一個把 256 張 GPU 撒滿整個資料中心交給你的排程器,已經悄悄把你的吞吐量砍半。

分散式檢查點:存狀態而不停擺

檢查點是你對抗故障的唯一保險,但對於權重與優化器狀態動輒數 TB 的模型,樸素地存檔本身就是一場災難:把所有東西匯流到單一 rank 去寫一個檔案,會讓整座叢集停擺數分鐘。分散式檢查點以平行方式寫入——每個 rank 持久化它本來就持有的切片,於是檢查點頻寬隨叢集規模擴展。這是 3D 平行檢查點切片(checkpoint sharding)的天生夥伴:磁碟上的布局映射記憶體中的切片,而一個獨立的重新切片(resharding)步驟,讓你在復原時能重新載入到不同的平行配置上。

\tau^{*} = \sqrt{2\,C\,\mathrm{MTBF}}

把成本收益旋鈕量化:Young 的最佳檢查點間隔在寫入開銷 C 與崩潰丟失的計算之間權衡,決定保存的頻率。

容錯與彈性訓練

存檢查點再重啟是基準線,但為了一個死掉的節點而重啟整份工作,浪費了其他每一張健康 GPU 的時間。容錯訓練做得更好:它偵測故障、驅逐或替換壞節點、重建通訊群組,並從上一個檢查點復原——彈性地,往往不必整份工作拆掉重來。這裡的前沿是把遺失的工作逼近零:狀態在記憶體中的冗餘複本,讓倖存者不必碰儲存就能替替補節點重新播種;以及讓訓練在備援容量回來前先以縮減規模繼續的重新配置。從復原時間省下的每一分鐘,都是加進有效產出的一分鐘。

  1. 偵測:一次健康檢查或一個卡住的集體運算,在數秒內標記出故障的 rank。
  2. 隔離:排空壞節點,向排程器從備援池要一個替補。
  3. 重新配置:為新的成員組成重建 NCCL 通訊群組。
  4. 復原:每個 rank 從分散式檢查點平行重新載入它的切片。
  5. 續訓:繼續訓練;理想上只損失上一個檢查點以來的那幾步。

異質加速器與前方的路

真實的機隊並不均勻。一座資料中心會累積數個世代的 GPU,再加上 TPU 與自訂 ASIC,而我們愈來愈想把它們一起用。異質加速器的訓練與服務,必須應付速度、記憶體容量、甚至數值行為都不同的裝置。這打破了均衡資料平行那個舒適的假設:較慢的裝置會變成拖累每個集體運算的落後者(straggler),所以工作必須不均勻地切分以匹配每個裝置的吞吐量,而像 XLA 這樣的抽象,正因能從一支程式瞄準天差地別的後端而值回票價。