グラデーション累積(グラデーションルイセキ)
LLM学習において小さいミニバッチを複数回フォワード・バックワードし、勾配を蓄積してから一括更新する手法。GPUメモリ制約下で実質的に大きいバッチサイズを実現する。
グラデーション累積(Gradient Accumulation)とは
LLM(大規模言語モデル)の学習において、1回のパラメータ更新に必要な勾配を複数のミニバッチから蓄積(累積)してから適用する手法。VRAMが限られた環境で大きな実効バッチサイズを実現するための標準的アプローチ。
基本原理
通常の学習ループでは「1ミニバッチ → 損失計算 → 逆伝播 → パラメータ更新」を繰り返す。グラデーション累積ではこれを以下に変更する。
# accumulation_steps = 4 の例
for step, batch in enumerate(dataloader):
loss = model(batch) / accumulation_steps # スケーリング
loss.backward() # 勾配は累積される(zero_grad未実行)
if (step + 1) % accumulation_steps == 0:
optimizer.step() # N回分の勾配を一括適用
optimizer.zero_grad()
実効バッチサイズ = micro_batch_size × accumulation_steps × num_gpus。
LLM学習での重要性
スケール問題: Llama-3 70Bなどの大規模モデルでは、bf16精度でも1サンプルが数GB消費する。A100 80GB 1枚ではmicro_batch_size=1が限界のケースも多い。
バッチサイズの影響: 学習の安定性、収束速度、最終精度はバッチサイズに敏感。Google Deepmindの研究では、LLMはバッチサイズ100万トークン前後が効率的とされる。グラデーション累積でこのスケールに到達できる。
コスト:
- メリット: VRAMを増やさず実効バッチ増加
- デメリット: フォワード・バックワードをN回実行するためスループットは低下。累積ステップ数に概ね比例して壁時計時間が増加する
実装上の注意点
損失のスケーリング: loss / accumulation_stepsでスケーリングしないと、累積後の勾配ノルムがN倍になり学習が発散する。PyTorch標準の.backward()は勾配を加算するため必須の操作。
Gradient Clipping: optimizer.step()前にtorch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)を呼ぶことで大きな勾配を制御し学習安定化。
混合精度との組み合わせ: bf16学習+AMP(自動混合精度)と組み合わせるのが2025年の標準。
フレームワークサポート
Hugging Face Accelerate: accumulate(model) コンテキストマネージャで自動管理。マルチGPU環境でも正しく同期される。
DeepSpeed: ZeRO最適化と組み合わせて自動適用。gradient_accumulation_stepsをconfigに指定するだけ。
Megatron-LM: パイプライン並列+グラデーション累積を同時使用し、NVIDIA超大規模クラスタでのLLM学習を実現。
推奨設定(2025年実践値)
A100 80GBで7B規模: micro_batch=4、accum_steps=4、実効batch=16。 A100 80GBで70B規模: micro_batch=1、accum_steps=16、実効batch=16。 H100 80GBで7B規模: micro_batch=8、accum_steps=2、実効batch=16。 H100 80GBで70B規模: micro_batch=2、accum_steps=8、実効batch=16。
まとめ
グラデーション累積はLLM学習の基礎テクニックであり、VRAM不足を補いながら大きな実効バッチサイズを実現する。追加コストはフォワード・バックワードのN回実行のみ。DeepSpeed/Accelerateの標準機能として透過的に利用できるため、ほぼすべてのLLMファインチューニング・事前学習パイプラインで採用されている。