スケーリング則の数学 — Kaplan則とChinchilla則を導出する

スケーリング則(Scaling Laws)は、言語モデルの性能がパラメータ数、データ量、計算量とどのように関係するかを記述する経験則です。この法則は、大規模モデルの効率的な訓練計画を立てる上で重要な指針となります。

本記事では、スケーリング則の理論と実証的な検証を解説します。

本記事の内容

  • スケーリング則の基本概念
  • Kaplan et al.のスケーリング則
  • Chinchillaスケーリング則
  • 計算最適な訓練
  • 実験的検証

スケーリング則の基本概念

背景

深層学習では、モデルを大きくしデータを増やすことで性能が向上することが経験的に知られています。スケーリング則はこの関係を定量化し、予測可能にします。

主要な変数

変数 記号 説明
パラメータ数 $N$ モデルの学習可能なパラメータの数
データ量 $D$ 訓練トークン数
計算量 $C$ 訓練に使用するFLOPs
損失 $L$ テスト損失(Cross-Entropy)

べき乗則

スケーリング則は、多くの場合べき乗則(Power Law)で表されます:

$$ L \propto X^{-\alpha} $$

ここで、$X$ はスケーリング変数($N$、$D$、または $C$)、$\alpha > 0$ はスケーリング指数です。

Kaplan et al. のスケーリング則

OpenAIの発見(2020)

OpenAIの研究チームは、言語モデルのスケーリング則を体系的に調査しました。

パラメータ数に対するスケーリング(十分なデータがある場合):

$$ L(N) = \left(\frac{N_c}{N}\right)^{\alpha_N} $$

ここで、$\alpha_N \approx 0.076$、$N_c \approx 8.8 \times 10^{13}$ です。

データ量に対するスケーリング(十分なパラメータがある場合):

$$ L(D) = \left(\frac{D_c}{D}\right)^{\alpha_D} $$

ここで、$\alpha_D \approx 0.095$、$D_c \approx 5.4 \times 10^{13}$ です。

計算量に対するスケーリング(最適配分の場合):

$$ L(C) = \left(\frac{C_c}{C}\right)^{\alpha_C} $$

ここで、$\alpha_C \approx 0.050$、$C_c \approx 1.6 \times 10^7$ です。

統合スケーリング則

パラメータ数とデータ量の両方を考慮:

$$ L(N, D) = \left[\left(\frac{N_c}{N}\right)^{\alpha_N / \alpha_D} + \frac{D_c}{D}\right]^{\alpha_D} $$

計算量の関係

計算量 $C$ はパラメータ数 $N$ とデータ量 $D$ の積に比例:

$$ C \approx 6ND $$

(1トークンあたり約6FLOPs/パラメータ、順伝播と逆伝播を含む)

Chinchilla スケーリング則

DeepMindの発見(2022)

DeepMindのChinchilla論文は、Kaplanのスケーリング則を再検討し、重要な修正を提案しました。

主要な発見

以前の研究では、計算予算が増えたらパラメータ数を優先的に増やすべきとされていました。しかし、Chinchillaはパラメータ数とデータ量を等しい比率で増やすべきことを示しました。

計算最適スケーリング

固定計算予算 $C$ に対する最適なパラメータ数 $N^*$ とデータ量 $D^*$:

$$ N^* \propto C^a, \quad D^* \propto C^b $$

Kaplanの主張: $a \approx 0.73$, $b \approx 0.27$(パラメータ重視)

Chinchillaの修正: $a \approx 0.5$, $b \approx 0.5$(均等配分)

最適トークン数の推定

Chinchillaの経験則として、最適な訓練トークン数はパラメータ数の約20倍:

$$ D^* \approx 20 \times N $$

モデル パラメータ数 最適トークン数
1B 1B 20B
7B 7B 140B
70B 70B 1.4T
175B 175B 3.5T

損失の推定

Chinchillaのスケーリング則:

$$ L(N, D) = E + \frac{A}{N^\alpha} + \frac{B}{D^\beta} $$

ここで: – $E$: 既約誤差(データ自体のエントロピー) – $A, B$: 定数 – $\alpha \approx 0.34$, $\beta \approx 0.28$

計算最適な訓練

最適化問題

固定計算予算 $C$ での最適配分:

$$ \min_{N, D} L(N, D) \quad \text{s.t.} \quad C = 6ND $$

ラグランジュ乗数法で解くと:

$$ \frac{\partial L}{\partial N} = \lambda \cdot 6D, \quad \frac{\partial L}{\partial D} = \lambda \cdot 6N $$

IsoFLOPs分析

同じ計算量でパラメータ数とデータ量の比率を変える実験:

