ウォームアップスケジューラ(ウォームアップスケジューラ)
学習初期にごく小さな学習率から開始し、指定ステップ数にわたって線形または指数的にピーク学習率まで上昇させるスケジューリング手法。ランダム初期化直後の不安定な勾配による loss spike や発散を防ぐ目的で、LLM 訓練では事実上必須のテクニックとなっている。
ウォームアップスケジューラとは
ウォームアップ(Warmup)は、モデル訓練の最初期にごく小さな学習率からスタートし、段階的にピーク学習率まで引き上げるスケジューリング手法である。Vaswani et al.(2017)の「Attention Is All You Need」論文で Transformer アーキテクチャとともに導入され、以降 BERT・GPT・Llama などすべての主要 LLM 訓練で採用されている。
訓練開始直後のモデルパラメータはランダム初期化状態にあり、勾配の分散が極めて大きい。この状態で高い学習率を適用すると、パラメータが急激に更新されて損失が発散(NaN)したり、急上昇(loss spike)したりする。ウォームアップはこの問題を回避し、オプティマイザの適応的統計量(Adam の一次・二次モーメント推定)が安定するまでの猶予期間を提供する。
ウォームアップの種類
| 種類 | 数式 | 特徴 | 主な用途 |
|---|---|---|---|
| Linear Warmup | η(t) = η_max × (t / T_warmup) | 最も標準的。Llama 3 採用 | LLM 事前学習 |
| Exponential Warmup | η(t) = η_max × (1 - e^(-t/τ)) | 初期の上昇が緩やか | 大バッチ訓練 |
| Gradual Warmup | η(t) = η_max × min(1, t/T_warmup) | Linear と同義、Goyal et al. 提案 | ResNet 大バッチ |
| Inverse Sqrt Warmup | η(t) = η_max × min(t^(-0.5), t × T^(-1.5)) | Attention Is All You Need | 初期 Transformer |
| Constant Warmup | η(t) = η_const (t < T) → η_max | 段差あり、あまり推奨されない | レガシー実装 |
ウォームアップが必要な理由
Adam オプティマイザの初期バイアス
Adam は勾配の一次モーメント m と二次モーメント v の指数移動平均を追跡する。訓練開始時にはこれらがゼロ初期化されているため、バイアス補正を行っても推定精度が低い。ウォームアップ期間中に低い学習率で m, v の推定を安定させることで、本格的な学習フェーズでの更新品質を担保する。
大バッチ訓練との関係
LLM 訓練ではバッチサイズが数百万トークンに達する。Goyal et al.(2017)は「大バッチ訓練ではウォームアップが必須」という知見を示し、バッチサイズに比例して学習率を上げる Linear Scaling Rule とウォームアップの組み合わせを提案した。この手法は現在の LLM 訓練の基盤になっている。
Loss Spike の防止
Llama 2 の技術レポートでは、訓練中に発生する loss spike について詳述されている。ウォームアップが不十分だと訓練最初期に spike が発生し、以降の訓練が不安定化する。Meta は Llama 3 で 2,000 ステップのウォームアップを採用し、この問題を回避した。
実モデルでのウォームアップ設定
| モデル | ウォームアップ方式 | ステップ数 | 全体比率 | ピーク学習率 |
|---|---|---|---|---|
| Llama 3 8B/70B | Linear | 2,000 | 0.05% | 3×10⁻⁴ / 1.5×10⁻⁴ |
| Mistral 7B | Linear | 1,000 | 非公開 | 3×10⁻⁴ |
| BERT Base | Linear | 10,000 | 1% | 1×10⁻⁴ |
| GPT-3 175B | Linear | 375M tokens | 0.12% | 6×10⁻⁵ |
| T5 11B | Inverse Sqrt | 10,000 | 0.9% | 1×10⁻² |
| Gemma 2 | Linear | 非公開 | 非公開 | 3×10⁻⁴ |
PyTorch での実装
from torch.optim.lr_scheduler import LinearLR, LambdaLR
# 方法 1: LinearLR(PyTorch 2.x 推奨)
warmup_scheduler = LinearLR(
optimizer,
start_factor=1e-7 / 3e-4, # 初期倍率
end_factor=1.0, # ピークで 1.0
total_iters=2000 # ウォームアップステップ数
)
# 方法 2: LambdaLR(柔軟なカスタム)
def warmup_lambda(step):
if step < 2000:
return step / 2000 # 線形増加
return 1.0
warmup_scheduler = LambdaLR(optimizer, lr_lambda=warmup_lambda)
Hugging Face での指定
from transformers import get_scheduler
scheduler = get_scheduler(
"cosine", # ウォームアップ後のスケジューラ
optimizer=optimizer,
num_warmup_steps=2000, # ウォームアップステップ数
num_training_steps=100000, # 総ステップ数
)
ウォームアップステップ数の決定ガイドライン
- 事前学習: 全体の 0.05〜2%。Llama 3 は 0.05%、BERT は 1%
- ファインチューニング: 全体の 3〜10%。100〜500 ステップが典型
- LoRA/QLoRA: 全体の 3〜6%。アダプタパラメータが少ないため安定しやすい
- バッチサイズが大きいほど: ウォームアップを長めに。4M tokens バッチなら 2,000 steps 以上推奨
FAQ
Q1: ウォームアップなしで訓練を始めるとどうなる?
小規模モデル(数億パラメータ以下)ではウォームアップなしでも訓練が進行するケースがある。しかし LLM スケール(数十億以上)では、訓練最初期に loss spike や NaN が発生する確率が高まる。Google Brain の内部実験では、7B パラメータモデルでウォームアップなしの場合、10 回中 3 回で訓練が最初の 100 ステップ以内に発散した。
Q2: ウォームアップが長すぎると何が問題?
ウォームアップ期間中は学習率がピーク以下であるため、有効な学習が行われる時間が短くなる。全体の 5% を超えるウォームアップは一般的に長すぎるとされる。ただし、非常に大きなバッチサイズや不安定なデータセットでは例外的に長いウォームアップが有効な場合がある。
Q3: ファインチューニングでもウォームアップは必要?
事前学習済みモデルのファインチューニングでは、パラメータが既に良好な状態にあるためウォームアップの重要性は低い。ただし、学習率が比較的高い場合(1×10⁻⁴ 以上)や、LoRA ランクが大きい場合は短いウォームアップ(100〜300 ステップ)を入れることで安定性が向上する。