规模 第 9 讲 / 共 17 讲

第 9 讲:Scaling Laws(上)

大语言模型的成功很大程度上源于一个经验发现:模型性能随着规模的增大而可预测地提升。这种规律性被称为 Scaling Laws,它为大模型的训练资源分配提供了科学依据。本讲将介绍 Scaling Laws 的基本概念,从 Kaplan et al. (2020) 的原始发现到 Chinchilla (Hoffmann et al., 2022) 的修正结论。

Scaling Laws 的基本概念

Scaling Laws 研究的核心问题是:给定有限的计算预算,如何最优地分配模型参数量和训练数据量?

语言模型的训练过程可以用三个核心变量来描述:

这三者之间有一个近似关系:

C ≈ 6 × N × D

为什么是 6ND?

对于一个 Transformer 模型,forward pass 中每个 token 的计算量约为 2N FLOPs(每个参数贡献一次乘法和一次加法)。Backward pass 的计算量约为 forward 的两倍(需要计算参数梯度和输入梯度),所以总共 ≈ 6N FLOPs per token。训练 D 个 tokens,总计算量 C ≈ 6ND。

Power Law 关系

Scaling Laws 的核心发现是,模型的 test loss L 与 N、D、C 之间存在 Power Law(幂律)关系:

L(x) = a × x^(-b) + c

其中 x 可以是 N、D 或 C,a、b、c 是通过实验拟合的常数。c 代表不可约的 loss(irreducible loss),即数据本身的熵——即使模型无限大、数据无限多,loss 也不会低于这个值。

在 log-log 坐标下,Power Law 表现为直线:

log(L - c) = log(a) - b × log(x)

这使得在几个数量级的范围内进行外推变得可能——我们可以在小规模实验中拟合 scaling law,然后预测大模型的性能。

分别固定其他变量的 Scaling Laws

关系形式条件
L(N)L = a_N × N^(-α_N) + L_∞固定 D 为足够大(不欠训练)
L(D)L = a_D × D^(-α_D) + L_∞固定 N 为足够大(不欠参数)
L(C)L = a_C × C^(-α_C) + L_∞N 和 D 最优分配

Kaplan et al. (2020) 的原始 Scaling Laws

OpenAI 的 Kaplan 等人在 2020 年发表了划时代的论文 "Scaling Laws for Neural Language Models",首次系统性地研究了语言模型的 scaling 行为。

核心发现

  1. Loss 与 N、D、C 之间存在清晰的 Power Law 关系,跨越多个数量级
  2. 模型架构的细节不太重要:层数 vs 宽度、attention head 数量等超参数对 scaling behavior 的影响很小,主要取决于总参数量 N
  3. 大模型更 sample-efficient:大模型达到相同 loss 需要的训练数据更少

Kaplan 的最优分配结论

Kaplan 等人得出的最优分配比例是:

N ∝ C^0.73,D ∝ C^0.27

这意味着:当计算预算增加时,应该把大部分预算用于增大模型,而不是增加数据。例如计算预算翻倍时,模型应该增大 2^0.73 ≈ 1.66 倍,数据只增加 2^0.27 ≈ 1.21 倍。

Kaplan 的方法论问题

后来的研究发现,Kaplan 的实验存在几个关键问题:(1)每个模型没有训练到收敛,大模型的 learning rate schedule 不够长;(2)没有对每个规模的 learning rate 进行充分调优;(3)不同规模的模型使用了相同的训练步数而不是相同的 token 数。这些问题导致结论偏向于"增大模型比增加数据更重要"。

IsoFLOP 分析方法

IsoFLOP 分析是研究 Scaling Laws 的核心方法论。它的思路很直观:

  1. 选择几个固定的计算预算 C(iso = 相同,FLOP = 计算量)
  2. 对于每个计算预算,训练多个不同大小的模型(不同的 N)
  3. 由于 C ≈ 6ND,给定 C 和 N 后,训练的 token 数 D = C/(6N) 是确定的
  4. 对于每个 (C, N) 组合,记录最终的 loss
  5. 找到每个 C 下使 loss 最小的 N*(最优模型大小)

通过这种方法,我们可以绘制出在不同计算预算下的最优模型大小和对应的最优数据量。

IsoFLOP 实验设计

# Pseudo-code for IsoFLOP experiment
compute_budgets = [1e18, 1e19, 1e20, 1e21]  # FLOPs
model_sizes = [10e6, 50e6, 100e6, 500e6, 1e9, 5e9]  # Parameters

results = {}
for C in compute_budgets:
    for N in model_sizes:
        D = C / (6 * N)  # Tokens to train
        if D < min_tokens:
            continue  # Skip if too few tokens

        # Train model with N params for D tokens
        loss = train_model(N, D)
        results[(C, N)] = loss

    # Find optimal N for this compute budget
    optimal_N = min(model_sizes, key=lambda n: results.get((C, n), float('inf')))
    print(f"C={C:.0e}: optimal N={optimal_N:.0e}, D={C/(6*optimal_N):.0e}")

