Hugging Face Accelerate:協調 DeepSpeed 與 FSDP 精度

精度差異與收斂

DeepSpeed 與 FSDP 在參數精度的處理方式不同,可能導致訓練結果出現分歧。在使用 bfloat16 載入 Mistral-7B 基礎模型的測試中,DeepSpeed 能夠穩定收斂,而 FSDP 除非手動將學習率按 GPU 數量放大或降低至 1e-5,否則無法降低損失。

此行為歸因於內部的升級(upcasting)。DeepSpeed 的 DeepSpeedZeroOptimizer_Stage3 會透過 _create_fp32_partitions 自動將可訓練參數組升級至 float32,並以完整精度保存主權重,這使得優化器能在較低精度下不穩定的學習率下仍能收斂。

精度工作流程比較

DeepSpeed 與 FSDP 在管理「展平」參數與優化器初始化方面根本不同:

流程 FSDP DeepSpeed
準備 使用 torch_dtype 忽略 torch_dtype;以 float32 建立
優化器初始化 torch_dtype 中建立參數 float32 中建立參數
優化器(預步驟) 如有升級則升至 torch_dtype 將所有內容升級至 float32
優化器(實際步驟) torch_dtype 中執行 float32 中執行

雖然 DeepSpeed 的原生升級確保了收斂,但會使記憶體消耗增加 2 倍,這在使用少量 GPU 訓練時相當顯著。相對地,torch 原生的 FSDP 實作不強制升級,提供了在記憶體受限情境下的更大彈性,允許優化器在低精度下運作。

Accelerate 0.30.0 中的新 FSDP 模式

為了協調這兩個框架,Hugging Face Accelerate 現在支援兩種不同的 FSDP 模式,以符合使用者在收斂穩定性與記憶體效率之間的優先考量:

  1. 混合精度模式:在準備與優化器步驟期間將參數升級至 fp32,與 DeepSpeed 保持一致,同時在訓練時使用 bf16
  2. 記憶體受限模式:在準備、訓練與優化器步驟全程使用低精度 (bf16)。

框架比較表

框架 模型載入 混合精度 準備 訓練 優化器
FSDP(記憶體受限) bf16 bf16 bf16 bf16
FSDP(混合精度) bf16 bf16 fp32 bf16 fp32
DeepSpeed bf16 bf16 fp32 bf16 fp32

吞吐量表現

在四張 A100 GPU 上使用 IBM Granite 7B 模型進行基準測試,顯示 FSDP(對齊模式)與 DeepSpeed(Zero3)提供了幾乎相同的吞吐量表現:

框架 每設備每秒標記數 步驟時間(秒) 模型 FLOPs 利用率(MFU)
FSDP(對齊) 3158.7 10.4 0.41
DeepSpeed 3094.5 10.6 0.40

遷移與設定

Hugging Face 已發布一份概念指南以協助使用者在 FSDP 與 DeepSpeed 之間遷移。切換主要透過 Accelerate 設定檔或 DeepSpeedFSDP 插件類別來處理。遷移時的主要考量包括:

  • 分片策略:在各框架間達成等效的分片。
  • 模型載入:實作高效的載入模式。
  • 權重預取:管理權重在 GPU 之間的搬移方式。
  • 檢查點:處理各框架在保存與載入模型狀態上的差異。

Sources