import numpy as np
import matplotlib.pyplot as plt

def chinchilla_loss(N, D, A=406.4, B=410.7, E=1.69, alpha=0.34, beta=0.28):
    """Chinchillaスケーリング則による損失推定"""
    return E + A / (N ** alpha) + B / (D ** beta)


def compute_loss_curve(C, N_range):
    """固定計算量での損失曲線を計算"""
    losses = []
    for N in N_range:
        D = C / (6 * N)  # C = 6ND
        if D > 0:
            loss = chinchilla_loss(N, D)
            losses.append(loss)
        else:
            losses.append(np.inf)
    return np.array(losses)


# IsoFLOPs曲線のプロット
compute_budgets = [1e18, 1e19, 1e20, 1e21, 1e22]  # FLOPs
N_range = np.logspace(7, 11, 100)  # 10M to 100B parameters

plt.figure(figsize=(12, 6))

for C in compute_budgets:
    losses = compute_loss_curve(C, N_range)
    valid_mask = ~np.isinf(losses)
    plt.plot(N_range[valid_mask], losses[valid_mask],
             label=f'C = {C:.0e} FLOPs')

    # 最適点を見つける
    if np.any(valid_mask):
        min_idx = np.argmin(losses[valid_mask])
        N_opt = N_range[valid_mask][min_idx]
        plt.scatter([N_opt], [losses[valid_mask][min_idx]], s=100, zorder=5)

plt.xscale('log')
plt.xlabel('Parameters (N)')
plt.ylabel('Loss')
plt.title('IsoFLOPs Curves: Loss vs Parameters for Fixed Compute')
plt.legend()
plt.grid(True, alpha=0.3)
plt.savefig('isoflops_curves.png', dpi=150, bbox_inches='tight')
plt.show()

最適配分の計算

def optimal_allocation(C, alpha=0.34, beta=0.28, A=406.4, B=410.7):
    """
    固定計算量での最適なパラメータ数とデータ量を計算

    Parameters:
    -----------
    C : float
        計算予算(FLOPs)
    alpha, beta : float
        スケーリング指数
    A, B : float
        スケーリング定数

    Returns:
    --------
    N_opt : float
        最適パラメータ数
    D_opt : float
        最適データ量(トークン数)
    """
    # C = 6 * N * D の制約下で L(N,D) を最小化
    # 最適解: N^* ∝ C^(beta/(alpha+beta)), D^* ∝ C^(alpha/(alpha+beta))

    a = beta / (alpha + beta)
    b = alpha / (alpha + beta)

    # 定数の導出(数値的に)
    # 簡略化のため、Chinchillaの経験則 D ≈ 20N を使用
    N_opt = (C / (6 * 20)) ** 0.5
    D_opt = 20 * N_opt

    return N_opt, D_opt


# 例:1e23 FLOPsでの最適配分
C = 1e23
N_opt, D_opt = optimal_allocation(C)
print(f"Compute Budget: {C:.2e} FLOPs")
print(f"Optimal Parameters: {N_opt:.2e} ({N_opt/1e9:.1f}B)")
print(f"Optimal Tokens: {D_opt:.2e} ({D_opt/1e12:.1f}T)")
print(f"Tokens per Parameter: {D_opt/N_opt:.1f}")

実際のモデルとの比較

主要LLMの訓練設定

モデル パラメータ トークン トークン/パラメータ 効率
GPT-3 175B 300B 1.7 不十分
Chinchilla 70B 1.4T 20 最適
LLaMA 2 70B 2T 29 過剰訓練
GPT-4* ~1T? ~10T? ~10? 不明

*推定値

過剰訓練(Over-training)

LLaMA 2のように、最適点を超えてデータを増やす戦略もあります。

利点: – 推論コストの削減(より小さなモデルで同等性能) – データ効率の向上

トレードオフ: – 訓練計算量の増加 – 収穫逓減

数学的な導出

スケーリング則の導出

損失関数のテイラー展開と統計力学的考察から、べき乗則が導かれます。

仮定: 1. モデルはデータ分布の近似を学習 2. パラメータは独立に寄与 3. データは i.i.d.

導出

バイアス-バリアンス分解:

$$ L = L_{\text{irreducible}} + L_{\text{bias}}(N) + L_{\text{variance}}(N, D) $$

有限パラメータによるバイアス:

$$ L_{\text{bias}}(N) \sim N^{-\alpha} $$

有限データによるバリアンス:

$$ L_{\text{variance}}(N, D) \sim \frac{N}{D} $$

Emergence(創発)

大規模モデルでは、特定の能力が突然現れる「創発」現象が観察されています。

