第 9 讲:Scaling Laws(上)
大语言模型的成功很大程度上源于一个经验发现:模型性能随着规模的增大而可预测地提升。这种规律性被称为 Scaling Laws,它为大模型的训练资源分配提供了科学依据。本讲将介绍 Scaling Laws 的基本概念,从 Kaplan et al. (2020) 的原始发现到 Chinchilla (Hoffmann et al., 2022) 的修正结论。
Scaling Laws 的基本概念
Scaling Laws 研究的核心问题是:给定有限的计算预算,如何最优地分配模型参数量和训练数据量?
语言模型的训练过程可以用三个核心变量来描述:
- N — 模型的非 embedding 参数量(number of parameters)
- D — 训练数据量(number of training tokens)
- C — 计算量(total compute in FLOPs)
这三者之间有一个近似关系:
为什么是 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(幂律)关系:
其中 x 可以是 N、D 或 C,a、b、c 是通过实验拟合的常数。c 代表不可约的 loss(irreducible loss),即数据本身的熵——即使模型无限大、数据无限多,loss 也不会低于这个值。
在 log-log 坐标下,Power Law 表现为直线:
这使得在几个数量级的范围内进行外推变得可能——我们可以在小规模实验中拟合 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 行为。
核心发现
- Loss 与 N、D、C 之间存在清晰的 Power Law 关系,跨越多个数量级
- 模型架构的细节不太重要:层数 vs 宽度、attention head 数量等超参数对 scaling behavior 的影响很小,主要取决于总参数量 N
- 大模型更 sample-efficient:大模型达到相同 loss 需要的训练数据更少
Kaplan 的最优分配结论
Kaplan 等人得出的最优分配比例是:
这意味着:当计算预算增加时,应该把大部分预算用于增大模型,而不是增加数据。例如计算预算翻倍时,模型应该增大 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 的核心方法论。它的思路很直观:
- 选择几个固定的计算预算 C(iso = 相同,FLOP = 计算量)
- 对于每个计算预算,训练多个不同大小的模型(不同的 N)
- 由于 C ≈ 6ND,给定 C 和 N 后,训练的 token 数 D = C/(6N) 是确定的
- 对于每个 (C, N) 组合,记录最终的 loss
- 找到每个 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 形):
- 模型太小(N 太小):参数不足以利用所有计算预算,loss 较高
- 模型太大(N 太大):训练数据不够(D 太小),模型欠训练,loss 也较高
- 最优点:N* 恰好平衡了模型容量和训练充分性
Chinchilla Scaling Laws
2022 年,DeepMind 的 Hoffmann 等人发表了 "Training Compute-Optimal Large Language Models"(即 Chinchilla 论文),修正了 Kaplan 的结论。
实验方法
Chinchilla 使用了三种互补的分析方法:
- 方法一(IsoFLOP profiles):固定 9 个不同的计算预算,对每个预算训练不同大小的模型,找到最优 N
- 方法二(IsoLoss contours):拟合参数化的 loss 函数 L(N, D),然后对每个 C 求最优
- 方法三(拟合 parametric loss function):直接拟合 L(N, D) = E + A/N^α + B/D^β
Chinchilla 的核心结论
三种方法得出了一致的结论:
也就是说,参数量和数据量应该等比例增长。具体的比例关系为:
Chinchilla-Optimal 意味着什么?
一个 Chinchilla-optimal 的模型,其训练 token 数大约是参数量的 20 倍。例如:一个 10B 参数的模型应该在约 200B tokens 上训练。这与 Kaplan 的结论截然不同——Kaplan 建议大幅增大模型而不增加数据,而 Chinchilla 认为数据同样重要。
Chinchilla 的 Loss Function
Chinchilla 拟合的 parametric loss function 为:
其中:
- E:irreducible loss(数据的内在熵)
- A / N^α:模型容量不足导致的 loss(approximation error)
- B / D^β:训练数据不足导致的 loss(estimation error)
- 拟合值约为:E ≈ 1.69,A ≈ 406.4,α ≈ 0.34,B ≈ 410.7,β ≈ 0.28
这个公式直观地分解了 loss 的三个来源:数据噪声、模型太小、数据太少。
Kaplan vs Chinchilla 对比
| 方面 | Kaplan (2020) | Chinchilla (2022) |
|---|---|---|
| 最优分配 | N ∝ C^0.73, D ∝ C^0.27 | N ∝ 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 分配:
- 计算最优参数量:
N_opt = (C / 120)^(1/2)(因为 D = 20N,C = 6ND = 120N²) - 计算最优 token 数:
D_opt = 20 × N_opt - 验证:
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 的模型大小为:
例如,如果你有 1T (10¹²) tokens 的高质量数据,最优模型大小为 50B 参数。
计算预算估算表
| 计算预算 | Chinchilla-Optimal N | Chinchilla-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?虽然目前还没有完整的理论解释,但有一些直觉:
- 数据中的信息分布是幂律的:自然语言中,简单的模式(如常见词搭配)频繁出现且容易学习,复杂的模式(如逻辑推理)稀少且难学。增大模型或数据时,能捕获的模式越来越"稀有"
- 维度诅咒的缓解:神经网络在高维空间中逼近函数,所需的参数量与问题的有效维度成幂律关系
- 从统计学习理论看:泛化误差 = approximation error + estimation error。前者随 N 增大以幂律下降(模型类的逼近能力),后者随 D 增大以幂律下降(统计估计的精度)
小结
- Scaling Laws 揭示了 loss 与 N、D、C 之间的 Power Law 关系
- IsoFLOP 分析是研究 scaling 行为的核心方法论
- Kaplan (2020) 首次发现 scaling laws,但由于实验方法问题,偏向于"增大模型"
- Chinchilla (2022) 修正了结论:模型和数据应等比增长,D ≈ 20N
- Chinchilla Scaling Laws 是训练预算规划的实用工具:给定 C,可以直接计算最优的 N 和 D
- 在 log-log 坐标下,Power Law 表现为直线,使得小规模实验的外推预测成为可能