AI・機械学習
中級

データ並列(データヘイレツ)

分散学習の最も基本的な手法。モデル全体を各GPUに複製し、学習データのミニバッチを各GPUに分配して並列に前方伝播・後方伝播を実行する。各GPUで計算した勾配をAllReduceで集約・平均してパラメータを同期更新する。

0 回閲覧
0 いいね

データ並列とは

データ並列(Data Parallelism, DP)は、分散学習の中で最も基本的かつ広く使われる手法である。モデルの完全なコピーを各GPU(ワーカー)に配置し、学習データセットをワーカー間で分割して並列に学習を行う。各ワーカーが計算した勾配をAllReduceで集約・平均し、全ワーカーのモデルパラメータを同期的に更新する。

データ並列の基本動作

  1. モデル複製: 全GPUに同一のモデルパラメータを配置
  2. データ分割: ミニバッチをGPU数で均等に分割(例: バッチサイズ256を8GPUで32ずつ)
  3. Forward Pass: 各GPUが独立に前方伝播を実行
  4. Backward Pass: 各GPUが独立に後方伝播を実行し、ローカル勾配を算出
  5. AllReduce: 全GPUの勾配を集約して平均を取る
  6. パラメータ更新: 全GPUが同一の勾配平均でパラメータを更新(同期が保たれる)

PyTorch DDP(DistributedDataParallel)

PyTorchの標準データ並列実装であるDDPは以下の最適化を行う。

機能説明デフォルト値
勾配バケット化小さな勾配テンソルをバケットにまとめてAllReduce25MB
計算-通信オーバーラップbackward計算と並行して勾配をAllReduce有効
未使用パラメータ検出forward未使用のパラメータの勾配をスキップFalse
勾配累積N回のforward/backwardを勾配累積してからAllReduce1
バックエンド通信バックエンド選択nccl (GPU)
# PyTorch DDPの基本的な使い方(概念例)
# model = DistributedDataParallel(model, device_ids=[local_rank])
# optimizer.zero_grad()
# loss = model(input).sum()
# loss.backward()  # AllReduceは自動実行
# optimizer.step()

ZeRO(Zero Redundancy Optimizer)

MicrosoftのDeepSpeedが提唱したZeROは、データ並列の冗長性を排除してメモリ効率を大幅に改善する。

ステージ分割対象メモリ削減通信量
ZeRO-1オプティマイザ状態4倍DDP同等
ZeRO-2+ 勾配8倍DDP同等
ZeRO-3+ パラメータNリニア1.5倍増
ZeRO-Infinity+ CPUオフロードほぼ無制限大幅増

ZeRO-3では7Bモデル(FP16で14GB)の学習が、8GPUならGPUあたり約1.75GB+αのパラメータメモリで済む。オプティマイザ状態(Adamで約56GB)も8分割で7GB/GPUとなる。

PyTorch FSDP(Fully Sharded Data Parallel)

MetaのFSDPはZeROの概念をPyTorchネイティブに実装したものである。

  • シャーディング戦略: FULL_SHARD(ZeRO-3相当)、SHARD_GRAD_OP(ZeRO-2相当)、NO_SHARD(DDP相当)
  • Mixed Precision: BF16/FP16での学習をネイティブサポート
  • アクティベーションチェックポイント: checkpoint_wrapperで再計算を自動適用
  • Transformer自動ラップ: transformer_auto_wrap_policyでTransformerブロック単位に自動シャーディング
  • PyTorch 2.0+統合: torch.compileとの互換性が改善

データ並列のスケーリング

GPU数グローバルバッチサイズ学習率スケーリング効率(理想1.0)
1321e-41.0(基準)
82568e-40.95-0.98
642,0486.4e-30.90-0.95
2568,1922.56e-20.85-0.92
1,02432,768ウォームアップ必須0.75-0.85

大規模バッチでは学習率のスケーリングが重要。線形スケーリングルール(GPU数に比例して学習率を上げる)やLARS/LAMBオプティマイザを使用する。

データ並列の課題と対策

  • 通信ボトルネック: GPU数が増えるとAllReduceの通信量が学習時間に影響。対策: 勾配圧縮、FP8通信、計算-通信オーバーラップ
  • 大バッチ汎化問題: バッチサイズが大きすぎると汎化性能が低下。対策: ウォームアップ、学習率スケジューリング、LAMB
  • メモリ冗長: 標準DDPでは全GPUにモデル全体を複製するためメモリが無駄。対策: ZeRO/FSDP
  • 同期バリア: 最も遅いGPUに全体が律速される(ストラグラー問題)。対策: 非同期SGD、バックアップワーカー

2025-2026年の最新動向

  • DiLoCo: Google DeepMindが提唱した「低通信分散学習」。数百ステップごとに外側ループで同期し、内側ループは各ワーカーが独立に学習。通信量を100倍以上削減
  • FP8データ並列: H100のFP8演算とFP8通信を活用し、学習速度と通信効率を同時に改善
  • Asynchronous DDP: 同期バリアを排除した非同期勾配更新。収束の安定性は課題だが、異種GPU混在環境で有効
  • FSDP2(PyTorch 2.4+): FSDPの第2世代。DTensor統合、per-parameter sharding、より細かい制御が可能

よくある質問(FAQ)

Q1: データ並列とDDP(DistributedDataParallel)の違いは? A: データ並列は概念・手法の名称。DDPはPyTorchにおけるデータ並列の実装。旧式のDataParallel(DP)はGILボトルネックで非推奨。DDPはプロセスベースでGPU間のAllReduceを効率的に行う。

Q2: ZeRO-3とFSDPはどちらを使うべきですか? A: PyTorchエコシステムに統一したいならFSDPが推奨。DeepSpeed固有機能(ZeRO-Infinity、1-bit Adam、勾配圧縮)が必要ならZeRO-3。性能はほぼ同等だが、FSDPはPyTorch公式でありtorch.compileとの統合が優れている。

Q3: データ並列だけで大規模モデルを学習できますか? A: ZeRO-3/FSDPを使えば数十億パラメータまでは可能。70Bモデルを64台のH100(ZeRO-3)で学習した実績がある。ただし405B以上ではテンソル並列・パイプライン並列との組み合わせ(3D並列)が必須。

まとめ

  • データ並列は分散学習の基本で、モデル複製+データ分割+勾配AllReduceで動作
  • PyTorch DDPが標準実装、ZeRO/FSDPがメモリ効率を大幅改善
  • ZeRO-3/FSDPでGPUあたりのメモリ使用量をN分の1に削減可能
  • 大バッチ学習では学習率スケーリングとウォームアップが重要
  • DiLoCoなどの低通信手法が2025-2026年の注目トレンド