一文要約:LayerNorm は各 token のベクトルを安定したスケールへ戻し、学習可能な
γとβで再調整します。Softmax は一組のスコアを、合計 100% の確率分布に変えます。
6.1 なぜこの 2 つの道具が重要なのか
Transformer ブロックは掛け算と足し算を何度も繰り返します。ネットワークが深くなると活性化のスケールがばらつき、最適化が難しくなります。極端な場合には数値のオーバーフローや弱い勾配信号にもつながります。
これを抑えるのに役立つ、軽量な操作が 2 つあります。
- LayerNorm(または近縁の RMSNorm)はサブレイヤーの周辺に置かれ、活性化のスケールを扱いやすくします。
- Softmax は Attention の内部に登場します。モデル出力では、推論時に確率やサンプリングが必要なときに使います。
どちらも複雑ではありません。それでも、安定した学習と有用な推論に大切な役割を持ちます。
6.2 LayerNorm:スケールを妥当に保つ
6.2.1 問題:数値はドリフトする
ニューラルネットワークのレイヤーは掛け算と足し算を繰り返します。その結果、レイヤーごとの数値が大きく異なるスケールで動くことがあります。
大きすぎる: 10,000 100,000 → 最適化が不安定、場合によってはオーバーフロー
小さすぎる: 0.0001 0.00001 → 有用な変化や勾配を捉えにくい
正規化は、これらの値を予測しやすいスケールへ戻し、最適化を安定させます。
6.2.2 LayerNorm が行うこと
Layer Normalization は、1 つのトークンベクトル内の特徴値を正規化します。各トークンに対して以下を行います。
d_model次元すべての平均を計算する- 分散を計算する
- 平均を引き、標準偏差で割る
- 学習可能なスケール
γとシフトβを適用する
数式:
y = (x - μ) / √(σ² + ε) × γ + β
分解すると:
x - μ:平均を引き、結果をゼロ中心にする/ √(σ² + ε):標準偏差で割り、広がりをおよそ 1 にする。実装ごとに決まる小さなεはゼロ除算を防ぐ× γ + β:学習可能なスケールとバイアスを適用する。これにより、別の出力レンジが有用だとモデルが判断したときにそれを選べる。γとβは1と0から始まり、学習中に更新される
厳密には、平均 0、分散 1 は γ と β を適用する前の標準化結果を表します。最終出力もその統計量を保つのは、γ = 1、β = 0 のときです。
6.2.3 計算例
あるトークンの 4 次元の活性化ベクトルが [22, 5, 6, 8] だとします。
ステップ 1:平均を計算
μ = (22 + 5 + 6 + 8) / 4 = 41 / 4 = 10.25
ステップ 2:分散を計算
σ² = ((22 - 10.25)² + (5 - 10.25)² + (6 - 10.25)² + (8 - 10.25)²) / 4
= (138.06 + 27.56 + 18.06 + 5.06) / 4
= 47.19
ステップ 3:正規化
dim0: (22 - 10.25) / √47.19 = 11.75 / 6.87 ≈ 1.71
dim1: ( 5 - 10.25) / √47.19 = -5.25 / 6.87 ≈ -0.76
dim2: ( 6 - 10.25) / √47.19 = -4.25 / 6.87 ≈ -0.62
dim3: ( 8 - 10.25) / √47.19 = -2.25 / 6.87 ≈ -0.33
γ = 1、β = 0 とすると、結果は [1.71, -0.76, -0.62, -0.33]。平均 ≈ 0、分散 ≈ 1 です。
6.2.4 PyTorch 実装
import torch
import torch.nn as nn
layer_norm = nn.LayerNorm(normalized_shape=4, bias=True)
x = torch.tensor([[22.0, 5.0, 6.0, 8.0]])
y = layer_norm(x)
print(y) # おおよそ [1.71, -0.76, -0.62, -0.33]
nn.LayerNorm が上の数式を扱ってくれます。normalized_shape はどの次元で正規化するかを指定します。実際の Transformer では、この次元は d_model です。
6.2.5 なぜ「Layer」ノルムなのか
正規化はトークンごとに、特徴(レイヤー)次元にわたって適用されます——バッチ次元ではありません。各トークンのベクトルは独立に正規化され、異なるトークンは互いの統計量に干渉しません。
これは Batch Normalization とは対照的です。Batch Norm は複数のサンプル(タスクによっては空間・位置次元も含む)の統計量を使います。LayerNorm は同じ batch 内の他のサンプルに依存しないため、可変長シーケンスに自然に使えます。
6.2.6 LayerNorm が現れる場所
標準的な decoder-only Block では、通常 2 つのサブレイヤーの周辺で正規化します。
Input
↓
LayerNorm <- 1 回目
↓
Masked Multi-Head Attention
↓
残差接続
↓
LayerNorm <- 2 回目
↓
Feed Forward Network (FFN)
↓
残差接続
↓
Output
オリジナル Transformer の encoder には 2 つのサブレイヤーがあり、decoder には cross-attention もあるため 3 つありました。配置は、各サブレイヤーと残差加算の後に LayerNorm を置く post-norm です。GPT-2 は LayerNorm を各サブブロックの入力へ移し、最後にも norm を追加しました。これが後の decoder-only LLM でよく使われる pre-norm の流れです。
Llama 2 など、多くの現代 LLM は代わりに RMSNorm を使います。「スケールを整える」という直感は同じですが、平均は引かず、通常 β もありません。LayerNorm の近縁ですが、同じ演算ではありません。
6.3 Softmax:スコアを確率に変える
6.3.1 問題:確率が必要
Transformer で確率分布を必要とする場所は 2 つあります。
- Attention の中:スケーリングと mask を適用した Query–Key スコアから、合計が 1 になる重みを作る
- 最終出力:最後の隠れ状態を語彙に射影したあと、すべての候補次トークンに対する分布が必要
確率には 2 つの要件があります。各値が 0 から 1 の間であること、そしてすべての値の合計が厳密に 1 であること。行列積の素のスコアはどちらも満たしません。
6.3.2 Softmax が行うこと
Softmax は、任意の実数ベクトルを妥当な確率分布に変換します。
語彙出力を例にとってみます——4 つの候補次トークンに対するモデルの素のスコア(ロジット)です。
入力ロジット:request = 3.01, tab = 0.09, quote = 2.48, other = 1.95
出力確率:request = 50.28%, tab = 2.71%, quote = 29.59%, other = 17.42%
Softmax のあと:
- 各値は 0 から 1 の間
- 合計は 100%
6.3.3 Softmax の数式
言葉にすると:
e ≈ 2.718を各スコアの指数にする- 各結果をすべての結果の合計で割る
コンピュータでは通常、まず最大の logit を引きます:softmax(z) = softmax(z - max(z))。確率は変わらず、大きな e^z のオーバーフローを防げます。
6.3.4 計算例
入力ロジット:[3.01, 0.09, 2.48, 1.95]
ステップ 1:指数化
e^3.01 = 20.29
e^0.09 = 1.09
e^2.48 = 11.94
e^1.95 = 7.03
ステップ 2:合計
total = 20.29 + 1.09 + 11.94 + 7.03 = 40.35
ステップ 3:割る
request: 20.29 / 40.35 = 0.5028 = 50.28%
tab: 1.09 / 40.35 = 0.0271 = 2.71%
quote: 11.94 / 40.35 = 0.2959 = 29.59%
other: 7.03 / 40.35 = 0.1742 = 17.42%
6.3.5 知っておきたい 3 つの性質
1. スコア差を確率比へ変える:P(i) / P(j) = e^(z_i-z_j)。最大 logit が支配的になるのは、そのリードが十分大きいときです。
2. 順序を保つ:ロジット A > ロジット B なら、P(A) > P(B)。最高スコアは最高確率のままです。
3. 負の入力を扱える:指数化は常に正の数を返す(任意の x で e^x > 0)ので、負のロジットからも妥当な確率が得られます。
6.3.6 PyTorch 実装
import torch
import torch.nn.functional as F
logits = torch.tensor([3.01, 0.09, 2.48, 1.95])
probs = F.softmax(logits, dim=0)
print(probs) # tensor([0.5028, 0.0271, 0.2959, 0.1742])
print(probs.sum()) # tensor(1.0000)
6.4 アーキテクチャ内での位置
6.4.1 完全な出力フロー
最後の Transformer ブロックから次トークン予測まで:
Transformer ブロック出力
↓
最終 Norm
↓
線形射影 (d_model → vocab_size)
↓
ロジット
├─ 学習:CrossEntropyLoss(logits, target)
├─ greedy decoding:argmax(logits)
└─ サンプリング:Softmax(logits / T) のあと抽選
線形射影は最終隠れ状態を d_model 次元から vocab_size 次元へ写します。仮に d_model = 4096、vocab_size = 100,000 なら、行列には 4096 × 100,000 = 4.096 億 個の要素があります。よく LM Head と呼ばれます。入力 embedding と重みを共有するモデルもあるため、これが常に追加のパラメータとは限りません。
6.4.2 2 つがどう協働するか
LayerNorm と Softmax は別々の場所で別々の仕事をしますが、協働します。
- LayerNorm はサブ層間の活性化を安定化し、次の計算で扱いやすいスケールに保つ
- すべての Block のあと、多くの pre-norm decoder は最終隠れ状態を LayerNorm または RMSNorm に通し、それから LM Head へ送る
- 学習時の cross-entropy は通常 logits を直接受け取り、数値的に安定した log-softmax を内部で計算する。推論時は、確率やサンプリングが必要なときに Softmax を使う。greedy decoding なら Softmax が順序を保つため、
argmax(logits)を直接計算できる
Attention の中では、Softmax がスケーリングと mask を適用したスコア QKᵀ/√d_k + mask を、各行の合計が 1 の Attention 重みに変えます。
6.5 Temperature:分布の形を制御する
推論 API を呼ぶときに temperature を設定すると、出力層での Softmax の挙動を変えています。
6.5.1 Temperature の数式
Softmax の前にロジットを T で割ると、結果の分布の形が変わります。
- T < 1(低温度):小さい数で割ることで、大きいロジットが相対的にさらに大きくなる。分布は鋭くなり——上位トークンが支配的になる
- T = 1(既定):標準の Softmax、変更なし
- T > 1(高温度):ロジットの差が縮む。分布は平坦になり——確率の低いトークンにより多くの重みが配分される
6.5.2 数値例
ロジット:[3.0, 1.0, 0.5]
| Temperature | 確率(おおよそ) | 性格 |
|---|---|---|
| T = 0.5 | [0.976, 0.018, 0.007] | 鋭い——確率の大半が最初の token に集まる |
| T = 1.0 | [0.821, 0.111, 0.067] | 標準的な分布 |
| T = 2.0 | [0.604, 0.222, 0.173] | 平坦——他の token の重みも増える |
値は
softmax(logits / T)で計算し、小数点以下 3 桁に丸めています。そのため表示値の合計は 0.001 ずれる場合があります。
6.5.3 実用上の含意
数式では T は 0 より大きくなければならず、文字どおりの T = 0 はゼロ除算になります。多くの推論ツールは temperature = 0 を greedy decoding の約束事として扱いますが、正確な挙動は実装次第です。
- 低い temperature:分布が集中し、サンプリングは通常より保守的になる
- 高い temperature:分布が平坦になり、通常より多様になる一方、最高確率の経路から外れやすくなる
Temperature は、デコード時にモデルの logits をどう使うかを変えるだけで、モデルが学習した内容を変えるものではありません。greedy decoding でも、ハードウェア、並列計算、配信実装によって差が生じることがあるため、常に一字一句同じになるという普遍的な保証ではありません。
6.6 章のまとめ
6.6.1 並列比較
| 項目 | LayerNorm | Softmax |
|---|---|---|
| 目的 | 活性化を正規化 | スコアを確率に変換 |
| 出力範囲 | スケール/シフト前は平均 ≈ 0、分散 ≈ 1 | 各要素 [0, 1]、合計 1 |
| 登場場所 | Attention/FFN の周辺、しばしば最終 norm | Attention 内、必要なときの出力サンプリング |
| 学習可能パラメータ | あり(γ と β) | なし(ただし temperature はハイパーパラメータ) |
6.6.2 数式リファレンス
LayerNorm:
y = (x - mean(x)) / std(x) × γ + β
Softmax:
P(i) = e^(x_i) / Σ_j e^(x_j)
Temperature 付き Softmax:
P(i) = e^(x_i / T) / Σ_j e^(x_j / T)
6.6.3 中核のテイクアウェイ
LayerNorm(そして近縁の RMSNorm)は、Transformer の“物差し”のように中間値を扱いやすいスケールへ戻します。Softmax は、Attention やサンプリングが分布を必要とするときの“確率コンバータ”です。小さな演算ですが、大きな役割があります。
章末チェックリスト
この章の後で、あなたは以下ができるはずです。
- LayerNorm が必要な理由を説明できる:行列積の積み重ねが活性化のドリフトを起こすこと
- 小さな入力ベクトルが与えられたときに LayerNorm の計算を手で追える
- Softmax を「指数化してから正規化する」操作として説明できる
- 小さなロジットベクトルが与えられたときに Softmax の計算を手で追える
- Transformer アーキテクチャの中で LayerNorm、RMSNorm、Softmax がどこに現れるかを言える
- Temperature が何を制御し、低い/高い値の実用的な効果が何かを説明できる
次の章でまた
ここまでで本章はおしまいです。これで、システム全体を静かに支える 2 つの軽量な道具をカバーしました。Transformer ブロックの図の中で LayerNorm と Softmax がどこに現れるかをあなたが描けるなら、先に進む準備ができています。
第 7 章では Feed Forward Network を紹介します——各 Transformer ブロックの内部にあるもう 1 つの主要コンポーネントで、モデルのパラメータの大半を保持しています。良いお知らせ:行列積と活性化関数を理解していれば、FFN は素直です。次の章でまた。