IsoFLOP 曲线的典型形状

在 log-log 坐标下,IsoFLOP 曲线呈 U 形(在线性坐标下也是 U 形):

Chinchilla Scaling Laws

2022 年,DeepMind 的 Hoffmann 等人发表了 "Training Compute-Optimal Large Language Models"(即 Chinchilla 论文),修正了 Kaplan 的结论。

实验方法

Chinchilla 使用了三种互补的分析方法:

  1. 方法一(IsoFLOP profiles):固定 9 个不同的计算预算,对每个预算训练不同大小的模型,找到最优 N
  2. 方法二(IsoLoss contours):拟合参数化的 loss 函数 L(N, D),然后对每个 C 求最优
  3. 方法三(拟合 parametric loss function):直接拟合 L(N, D) = E + A/N^α + B/D^β

Chinchilla 的核心结论

三种方法得出了一致的结论:

N_opt ∝ C^0.50,D_opt ∝ C^0.50

也就是说,参数量和数据量应该等比例增长。具体的比例关系为:

D_opt ≈ 20 × N_opt

Chinchilla-Optimal 意味着什么?

一个 Chinchilla-optimal 的模型,其训练 token 数大约是参数量的 20 倍。例如:一个 10B 参数的模型应该在约 200B tokens 上训练。这与 Kaplan 的结论截然不同——Kaplan 建议大幅增大模型而不增加数据,而 Chinchilla 认为数据同样重要。

Chinchilla 的 Loss Function

Chinchilla 拟合的 parametric loss function 为:

L(N, D) = E + A / N^α + B / D^β

其中:

这个公式直观地分解了 loss 的三个来源:数据噪声、模型太小、数据太少。

Kaplan vs Chinchilla 对比

方面Kaplan (2020)Chinchilla (2022)
最优分配N ∝ C^0.73, D ∝ C^0.27N ∝ C^0.50, D ∝ C^0.50
D/N 比例~5 tokens/param~20 tokens/param
核心建议优先增大模型模型和数据等比增长
GPT-3 (175B) 评估接近最优严重欠训练
实验严谨性没充分训练大模型每个实验点充分训练

实际应用:给定预算如何分配

Chinchilla Scaling Laws 最大的实际价值在于帮助我们做训练预算规划。

计算预算到模型配置

假设我们有一个固定的计算预算 C(以 FLOPs 为单位),使用 Chinchilla-optimal 分配:

  1. 计算最优参数量:N_opt = (C / 120)^(1/2)(因为 D = 20N,C = 6ND = 120N²)
  2. 计算最优 token 数:D_opt = 20 × N_opt
  3. 验证:6 × N_opt × D_opt ≈ C
# Example: Planning model training
def plan_training(compute_budget_flops):
    """Given compute budget in FLOPs, compute optimal N and D."""
    N_opt = (compute_budget_flops / 120) ** 0.5
    D_opt = 20 * N_opt

    # Convert to practical units
    print(f"Compute Budget: {compute_budget_flops:.2e} FLOPs")
    print(f"Optimal Parameters: {N_opt:.2e} ({N_opt/1e9:.1f}B)")
    print(f"Optimal Tokens: {D_opt:.2e} ({D_opt/1e9:.0f}B)")
    print(f"Verification: 6*N*D = {6*N_opt*D_opt:.2e} FLOPs")

# Example: 1000 H100-hours ≈ 1000 * 3600 * 989e12 ≈ 3.56e21 FLOPs
plan_training(3.56e21)
# Optimal Parameters: ~5.4B
# Optimal Tokens: ~109B

反向推算:已有数据量决定模型大小

如果你已经有固定的数据集(D tokens),Chinchilla-optimal 的模型大小为:

N_opt = D / 20

例如,如果你有 1T (10¹²) tokens 的高质量数据,最优模型大小为 50B 参数。

计算预算估算表

计算预算Chinchilla-Optimal NChinchilla-Optimal D大致 GPU-hours (H100)
10¹⁸ FLOPs~91M~1.8B tokens~0.3 hours
10¹⁹ FLOPs~289M~5.8B tokens~3 hours
10²⁰ FLOPs~913M~18B tokens~28 hours
10²¹ FLOPs~2.9B~58B tokens~281 hours
10²² FLOPs~9.1B~183B tokens~2,810 hours
10²³ FLOPs~28.9B~577B tokens~28,100 hours
10²⁴ FLOPs~91.3B~1.8T tokens~281,000 hours

注意 GPU-hours 的估算

上表假设 H100 的实际利用率约为 50%(即 ~500 TFLOPS 的 BF16 有效吞吐量)。实际训练中,利用率受通信开销、数据加载、pipeline bubble 等因素影响,通常在 30%-60% 之间。

Scaling Laws 的直觉理解

为什么模型性能会遵循 Power Law?虽然目前还没有完整的理论解释,但有一些直觉:

小结