Accelerate ND-Parallel: 効率的なマルチGPU訓練ガイド
Hugging FaceはAccelerateとAxolotlにND-Parallelismを導入し、データ並列(DP)、完全分割データ並列(FSDP)、テンソル並列(TP)、コンテキスト並列(CP)といった複数の並列戦略を単一のトレーニングスクリプト内で組み合わせるシンプルな方法を提供します。この統合により、開発者は数十億から数百億パラメータ規模のモデルをマルチノードGPUクラスターで訓練する際、メモリ使用量と通信オーバーヘッドのトレードオフを最適化できます。
コア並列戦略
データ並列 (DP)
データ並列はモデル全体、勾配、オプティマイザの状態をすべてのデバイスに複製します。各デバイスは異なるサブバッチのデータを処理し、パラメータ更新前に全デバイス間で勾配を同期します。これによりスループットが向上しますが、モデル全体が単一GPUに収まる必要があります。
完全分割データ並列 (FSDP)
FSDPはモデルの重み、勾配、オプティマイザ状態をGPU間で分割し、デバイスごとのメモリフットプリントを削減します。順伝搬や逆伝搬を行う際、FSDPは特定の層(通常はトランスフォーマーデコーダーブロック)に必要な重みを集め、処理後に再度分割します。これにより、通信オーバーヘッドは増加しますが、ピークメモリ使用量は大幅に低減されます。
テンソル並列 (TP)
テンソル並列は大規模な線形層(フィードフォワード層や注意投影など)をデバイス間で分割します。FSDPの動的分割とは異なり、TPは静的なメモリパーティションを作成します。TPは頻繁な活性化同期が必要なため、NVLinkなどの高帯域幅リンクを使用する単一ノード内で最も効果的であり、PCIe接続のGPUには推奨されません。
コンテキスト並列 (CP)
コンテキスト並列は入力シーケンスをGPU間で分割し、注意機構の二次的なスケーリングによりGPUメモリを超えてしまう極長シーケンスを処理可能にします。RingAttentionを使用し、各GPUはクエリ、キー、バリュー行列の一部を保持し、キーとバリューのシャードをGPUリング上で循環させます。これにより、各クエリはシーケンス全体に対する注意スコアを計算しつつ、計算とメモリ負荷を分散します。
ND-Parallelism: マルチノードスケーリングのための戦略構成
マルチノード訓練はしばしばノード間レイテンシやメモリ制約がボトルネックになります。ND-Parallelismはクラスターを多次元トポロジとして扱い、通信を最適化します。
ハイブリッド分割データ並列 (HSDP)
HSDPは2次元並列アプローチで、ノード内ではFSDP(高速なノード内リンクを利用)を、ノード間ではDPを行います。これにより、遅いノード間通信は勾配同期の1ステップに最小化され、純粋なFSDPに比べてメモリ使用量は増加しますが、スループットが向上します。
FSDP + テンソル並列
FSDPとTPを組み合わせると、ノード間でFSDPによりモデルを分割し、ノード内でTPにより層を分割します。これによりFSDPのレイテンシが低減され、単一デバイスでは収まりきらない大規模層の訓練が可能になり、グローバルバッチサイズの削減も実現します。
FSDP + コンテキスト並列
この2次元戦略は、非常に長いシーケンス長での訓練時に使用されます。CPはすでにFSDPと統合されていますが、CP上にFSDPを追加することで、モデルの重みとオプティマイザ状態に必要なメモリ予算をさらに削減します。
ハイブリッド分割データ並列 + テンソル並列
この3次元階層は、DPでノードグループ間にモデルを複製し、各グループ内でFSDPによりモデルを分割し、各ノード内でTPにより層を分割します。この構成はハードウェアやスケーリング制約に合わせた最大の柔軟性を提供します。
実装と使用上の注意点
Accelerate と Axolotl の設定
ユーザーはAccelerate の ParallelismConfig クラスや Axolotl の特定設定フィールドを通じてこれらの戦略を構成できます:
dp_shard_size: FSDP の分割度合いdp_replicate_size: DP の複製度合いtp_size/tensor_parallel_size: TP の度合いcp_size/context_parallel_size: CP の度合い
メモリと安定性の最適化
- CPU RAM Efficient Loading: 単一デバイスに収まらない大規模モデルの場合、
cpu_ram_efficient_loadingとSHARDED_STATE_DICTをFullyShardedDataParallelPluginで有効にすることが重要です。 - Effective Batch Size: 有効バッチサイズは
micro_batch_size * gradient_accumulation_steps * dp_world_sizeと計算され、dp_world_size = (dp_shard_size * dp_replicate_size) / tp_sizeです。 - Learning Rate Scaling: 有効バッチサイズが増加すると、学習率は線形または平方根スケーリングで調整し、安定性を保つべきです。
- Gradient Checkpointing: 逆伝搬時に中間活性化を再計算することで計算コストとメモリ使用量のトレードオフを行います。これにより活性化メモリを 60-80% 削減できる一方、訓練時間は約 20-30% 増加します。