$$ \text{Capability}(N) = \begin{cases} \approx 0 & N < N_{\text{critical}} \\ \text{positive} & N \geq N_{\text{critical}} \end{cases} $$

しかし、最近の研究では、これは評価指標の非連続性によるアーティファクトである可能性が指摘されています。

スケーリング則の可視化

import numpy as np
import matplotlib.pyplot as plt

# スケーリング則の可視化
fig, axes = plt.subplots(2, 2, figsize=(14, 12))

# 1. パラメータに対するスケーリング
ax = axes[0, 0]
N = np.logspace(6, 12, 100)
alpha_N = 0.076
N_c = 8.8e13
L_N = (N_c / N) ** alpha_N

ax.loglog(N, L_N, 'b-', linewidth=2)
ax.set_xlabel('Parameters (N)')
ax.set_ylabel('Loss')
ax.set_title('Loss vs Parameters (Kaplan et al.)')
ax.grid(True, alpha=0.3)

# 実際のモデルをプロット
models = {
    'GPT-2': (1.5e9, 3.5),
    'GPT-3': (175e9, 2.9),
    'PaLM': (540e9, 2.7),
}
for name, (n, l) in models.items():
    ax.scatter([n], [l], s=100, zorder=5, label=name)
ax.legend()

# 2. データに対するスケーリング
ax = axes[0, 1]
D = np.logspace(9, 14, 100)
alpha_D = 0.095
D_c = 5.4e13
L_D = (D_c / D) ** alpha_D

ax.loglog(D, L_D, 'r-', linewidth=2)
ax.set_xlabel('Training Tokens (D)')
ax.set_ylabel('Loss')
ax.set_title('Loss vs Data (Kaplan et al.)')
ax.grid(True, alpha=0.3)

# 3. 計算量に対するスケーリング
ax = axes[1, 0]
C = np.logspace(15, 25, 100)
alpha_C = 0.050
C_c = 1.6e7
L_C = (C_c / C) ** alpha_C

ax.loglog(C, L_C, 'g-', linewidth=2)
ax.set_xlabel('Compute (FLOPs)')
ax.set_ylabel('Loss')
ax.set_title('Loss vs Compute (Kaplan et al.)')
ax.grid(True, alpha=0.3)

# 4. Chinchilla vs Kaplan: 最適配分
ax = axes[1, 1]
C_budgets = np.logspace(18, 24, 50)

# Kaplan: N ∝ C^0.73
N_kaplan = C_budgets ** 0.73 / 1e4
D_kaplan = C_budgets / (6 * N_kaplan)

# Chinchilla: N ∝ C^0.5
N_chinchilla = C_budgets ** 0.5 / 1e2
D_chinchilla = C_budgets / (6 * N_chinchilla)

ax.loglog(C_budgets, D_kaplan / N_kaplan, 'b--', label='Kaplan (D/N)', linewidth=2)
ax.loglog(C_budgets, D_chinchilla / N_chinchilla, 'r-', label='Chinchilla (D/N)', linewidth=2)
ax.axhline(y=20, color='g', linestyle=':', label='D/N = 20 (Chinchilla optimal)')
ax.set_xlabel('Compute (FLOPs)')
ax.set_ylabel('Tokens per Parameter (D/N)')
ax.set_title('Optimal Data-to-Parameter Ratio')
ax.legend()
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('scaling_laws_visualization.png', dpi=150, bbox_inches='tight')
plt.show()

実用的な示唆

モデル訓練の計画

  1. 計算予算を決定: 利用可能なGPU時間とコスト
  2. 最適配分を計算: Chinchillaの法則に基づく
  3. データ準備: 必要なトークン数を確保
  4. 小規模実験: スケーリングの検証

予測可能な性能

スケーリング則を使って、大規模モデルの性能を予測:

$$ L_{\text{predicted}}(N_{\text{large}}) = L_{\text{small}} \cdot \left(\frac{N_{\text{small}}}{N_{\text{large}}}\right)^{\alpha} $$

まとめ

本記事では、スケーリング則について解説しました。

  • べき乗則: 損失はパラメータ、データ、計算量に対してべき乗的に減少
  • Kaplanの法則: パラメータ数を優先的に増やすべき
  • Chinchillaの修正: パラメータとデータを均等に増やすべき(D = 20N)
  • 計算最適訓練: 固定予算での最適なリソース配分
  • 実用的示唆: 訓練計画の立案に活用

スケーリング則は、LLMの効率的な開発において重要なガイドラインを提供します。ただし、これらは経験則であり、アーキテクチャやデータの質によって変化する可能性があることに注意が必要です。

次のステップとして、以下の記事も参考にしてください。