書籍の110ページに登場する「層正規化(LayerNorm)」と、一般の画像処理などで広く使われる「バッチ正規化(BatchNorm)」の計算方向の違い、および**「なぜLLM(GPTなど)ではバッチ正規化が一切使われないのか」**について、グラフィカルに図解します。
ニューラルネットワークの中間層で、データ(テンソル)の数値範囲を**「平均0・分散1」に綺麗に揃える(整頓する)処理**のことです。
各レイヤーのパラメータ(重み)が学習によって更新されると、後続のレイヤーに伝わるデータの分布が毎回大きく変動してしまいます(内部共変量シフト)。これにより学習が非常に不安定になり、速度が落ちます。正規化を行うことで、データの分布の暴れを抑え込み、学習を安定・高速化させます。
バッチサイズが
バッチ正規化 (BatchNorm) の集計イメージ
(縦方向=バッチ全体で平均・分散を求める)
特徴量チャネル1 特徴量チャネル2 特徴量チャネル3
サンプル1 (A君): [ 1.0, 10.0, -2.0 ]
サンプル2 (B君): [ 3.0, 20.0, 0.0 ]
サンプル3 (C君): [ 5.0, 30.0, 2.0 ]
│ │ │
集計の向き ───> ▼ ▼ ▼
[平均:3.0] [平均:20.0] [平均:0.0]
[分散:1.6] [分散:66.6] [分散:1.6]
- 直感的な例え(テストの偏差値): 「クラス全員(バッチ全体)」を対象に、「国語」という科目(特定のチャネル)単体の平均点と標準偏差を計算し、生徒全員の国語の点数を偏差値化(標準化)するようなものです。
バッチ内の各「データサンプル
層正規化 (LayerNorm) の集計イメージ
(横方向=サンプル単体で自己完結して平均・分散を求める)
特徴量チャネル1 特徴量チャネル2 特徴量チャネル3 ───> 集計の向き
サンプル1 (A君): [ 1.0, 10.0, -2.0 ] ──> [平均: 3.0, 分散: 26.0]
サンプル2 (B君): [ 3.0, 20.0, 0.0 ] ──> [平均: 7.7, 分散: 77.5]
サンプル3 (C君): [ 5.0, 30.0, 2.0 ] ──> [平均:12.3, 分散:157.5]
- 直感的な例え(テストの偏差値): 「生徒A君」単体の成績表を見て、A君の「国語・数学・英語・理科・社会」の平均点とばらつきを求め、A君の中で各科目の偏差値(自己偏差値)を計算するようなものです。クラスの他の生徒(B君やC君)が何点を取ろうが、A君の成績評価には一切影響しません。
LLMのアーキテクチャ(Transformer)において、バッチ正規化が一切使われないのには、決定的な3つの理由があります。
- BatchNormの弱点: バッチ全体から統計量を計算するため、バッチサイズが極端に小さい(例:メモリ制約でバッチサイズ1や2で学習する、またはWebサービスでユーザーからのリクエストを1件ずつ推論する)と、平均や分散が正しく計算できず、動作が壊れて精度が著しく低下します。
- LayerNormの強み:
他のサンプルのデータを見ず、目の前にあるサンプル単体の中で完結して計算するため、バッチサイズが
1であろうが1000であろうが、推論される数値が寸分違わず完全に一致し、抜群の安定性を誇ります。
- BatchNormの弱点: LLMでは入力される文章の長さ(トークン数)が毎回変わります。BatchNormは「単語の並び位置(タイムステップ)」ごとにバッチ全体を集計しようとしますが、長さがバラバラだと縦方向の対応が取れず、計算が破綻してしまいます。
- LayerNormの強み: 各単語の「埋め込み次元(768次元など)」という横方向の軸の中で完結して計算するため、文章全体の長さがどれだけ変化しても影響を全く受けません。
- BatchNormの弱点: 超巨大なLLMを複数のGPUに分散して学習させる際、BatchNormを使うとGPU間でデータを通信し、「全GPUを合わせたバッチ全体の平均と分散」を計算・同期する大きな待ち時間(オーバーヘッド)が発生します。
- LayerNormの強み: 各サンプルが自己完結して独立して計算できるため、GPU間の同期通信が一切不要になり、並列学習スピードが劇的に向上します。
- バッチ依存性の実証コード: batch_vs_layer_norm_demo.py (実際にバッチサイズを変更した際に、BatchNormの出力が他者依存で変化してしまうのに対し、LayerNormの出力は完全に安定して一致することを示すデモプログラムです)