Lecture 4 · 规模定律:损失怎样随参数、数据和算力变化 · Scaling Laws

Advances in Foundation Models · Lecture 04。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应 Maps to:Stanford CS324 Winter 2023 Advances in Foundation Models,1/23 Lecture: Scaling Laws and Emergent Behavior(Tatsunori Hashimoto)的前半;Syllabus 主题 “Emergent Behaviors and Capabilities” 中的课程笔记 Scaling Laws(CS324 Winter 2022)与 Kaplan et al. Scaling Laws for Neural Language Models(2020);1/25 客座报告 Pathways Language Model (PaLM) and Model Scaling(Aakanksha Chowdhery,Google)中与规模有关的部分。补充阅读:Hoffmann et al. Training Compute-Optimal Large Language Models(Chinchilla,2022)、Hestness et al. Deep Learning Scaling is Predictable, Empirically(2017)、Muennighoff et al. Scaling Data-Constrained Language Models(2023)。 依据说明:课程网站没有提供 1/23 讲座的 slides 或录像,1/25 的客座报告也只链接了 Google 的 PaLM 博客。本讲依据上面的阅读材料来写:整体结构沿着 Winter 2022 的 Scaling laws 课程笔记(一份 slides 形式的 PDF:数据规模定律 → 用规模定律做模型工程 → 用规模定律做预测),技术细节依据 Kaplan 和 Chinchilla 两篇论文;Chinchilla 不在 Winter 2023 的阅读清单上,但它是 2022 年之后理解这个主题绕不开的工作,所以占了较大篇幅。PaLM 一节依据 PaLM 论文(Chowdhery et al. 2022)和 Google 的博客,不是报告本身的记录。“2023 年之后”一节是我补充的。 配套代码 Code:code/lecture04/(numpy + PyTorch;5 个脚本 + 1 个模块;代码 02 第一次运行约 2 分钟、代码 04 再训练约 1.5 分钟,结果缓存后各脚本都只要几秒) 预计阅读时间:3 小时(含运行代码)


0. 本讲导航 · How to read this lecture

0.1 学习目标 Learning goals

学完这一讲,你应该能够:

  1. 解释幂律(power law)为什么在对数坐标下是一条直线、指数大小意味着什么;解释不可约损失(irreducible loss)EE 为什么让曲线”弯”下来,以及为什么画图前要先想清楚纵轴是 LL 还是 L−EL - E。
  2. 说出”为什么会出现幂律”的几种解释(估计误差的多项式收敛、数据的内在维数、Zipf 分布的”知识块”),以及它们解释不了什么。
  3. 推导 C≈6NDC \approx 6ND 里的 6,知道它什么时候准、什么时候不准,并能用它给 GPT-3、Chinchilla、PaLM、LLaMA 记账。
  4. 复述 Kaplan et al. (2020) 的主要发现(平滑幂律、形状不太重要、大模型样本效率更高、Nopt∝C0.73N_{\text{opt}} \propto C^{0.73}),以及 Chinchilla (2022) 怎样修正了它(参数和数据等比例增长、约 20 token/参数、Gopher 和 GPT-3 训练不足)。
  5. 描述 Chinchilla 的三种方法(训练曲线的下包络、IsoFLOP 曲线、参数化拟合),能从 L(N,D)=E+A/Nα+B/DβL(N,D) = E + A/N^\alpha + B/D^\beta 推出计算最优的分配。
  6. 说出 Kaplan 和 Chinchilla 结论不同的几个原因(学习率调度没有和训练长度匹配、规模偏小、嵌入参数的数法),以及 2024 年的复现工作怎样重新评估这些原因。
  7. 亲手拟合和外推一条规模定律,并能说出它会怎样失败:没有下限项、只看一个切片、范围太窄、噪声、超参数没有随规模调。
  8. 说出规模定律的用途(预测大训练、选超参数、比较架构和数据、做预算)和局限(损失 ≠ 下游能力、数据不够、推理成本),以及 2023 年以后”过度训练小模型”和”推理时计算”的发展。

0.2 先修与本讲范围 Prerequisites & scope

默认你已经会 Assumed本讲只给直觉,后面几讲再展开 Previewed only
第 1 讲 §2.4:交叉熵、bit/字符、“交叉熵 ≥ 熵”“涌现”能力与评价指标的关系(第 5 讲)
第 1 讲 §3.2:规模的增长数据去重、配比、质量过滤(第 2 讲)
对数:log⁡(ab)=log⁡a+log⁡b\log(ab) = \log a + \log b,log⁡xk=klog⁡x\log x^k = k \log xTransformer 内部结构(第 3 讲;本讲只改它的宽度和层数)
一点微积分:对一个变量求导、令其为 0FLOPs 与硬件利用率(MFU)、GPU 上的性能(第 8 讲)
Python、numpy 基础PaLM 的工程细节:损失尖峰、并行(第 9、10 讲)

本讲关心的是预训练损失(交叉熵)怎样随规模变化,以及怎样用这种规律做决策。能力是否随规模”突然出现”,留给第 5 讲。

0.3 本讲地图 Map

§1  为什么需要规模定律:调参太贵;"在小模型上调,外推到大模型"
§2  幂律与对数坐标:直线、不可约损失、为什么会出现幂律                      ← 代码 01
§3  算力的记账:C ≈ 6ND 从哪里来,什么时候准;给真实模型记账               ← 代码 01、05
§4  一个知道熵的玩具世界:合成语言、扫描训练、切片、噪声                    ← 代码 02
§5  Kaplan et al. (2020):平滑幂律、形状、L(N, D)、N ∝ C^0.73              ← 代码 04
§6  Chinchilla (2022):三种方法、约 20 token/参数、为什么和 Kaplan 不一样    ← 代码 03、04、05
§7  怎样拟合和外推一条规模定律,以及它怎样失败                              ← 代码 03
§8  规模定律拿来做什么:预测、调参、比较、预算、预测能力
§9  局限:损失 ≠ 能力、数据受限、推理成本、外推的边界                       ← 代码 05
§10 案例:PaLM 与规模                                                       ← 代码 05
§11 2023 年之后
§12–16  小结、常见误区、练习、延伸阅读、下一讲预告

0.4 记号 Notation

NN、DD、CC(参数量、训练 token 数、训练算力)沿用第 1 讲 §0.4。本讲新增:

符号含义例子
LL验证集上的交叉熵损失代码里是 bit/字符;Kaplan、Chinchilla 用 nats/token
EE不可约损失(irreducible loss):模型再大、数据再多也减不掉的部分代码 02 的合成语言:E=0.7722E = 0.7722 bit/字符(精确值)
A,αA, \alpha参数项 A/NαA / N^\alpha 的系数和指数Chinchilla:A=406.4A = 406.4,α=0.34\alpha = 0.34
B,βB, \beta数据项 B/DβB / D^\beta 的系数和指数Chinchilla:B=410.7B = 410.7,β=0.28\beta = 0.28
αN,αD,αC\alpha_N, \alpha_D, \alpha_CKaplan 的单变量幂律指数0.0760.076、0.0950.095、0.0500.050
Nopt(C)N_{\text{opt}}(C),Dopt(C)D_{\text{opt}}(C)给定算力 CC 时损失最低的模型大小和数据量(“计算最优”,compute-optimal)
aa,bbNopt∝CaN_{\text{opt}} \propto C^a,Dopt∝CbD_{\text{opt}} \propto C^b;在 C=6NDC = 6ND 下 a+b=1a + b = 1Kaplan a=0.73a = 0.73;Chinchilla a≈0.5a \approx 0.5
IsoFLOP 曲线固定算力 CC,损失随 NN(相应地 D=C/6ND = C/6N)变化的曲线§6.2
PF-day101510^{15} 次浮点运算/秒 × 一天 =8.64×1019= 8.64 \times 10^{19} FLOPsGPT-3 约 3,646 PF-days
token/参数D/ND / N,每个参数”看了”多少个训练 tokenChinchilla 约 20

nats 和 bits 只差一个常数因子:1 nat =1/ln⁡2≈1.44= 1/\ln 2 \approx 1.44 bit。

0.5 关于数字 · About the numbers

讲义里所有实验数字都来自配套代码的实际输出(固定随机种子、PyTorch 单线程,同一台机器上重复运行逐字相同;只有计时每次不同)。代码 02–04 的实验在一个熵可以精确计算的合成语言上进行(§4.1),模型是第 1 讲 tiny_gpt.py 里的 Transformer,参数量从约 2 千到约 10 万——比真实的大模型小 6–7 个数量级,参数量只跨 1.7 个数量级(Kaplan 跨了 6 个)。所以玩具实验只用来演示方法和机制:怎样量、怎样拟合、怎样推出最优分配、哪些做法会出错。玩具里拟合出的指数和”token/参数”和真实 LLM 不一样,正文会逐一说明,并给出真实模型的文献数字。有好几处结果和我写代码前的预想不一样(包括”形状不重要”在玩具里不成立),讲义按实际结果来写,这些情况列在代码 README 的”关于实验结果”里。


1. 为什么需要规模定律 · Why scaling laws?

1.1 一个昂贵的问题

假设你要训练一个 GPT-3 规模的模型。一次训练要 3×10233 \times 10^{23} 次浮点运算、数百万美元(第 1 讲 §3.2)。但在按下”开始”之前,你要决定几十个东西:模型多大?读多少数据?学习率多少?batch 多大?用 Adam 还是 SGD?多少层、多宽?这些决定只要错一个,几百万美元就打了折扣。

传统的做法是超参数搜索:试很多组设置,挑最好的。在大模型上这完全不可能——你连一次都训练不起,更别说试几十次。Winter 2022 的课程笔记把可能的出路列成三条:(1) 猜一个,然后祈祷;(2) 穷举搜索(太贵);(3) 找到一些简单的、能预测的规则,告诉你最优的设置是什么。

规模定律就是第三条路。笔记里的一句话概括了它的意义:以前是”在大模型上调超参数”(又旧又痛苦),现在是**“在小模型上调,再外推到大模型”**。具体流程是:

  1. 训练一批小模型(每个只花大训练的千分之一甚至万分之一的算力);
  2. 在它们上面建立一条规模定律(例如”损失怎样随参数量下降”,或者”Adam 和 SGD 各自的曲线”);
  3. 用这条定律预测大模型,选出最优的设置。

这件事能成立,前提是一个经验事实:语言模型的损失随规模的变化非常平滑、非常规则——在对数坐标下几乎是直线,跨好几个数量级。这一讲就是要把这件事讲清楚:它是什么、为什么、怎样用、在哪里会失效。

1.2 什么是规模定律

规模定律(scaling law):一个简单的函数,把”资源”(参数量 NN、数据量 DD、算力 CC)映射到”表现”(通常是测试集上的损失),并且能从小规模的实验外推到大规模。

这件事不是 2020 年才被发现的。Hestness et al. (2017) 在机器翻译、语言建模、图像分类、语音识别四个领域系统地测量了”泛化误差 vs 训练集大小”,发现它们都可以分成三段(这个三段图景下面会反复用到):

区域发生了什么
小数据区(small data region)样本太少,模型学不到什么,表现接近瞎猜
幂律区(power-law region)每多一点数据,误差就按幂律下降:在对数坐标下是一条直线
不可约误差区(irreducible error region)误差趋向一个下限(贝叶斯误差等),再多数据也减不掉

他们测到的数据指数(误差 ∝nβg\propto n^{\beta_g})都远小于 1:词级语言模型约 −0.066、字符级约 −0.094、机器翻译约 −0.128、图像分类 top-1 约 −0.309、语音识别约 −0.30。他们还发现,达到最好表现所需的模型大小随数据量次线性增长(∝mβp\propto m^{\beta_p},βp\beta_p 在 0.5–1 之间)。

2020 年,OpenAI 的 Kaplan et al. 把这件事推到了 Transformer 语言模型上,测量范围跨越 6 个以上数量级,并且同时研究了参数、数据、算力三个变量(§5)。2022 年,DeepMind 的 Hoffmann et al.(Chinchilla)修正了其中最重要的一个结论(§6)。


2. 幂律与对数坐标 · Power laws on log-log axes

2.1 幂律为什么在对数坐标下是直线

幂律:y=A⋅x−αy = A \cdot x^{-\alpha}。两边取对数:

log⁡y=log⁡A−αlog⁡x.\log y = \log A - \alpha \log x .

在横轴 log⁡x\log x、纵轴 log⁡y\log y 的图(log-log 图)上,这是一条斜率为 −α-\alpha 的直线。指数 α\alpha 的含义最好用”乘法”来理解:xx 乘以 kk,yy 就乘以 k−αk^{-\alpha}——不管从哪里出发。

代码 01 演示 1 用 Kaplan et al. 测到的参数指数 αN≈0.076\alpha_N \approx 0.076 算了一下:

参数量的变化损失乘以损失下降
× 20.94875.1%
× 100.839516.1%
要让损失减半参数要乘以约 9000 倍(21/0.076≈9.14×1032^{1/0.076} \approx 9.14 \times 10^3)

两个直觉:

  • “可预测”来自”固定的比例”。不管你现在是 1 亿还是 1000 亿参数,翻一倍都降 5.1%。所以在小模型上量出斜率,就能推出大模型——这是规模定律有用的根本原因。
  • 指数很小,意味着回报很”贵”。只靠加参数,损失减半要乘以约 9000 倍。现实中的进步来自同时增加 NN、DD、CC,以及改进数据和架构(它们通常改变的是曲线的位置而不是斜率,§8.3)。

2.2 不可约损失:曲线为什么会”弯”

纯幂律有一个致命问题:x→∞x \to \infty 时 y→0y \to 0。但语言模型的损失不可能降到 0——第 1 讲 §2.4 讲过,交叉熵永远不低于数据本身的熵 H(p)H(p)。文本里有真正的不确定性(下一个词本来就可以有好几种合理的选择),任何模型都消除不了。

所以更合理的形式是幂律 + 不可约项:

L(N)=E+ANα.L(N) = E + \frac{A}{N^{\alpha}} .

EE 是不可约损失(理想情况下就是文本的熵),A/NαA/N^\alpha 是”还能学会的部分”(reducible loss)。代码 01 演示 1 (b) 用 Chinchilla 发表的拟合式里的参数项(E=1.69E = 1.69,A=406.4A = 406.4,α=0.34\alpha = 0.34)算了一张表:

NNL(N)L(N)L−EL - ELL 的局部斜率L−EL - E 的局部斜率
10610^65.39643.70640.20270.3400
10810^82.46440.77440.08120.3400
101010^{10}1.85180.16180.02110.3400
101110^{11}1.76400.07400.01000.3400

(“局部斜率”是相邻两点在 log-log 图上连线的斜率,取负号。)直接看 LL,斜率从 0.2 多降到 0.01——画出来是一条越来越平的曲线,看上去像”规模失效了”。可是”还能减掉的部分” L−EL - E 一直在按同一个指数 0.34 下降。

这给了一条非常实用的建议:画规模曲线之前,先想清楚纵轴是 LL 还是 L−EL - E。“损失下降变慢了”可能只是因为你离 EE 近了,而不是规模的回报消失了。反过来,EE 不知道的时候(真实语料上永远不知道),它就成了拟合里最难确定的一个数(§7)。

2.3 为什么会出现幂律?

为什么损失和资源之间偏偏是幂律,而不是指数衰减或者别的形状?没有一个公认的完整答案,但有几个很有启发的简单模型。代码 01 演示 2 把它们各算了一遍。

(a) 估计误差按多项式速度下降。 这是 Winter 2022 课程笔记里的例子:用 nn 个样本的平均值估计一个分布的均值,均方误差是 σ2/n\sigma^2 / n。这本身就是一条斜率为 −1 的规模定律。代码模拟得到斜率 −0.999。更一般地,任何”误差按 nn 的多项式速度下降”的学习问题,在 log-log 图上都是直线——统计学习理论里的泛化误差界大多是这种形式。

(b) 指数由数据的”内在维数”决定。 但神经网络的指数(0.07–0.3)比 1 小得多,为什么?笔记给的解释是非参数估计:在 dd 维空间里,用”附近的样本”来预测,nn 个点把空间”填满”的密度只有 n−1/dn^{-1/d},误差的下降也就慢得多。代码用 1-最近邻回归验证了这一点:

维数 dd拟合斜率理论值 −2/d-2/d
1−1.911−2.000
2−0.963−1.000
4−0.448−0.500
8−0.208−0.250

维数越高,同样多的数据带来的改进越少。按这个解释,语言数据的指数这么小,是因为它的”内在维数”很高(Bahri et al. 2021 等工作试图在实验里验证这一点)。

(c) Zipf 分布的”知识块”。 另一个图景:要学的东西是一块一块的(一个词怎么拼、一个事实、一种语法结构),第 kk 常用的那块被用到的概率 pk∝k−(1+α)p_k \propto k^{-(1+\alpha)}(Zipf 分布:少数东西非常常见,大量东西非常罕见)。

  • 如果模型的容量只够记住最常用的 nn 块,剩下的损失 ∝∑k>npk≈n−α\propto \sum_{k>n} p_k \approx n^{-\alpha};
  • 如果数据只够让一部分块出现过,剩下的损失 ≈D−α/(1+α)\approx D^{-\alpha/(1+\alpha)}。

代码取 α=0.5\alpha = 0.5,得到容量方向斜率 −0.511(理论 −0.5)、数据方向 −0.344(理论 −0.333)。这个图景(Hutter 2021、Michaud et al. 2023 的”量子化模型”)的好处是:同一个分布同时解释了参数指数和数据指数,而且解释了为什么”大模型学会罕见的东西”。代码 02 的合成语言就是按这个思路造的:词表服从 Zipf 分布,罕见的词和搭配就是”尾部的知识块”。

这些模型能解释”为什么是幂律”,但都不能告诉你真实语言的指数是多少——那只能量。Winter 2022 笔记把这称为”一个迷人的谜”:实测的指数和简单理论的预测相差很远。


3. 算力的记账:C ≈ 6ND · Counting compute

规模定律里第三个变量是算力 CC。几乎所有论文都用同一个近似:训练算力 C≈6NDC \approx 6ND。这一节把 6 推出来,再看它什么时候准。

3.1 6 从哪里来

Transformer 里几乎所有计算都是矩阵乘法。看一个线性层 y=Wxy = Wx,WW 是 m×nm \times n 的矩阵(mnmn 个参数):

  • 前向:每个权重做一次乘法、一次加法 → 每个 token 2mn2mn 次浮点运算 = 2 × 参数量。
  • 反向:要算两个梯度——对输入的梯度 ∂L/∂x=W⊤(∂L/∂y)\partial L / \partial x = W^\top (\partial L / \partial y)(又是 2mn2mn),对权重的梯度 ∂L/∂W=(∂L/∂y) x⊤\partial L / \partial W = (\partial L / \partial y)\, x^\top(又是 2mn2mn)→ 4 × 参数量。

合起来每个参数、每个 token 6 次浮点运算。整个模型 NN 个参数、训练 DD 个 token,就是 C≈6NDC \approx 6ND。代码 01 演示 3 (a) 用 PyTorch 的 FLOP 计数器(FlopCounterMode)实测了一个 256 → 512 的线性层:前向正好是 2 × 参数 × token,前向 + 反向正好是 6 ×。

3.2 6N 什么时候准

6N6N 漏掉了一样东西:注意力里的 QK⊤QK^\top 和”按注意力权重加权求和”两步。它们的计算量 ∝\propto 上下文长度 × 宽度,没有对应的参数。Kaplan et al. 把前向的计算量写成

Cforward≈2N+2 nlayer nctx dmodel,C_{\text{forward}} \approx 2N + 2\, n_{\text{layer}}\, n_{\text{ctx}}\, d_{\text{model}} ,

第二项和第一项(2N≈24 nlayer dmodel22N \approx 24\, n_{\text{layer}}\, d_{\text{model}}^2)之比约为 nctx/(12 dmodel)n_{\text{ctx}} / (12\, d_{\text{model}})——上下文相对于宽度越长,6N 低估得越多。代码 01 演示 3 (b) 实测了几个 TinyGPT:

模型参数 NN上下文 ÷ 宽度实测训练 FLOPs ÷ 6N6N
代码 02 最窄的模型(2 层,d=8d = 8,上下文 32)2,1844.001.249
第 1 讲的 base model(d=64d = 64,上下文 96)109,0561.501.153
代码 02 最宽的模型(d=64d = 64,上下文 32)103,4880.501.042
8 层,d=512d = 51225,247,2320.061.008

对 GPT-3(96 层、宽度 12288、上下文 2048),注意力那一项只占 2N2N 的 1.4%。所以对大模型,6ND 非常准;对我们的玩具模型会低估 4%–25%。本讲的代码仍然统一用 6ND6ND 记账——同一把尺子用到底,比较和拟合是自洽的。(FLOP 计数器把因果掩码遮住的那一半也算了进去,所以玩具模型的实测比 Kaplan 的式子还高一些。实际硬件上能跑到多少 FLOPs/秒,是第 8 讲的话题。)

3.3 给真实模型记账

有了 6ND6ND,就能给每个大模型记一笔账(代码 05 演示 1;参数和 token 数来自各自的论文):

模型NNDDC=6NDC = 6NDPF-daystoken/参数
GPT-3(2020)175B300B3.15e233,6461.7
Gopher(2021)280B300B5.04e235,8331.1
Chinchilla(2022)70B1.4T5.88e236,80620.0
PaLM 540B(2022)540B780B2.53e2429,2501.4
LLaMA-65B(2023)65.2B1.4T5.48e236,33921.5
LLaMA-7B(2023)6.7B1T4.02e22465149.3
Llama 3 405B(2024)405B15.6T3.79e25438,75038.5
Llama 3 8B(2024)8B15T7.20e238,3331,875.0

几个核对:GPT-3 的 3.15×10233.15 \times 10^{23} 和第 1 讲引用的约 3.1×10233.1 \times 10^{23} 一致;PaLM 论文的算力表给 540B 的是 2527.2 ZFLOPs(=2.53×1024= 2.53 \times 10^{24}),Gopher 504.0、Chinchilla 588.0 ZFLOPs;Llama 3 论文报告 405B 用了 3.8×10253.8 \times 10^{25} FLOPs。

最后一列是这一讲的主角。 2020–2021 年的旗舰模型每个参数只看了 1–2 个 token;Chinchilla 是 20;LLaMA 把小模型推到 150;Llama 3 8B 接近 2000。为什么这个比例在三四年里变了上千倍?§5、§6、§9.3 一步步回答。


4. 一个”知道熵”的玩具世界 · A toy world with known entropy

在真实语料上做规模定律实验有一个根本的不便:你永远不知道 EE 是多少。拟合出一个 E=1.69E = 1.69,它是”英语的熵”吗?还是拟合的副产品?没法检查。所以这一讲的实验换了一个世界。

4.1 合成语言:熵可以精确算出来

代码 02 演示 1 和模块 scaling_tools.py 造了一个合成语言:

  • 词表:300 个”音节词”,每个由 1–3 个”辅音 + 元音”音节拼成(例如 mozimi、fu)。字母表只有 21 个字符(空格 + 15 个辅音 + 5 个元音)。
  • 词与词之间:一阶马尔可夫链。下一个词有一半的概率来自”背景”分布(Zipf:第 kk 常见的词概率 ∝1/k1.2\propto 1/k^{1.2}),另一半来自当前词”偏爱的两个后继词”(像真实语言里的搭配)。
piheba givu sotuki ro veso gesafe piheba givu zenado fu vaziko lemono dago levupi fu geri fu suz

最常见的词 piheba 占 12.8%,最罕见的只占约 0.013%——典型的长尾。

为什么熵能精确算?字符串和词序列一一对应(空格把词分开),所以

E=每个词的熵率每个词平均占的字符数=∑iπi H(P(⋅∣i))∑iπi (leni+1),E = \frac{\text{每个词的熵率}}{\text{每个词平均占的字符数}} = \frac{\sum_i \pi_i\, H\big(P(\cdot \mid i)\big)}{\sum_i \pi_i\, (\text{len}_i + 1)} ,

其中 π\pi 是马尔可夫链的平稳分布。代码算出:每个词 4.1615 bit,平均 5.3889 个字符(含空格),E=0.7722E = 0.7722 bit/字符。一个”知道生成过程”的真实模型在验证文本上的编码长度是 0.7681 bit/字符——和 EE 只差抽样噪声。(评测时只在每个 32 字符窗口的后 16 个位置算损失,保证每个位置都看得到上一个完整的词,所以任何模型的最好成绩恰好是 EE。)

这个语言的规律有三层:字母层(辅音元音交替)、词层(300 个词怎么拼)、词间层(搭配)。字符级 n-gram 能走多远?

模型bit/字符
均匀分布4.3923
1-gram3.9842
2-gram2.6096
3-gram1.7401
4-gram1.1693
5-gram0.9144
熵率 EE0.7722

每加一阶降得越来越少(1.37、0.87、0.57、0.25)。5-gram 只看 4 个字符,看不全长词,更看不到上一个词——数据再多也到不了 EE。

4.2 扫描训练:损失随 N 和 D 的变化

接下来是规模定律实验的标准做法:训练很多个模型,每个改变一个规模变量,记下最后的损失。代码 02 演示 2 训练了 6 种宽度(dmodel=8d_{\text{model}} = 8 到 64,层数固定为 2,参数量从 2,184 到 103,488)× 4 种数据量(0.25M 到 2M 个字符),一共 24 次训练(第一次运行约 2 分钟,之后读缓存)。每次训练按顺序读数据、每个 token 只读一遍(和真实 LLM 的”单遍训练”一样),学习率按余弦调度、调度长度等于训练长度。

验证损失(bit/字符):

宽度 dd总参数 NNDD = 0.25M0.5M1M2M
82,1842.47772.13891.88921.8344
167,4402.40541.79901.39361.1560
2415,7681.90991.38911.17291.0738
3227,1682.18541.39651.07311.0117
4859,1841.87971.18150.98990.9065
64103,4881.76431.14990.96270.8880

(熵率 E=0.7722E = 0.7722。这些算力 C=6NDC = 6ND 从 3.3×1093.3 \times 10^9 到 1.2×10121.2 \times 10^{12} FLOPs,跨 2.6 个数量级;GPT-3 是 3×10233 \times 10^{23}。)

读这张表的三个要点:

  1. 两个资源都有用。 同一行(固定 NN),数据越多越好,没有例外;同一列(固定 DD),D≥1D \ge 1M 时越宽越好。
  2. 一个资源的回报取决于另一个。 从 1M 到 2M,最窄的模型”还没学会的部分” L−EL - E 只减少了 5%(1.117 → 1.062)——它的容量已经是瓶颈,再多数据也没用;最宽的模型减少了 39%(0.191 → 0.116)。这种”两个瓶颈此消彼长”正是 Kaplan 的 L(N,D)L(N, D) 公式(§5.3)和 Chinchilla 的 E+A/Nα+B/DβE + A/N^\alpha + B/D^\beta(§6)要描述的。
  3. 最好的一格离 EE 还有 0.12。 我们的模型和数据都太小,整张表都在”能学的还很多”的区域。

4.3 两个切片

固定一个变量、看另一个变量,就得到 Kaplan 式的单变量曲线。代码 02 演示 3 算了相邻点在 log-log 图上的局部斜率:

  • 固定 DD = 2M,改变 NN:LL 的局部斜率从 0.38 降到 0.04——曲线是弯的;减掉 EE 以后,L−EL - E 的斜率在 0.27–0.83 之间跳动、没有一路变小的趋势。弯曲主要来自 EE(§2.2),跳动来自噪声(§4.4)。
  • 固定 NN = 103,488,改变 DD:L−EL - E 的局部斜率是 1.39、0.99、0.72,一路变小——固定 NN 时,DD 越大,“还没学会的部分”里”容量不够”的那一块占的比例越大,损失趋向的不是 EE,而是”EE + 容量不够造成的损失”。

两个方向的指数都比真实 LLM 大一个数量级(Kaplan:αN≈0.076\alpha_N \approx 0.076、αD≈0.095\alpha_D \approx 0.095)。我们的语言只有 300 个词,“能学的东西”有限、学得也快;真实语言的长尾长得多。这是玩具和真实世界在量级上的差别,机制是一样的。

4.4 噪声与”小数据区”

两个不那么光鲜、但很重要的观察:

  • 噪声。 代码 02 演示 4 把两个设定换了一个初始化种子重训:d=48d = 48、D=0.5D = 0.5M 时损失差 0.021,d=16d = 16、D=0.5D = 0.5M 时差 0.131。Kaplan et al. 估计他们的种子波动约为 0.02 nats/token。我们的小模型、短训练噪声大得多——相邻两个宽度只差 2 倍左右,一点随机波动就能让局部斜率变很多。所以没有人用”两点连线”估指数,而是用很多点一起拟合。
  • 小数据区。 D=0.25D = 0.25M 那一列只有 244 步训练,所有模型都离 EE 很远(L−EL - E 最小也有 0.99),排序也不规则(d=32d = 32 不如 d=24d = 24):训练还在剧烈变化,谁先”开窍”有很大的偶然性。这正是 Hestness et al. 说的小数据区。拟合规模定律时要排除这样的点,或者保证每个点都训练得足够——代码 03、04 都只用 D≥0.5D \ge 0.5M 的点。

5. Kaplan et al. (2020) 的发现 · Kaplan’s findings

Kaplan et al. 的 Scaling Laws for Neural Language Models 是 Winter 2023 阅读清单上唯一的规模定律论文。他们在 WebText2(约 2.29×10102.29 \times 10^{10} 个 token)上训练了从 768 到 15 亿个非嵌入参数的 Transformer,用 Adam(最大的几个模型用 Adafactor)、batch 512 × 1024 token、固定 2.5×1052.5 \times 10^5 步、3000 步热身后余弦衰减到 0。论文开头的要点可以归纳成下面几条。

5.1 平滑的幂律

只受一个变量限制时(另外两个足够多),损失是那个变量的幂律,跨 6 个以上数量级:

L(N)=(NcN)αN,L(D)=(DcD)αD,L(Cmin⁡)=(Ccmin⁡Cmin⁡)αCmin⁡L(N) = \left(\frac{N_c}{N}\right)^{\alpha_N},\quad L(D) = \left(\frac{D_c}{D}\right)^{\alpha_D},\quad L(C_{\min}) = \left(\frac{C_c^{\min}}{C_{\min}}\right)^{\alpha_C^{\min}}

其中 αN≈0.076\alpha_N \approx 0.076(Nc≈8.8×1013N_c \approx 8.8 \times 10^{13} 个非嵌入参数),αD≈0.095\alpha_D \approx 0.095(Dc≈5.4×1013D_c \approx 5.4 \times 10^{13} token),αCmin⁡≈0.050\alpha_C^{\min} \approx 0.050(Ccmin⁡≈3.1×108C_c^{\min} \approx 3.1 \times 10^8 PF-days)。注意这些式子没有不可约项——在他们的范围里,损失离”下限”还远,纯幂律够用;但这也意味着它们不能无限外推(§9.4)。

L(N)L(N) 是在”数据足够、提前停止”的条件下量的,L(D)L(D) 是在”模型足够大、提前停止”的条件下量的——都是为了让另一个资源不成为瓶颈。我们在 §4.3 看到了不这样做的后果:固定 DD 的切片趋向的不是 EE。

5.2 形状不太重要——在合理的范围内

Kaplan 的第一条要点是”性能强烈依赖规模,微弱依赖形状”:参数量固定时,层数、宽度、注意力头数在很宽的范围内改变,损失只变几个百分点。这一点很重要:它意味着规模定律可以只用一个数 NN 来描述模型,不必关心它的形状。

我们的玩具给了一个反例(代码 04 演示 1,D=1D = 1M,非嵌入参数都在约 2.5–2.9 万):

层数宽度宽度/层数非嵌入参数损失
1484828,3681.0032
2321625,4721.0731
424628,9441.1620
816226,2721.3405

最好和最差差了 0.34 bit/字符,越深越窄越差。这和 Kaplan 矛盾吗?不完全是:Kaplan 的例子里,(nlayer,dmodel)=(6,4288)(n_{\text{layer}}, d_{\text{model}}) = (6, 4288) 和 (48,1600)(48, 1600) 的损失只差 3%,宽度/层数分别约为 700 和 33,他们说这个比值变 40 倍对表现影响很小——但那是在几十到几百的范围里,我们的比值只有 2–48;我们的学习率只按宽度调过;每个模型只训练了 977 步(越深的网络往往越需要更多步数和更小心的学习率)。Winter 2022 笔记也提醒过另一端:1 层和 2 层的差别非常大,层数很少时形状确实重要。教训是:“形状不重要”是一个有适用范围的经验规律;做规模扫描时要一次只变一个东西(我们的扫描固定 2 层、只改宽度),否则”大模型更好”里会混进”形状更好”或”更好优化”。

5.3 L(N, D)、过拟合与样本效率

同时受 NN 和 DD 限制时,Kaplan 用的形式是

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

它描述了 §4.2 看到的”两个瓶颈”:NN 很大时退化成 L(D)L(D),DD 很大时退化成 L(N)L(N)。由它得到一个”多少数据才不过拟合”的经验式:D≳5×103⋅N0.74D \gtrsim 5 \times 10^3 \cdot N^{0.74}——数据需要的增长比参数慢(次线性)。他们据此说,10 亿参数以下的模型在 22B token 的 WebText2 上训练几乎不会过拟合。

另外两条要点和后面的故事密切相关:

  • 大模型的样本效率更高:达到同样的损失,大模型需要的训练步数和数据都更少。
  • “训练到收敛”是低效的:给定算力,最好的做法是训练一个很大的模型,在收敛之前很久就停下。Winter 2022 笔记把这句话写成”properly undertrained models are better”——恰当地训练不足的模型更好。

5.4 计算最优:N ∝ C^0.73

把”给定算力怎样分配”写成公式,Kaplan 得到:

Nopt∝C0.73,B∝C0.24,S∝C0.03,N_{\text{opt}} \propto C^{0.73},\quad B \propto C^{0.24},\quad S \propto C^{0.03},

(BB 是 batch 大小,SS 是步数,D=BS∝C0.27D = BS \propto C^{0.27}。)算力增加时,绝大部分应该花在更大的模型上,步数几乎不变。按 Chinchilla 论文的转述:算力乘以 10,模型应该乘以约 5.5,数据只乘以约 1.8(代码 05 演示 2 按指数直接算:× 5.37 和 × 1.86)。

这个结论深刻地影响了 2020–2021 年的大模型:GPT-3(175B / 300B token)、Jurassic(178B / 300B)、Gopher(280B / 300B)、MT-NLG(530B / 270B)——参数一路涨到 5000 亿,数据却一直停在 3000 亿上下(数字来自 Chinchilla 论文表 1)。代码 05 演示 2 (c) 按 Kaplan 表 6 的公式 Nopt=1.3×109⋅C0.73N_{\text{opt}} = 1.3 \times 10^9 \cdot C^{0.73}(CC 以 PF-day 计)算了一下:在 GPT-3 的算力预算上,它建议的是一个 518B 参数、只读 101B token 的模型——比 GPT-3 还大。

Kaplan 也知道这些公式不能无限外推:L(Cmin⁡)L(C_{\min}) 下降得比 L(D)L(D) 能支持的更快,两条线在大约 C∗∼104C^* \sim 10^4 PF-days、N∗∼1012N^* \sim 10^{12} 参数、D∗∼1012D^* \sim 10^{12} token、L∗∼1.7L^* \sim 1.7 nats/token 处相交,“规模定律必然在那之前失效”——他们特别说明这个点的不确定性有一个数量级。


6. Chinchilla:重新分配算力 · Training compute-optimal models

6.1 结论

2022 年,DeepMind 的 Hoffmann et al. 训练了 400 多个语言模型(7000 万到 160 亿参数、50 亿到 5000 亿 token),重新回答”给定算力,NN 和 DD 怎样分配”。结论和 Kaplan 很不一样:

  • 模型大小和训练 token 数应该等比例增长:Nopt∝CaN_{\text{opt}} \propto C^{a},Dopt∝CbD_{\text{opt}} \propto C^{b},a≈b≈0.5a \approx b \approx 0.5。算力乘以 10,参数和数据各乘以约 3.16。
  • 当时的大模型都”训练不足”(undertrained):在它们的算力下,应该用小得多的模型、读多得多的数据。
  • 为了验证,他们用 Gopher(280B / 300B token)的算力训练了 Chinchilla:70B 参数、1.4T token。Chinchilla 在几乎所有评测上都超过了 Gopher(MMLU 平均 67.5%,比 Gopher 高 7 个百分点以上);模型小了 4 倍,推理和微调也便宜得多。

“每个参数约 20 个 token”这条广为流传的经验法则来自哪里?论文本身没有这样说。它来自 Chinchilla 本身(70B × 20 = 1.4T),以及论文表 3 的外推结果——代码 05 演示 2 (a) 把表 3 的每一行算了一下”token/参数”:

参数FLOPstokentoken/参数
1B1.21e2020.2B20.2
10B1.23e22205.1B20.5
67B5.76e231.5T22.4
175B3.85e243.7T21.1
1T1.27e2621.2T21.2

每一行都在 20 上下,而且基本不随规模变——这正是 a≈b≈0.5a \approx b \approx 0.5 的含义。按这条法则,GPT-3 的预算应该训练一个约 51B 参数、读约 1T token 的模型(代码 05 演示 2 (c))。

6.2 三种方法

Chinchilla 论文用三种独立的方法估计 Nopt(C)N_{\text{opt}}(C),这是它最值得学的地方。

方法 1:训练曲线的下包络。 固定一组模型大小,每个大小用 4 种不同长度的余弦调度训练。把所有训练曲线画在”损失 vs FLOPs”图上,在每个 FLOPs 处取所有曲线的最低点,就得到”这个算力下能达到的最好损失”以及达到它的模型大小。

方法 2:IsoFLOP 曲线。 选 9 个算力预算(从 6×10186 \times 10^{18} 到 3×10213 \times 10^{21} FLOPs),每个预算下训练一串不同大小的模型(数据量 D=C/6ND = C/6N 相应变化),画”损失 vs log⁡N\log N”:

损失
 │ ╲                         ╱      ← 模型太大:数据太少、步数不够
 │   ╲                     ╱
 │     ╲                 ╱
 │       ╲___      ____╱           ← 谷底:这个算力下的计算最优模型
 │           ‾‾‾‾‾‾
 │  模型太小:容量不够,读再多数据也学不会
 └──────────────────────────────── log N(同时 D = C/6N 在减小)

每条曲线是一个山谷,在谷底附近拟合一条抛物线,顶点就是 Nopt(C)N_{\text{opt}}(C)。再把 9 个谷底在 log-log 图上连成直线,斜率就是 aa。

方法 3:参数化拟合。 用所有实验点直接拟合

L(N,D)=E+ANα+BDβ.L(N, D) = E + \frac{A}{N^\alpha} + \frac{B}{D^\beta} .

三项的含义很清楚:EE 是不可约损失(理想的生成过程的熵),A/NαA/N^\alpha 是”模型容量有限”造成的损失,B/DβB/D^\beta 是”数据有限、没训练到底”造成的损失。他们在对数空间用 Huber 损失(δ=10−3\delta = 10^{-3})和 L-BFGS 拟合,得到 E=1.69E = 1.69、A=406.4A = 406.4、B=410.7B = 410.7、α=0.34\alpha = 0.34、β=0.28\beta = 0.28。

有了这个式子,计算最优分配可以直接推出来。把 D=C/(6N)D = C/(6N) 代入,对 NN 求导令其为 0:

αAN−α=βBD−β⟹Nopt=G(C6)βα+β,Dopt=G−1(C6)αα+β,G=(αAβB)1α+β.\alpha A N^{-\alpha} = \beta B D^{-\beta} \quad\Longrightarrow\quad N_{\text{opt}} = G \left(\frac{C}{6}\right)^{\frac{\beta}{\alpha + \beta}},\quad D_{\text{opt}} = G^{-1} \left(\frac{C}{6}\right)^{\frac{\alpha}{\alpha + \beta}},\quad G = \left(\frac{\alpha A}{\beta B}\right)^{\frac{1}{\alpha + \beta}} .

所以 a=β/(α+β)a = \beta / (\alpha + \beta),b=α/(α+β)b = \alpha / (\alpha + \beta),a+b=1a + b = 1。直觉:最优点上,两项的”边际收益”相等(第一个等式)。哪一项的指数更小、下降得更慢,它就越会成为瓶颈,就该分到更多的资源——β\beta 小(数据项下降慢)意味着 bb 大,要多给数据。

三种方法的结果(论文表 2):

方法aa(Nopt∝CaN_{\text{opt}} \propto C^a)bb(Dopt∝CbD_{\text{opt}} \propto C^b)
1. 训练曲线下包络0.500.50
2. IsoFLOP 曲线0.490.51
3. 参数化拟合0.460.54
Kaplan et al. (2020)0.730.27

三种方法彼此接近,和 Kaplan 差得很远。论文也注意到了局限:高算力端的 log⁡Nopt\log N_{\text{opt}} 有一点凹(说明幂律可能高估了大算力下的最优模型),而且大规模上只有 Chinchilla 和 Gopher 两次可比较的训练。

6.3 在玩具上走一遍三种方法

代码 04 演示 2 在合成语言上做了同样的事。为了让 IsoFLOP 曲线的”小模型一侧”也有点,几个窄模型额外训练了 4M、8M token。每个预算下,从每个宽度的”损失 vs DD“曲线上读出 D=C/6ND = C/6N 处的损失(对数坐标插值,不外推),拟合抛物线:

算力 CC曲线上的点(宽度:损失)抛物线谷底 NoptN_{\text{opt}}
5.66e10d8: 1.781,d16: 1.307,d24: 1.33010,093
1.13e11d16: 1.138,d24: 1.146,d32: 1.23310,333
2.26e11d24: 1.062,d32: 1.044,d48: 1.11124,895
3.20e11d24: 1.039,d32: 1.013,d48: 1.017,d64: 1.14132,052
6.40e11d32: 0.969,d48: 0.919,d64: 0.95954,828

(表中是 8 个预算里的 5 个;有一个预算的谷底落在采样范围之外,没有使用。)每一行都是一个山谷:太窄的模型读了很多数据也学不会,太宽的模型只读了很少的数据。谷底随算力右移:最好的宽度从 d=16d = 16 移到 32、再到 48。三种方法给出的指数:

我们的玩具Chinchilla 论文
方法 1(每个算力下最好的网格模型)0.990.50
方法 2(IsoFLOP 抛物线谷底)0.800.49
方法 3(参数化拟合,23 个点)0.640.46

两点值得说清楚。第一,我们的三种方法彼此差得多(0.64–0.99):每条 IsoFLOP 曲线只有 3–4 个点,相邻宽度的参数量差 2 倍左右,谷底的位置是”一步一步跳”的;方法 1 只能在 6 个宽度里挑,最粗糙。Chinchilla 每条 IsoFLOP 曲线上都有一串密集的模型,所以三种方法能互相印证。第二,玩具里 a>0.5a > 0.5,计算最优点的 token/参数在 35–177 之间(大算力端 36–61),都和真实 LLM 的”约 0.5、约 20”不同。原因是两个世界的指数不同:代码 03 演示 2 的联合拟合给出 β≈1.36>α≈0.58\beta \approx 1.36 > \alpha \approx 0.58——在玩具里,数据项下降得快,不是瓶颈,所以多给参数。数字不能搬,方法可以:同样的拟合和推导,换一个世界就给出那个世界的答案。

6.4 为什么 Kaplan 和 Chinchilla 不一样?

同样是 Transformer 语言模型,为什么一个说 0.73、一个说 0.5?Chinchilla 论文给了两个解释,后来的复现又加了几个。

(1) 学习率调度没有和训练长度匹配(Chinchilla 的主要解释)。 Kaplan 的所有模型都用同一个长调度(固定步数、余弦衰减),然后在训练中途读损失,当作”训练这么多 token”的结果。但中途检查点的学习率还很高,模型没有经过”退火”(学习率降下来时损失会再降一截),损失被高估了。Chinchilla 的附录发现:余弦周期比实际训练长 25% 以上,最终损失就明显变差。用这些中途损失来拟合,“读的数据比调度长度少”的配置都显得比实际差,而且停得越早被高估得越多;这个偏差随算力变化,最终让结论偏向”算力增加时模型应该比数据长得更快”(练习 9 分析了这个机制)。

代码 04 演示 3 在玩具上复现了这个现象。每个宽度的 2M token 训练在途中读了几次损失,和”调度长度就等于那么长”的训练比较(中途检查点 − 匹配调度,6 个宽度平均):

停在调度的12%(0.25M)25%(0.5M)50%(1M)
平均差−0.1185+0.1026+0.1307

走到四分之一和一半时,中途检查点平均差 0.1 bit 以上——和 Chinchilla 的观察一致。走到八分之一时反而是中途检查点更好:那个匹配调度的训练只有 244 步,学习率很快就降下来了,还没学会多少就”减速”了(玩具步数太少造成的,真实训练不会这么短)。用中途检查点拟合,得到的是另一条”规模定律”:

数据来源(同样的格子,D≥0.5D \ge 0.5M)EEα\alphaβ\betaa=β/(α+β)a = \beta/(\alpha+\beta)
匹配调度(Chinchilla 式)0.6780.5751.3630.703
中途检查点(Kaplan 式)0.0000.6590.3330.336

(真值 E=0.7722E = 0.7722。)误差不是一个常数偏移,而是随”走了多少”变化,所以它改变了曲线的形状:EE 掉到 0,数据指数小了很多,推出的分配完全不同。在我们的玩具里偏差的方向和 Chinchilla 描述的相反(aa 变小了),但”调度不匹配会系统地歪曲拟合”这一点是一样的。

(2) 规模偏小。 Kaplan 的模型大多在 1 亿参数以下;Chinchilla 的多数模型超过 5 亿。如果真实的 log⁡Nopt\log N_{\text{opt}}–log⁡C\log C 关系有一点弯曲,在小规模上量出的斜率就和大规模不同。

(3) 参数怎么数。 Kaplan 用非嵌入参数(不算词嵌入和位置嵌入),Chinchilla 用总参数。Pearce & Song (2024) 认为这是分歧的一大来源:小模型里嵌入占的比例大,不算嵌入,小模型就显得”更小”,参数量的跨度被拉大;他们模拟发现,在 Kaplan 的数法和规模下会得到接近 0.73 的系数,并建议今后一律用总参数和总算力。代码 04 演示 4 在玩具上看到了同方向的效应:嵌入在最窄的模型里占 19.4%、最宽的只占 3.3%;IsoFLOP 推出的指数从 0.80(总参数)变成 0.86(非嵌入参数)。

(4) 2024 年的再审视。 Porian et al. (2024) 系统地复现了两边的设置,把差别归结为三个因素:最后一层(输出层)的计算量怎么算、热身(warmup)的长度、以及优化器超参数有没有随规模重新调(小 batch 时调 AdamW 的 β2\beta_2 很关键)。修正之后,他们得到了和 Chinchilla 非常一致的结果;有意思的是,他们发现仔细的学习率衰减并不是 Chinchilla 定律成立的必要条件——也就是说,解释 (1) 可能不是主要原因。

这一段历史本身就是一个教训:规模定律的结论对实验细节非常敏感。参数怎么数、算力怎么数、学习率调度、热身、每个规模的超参数,任何一个没处理好,都会系统地改变外推的结果——而外推的结果决定了几千万美元花在哪里。


7. 怎样拟合和外推一条规模定律 · Fitting and extrapolating

7.1 拟合的流程

一个标准的流程:

  1. 选函数形式。 单变量用 E+Ax−αE + A x^{-\alpha};两个变量用 E+A/Nα+B/DβE + A/N^\alpha + B/D^\beta(或 Kaplan 的形式)。不要省略 EE,除非你确定离下限还很远。
  2. 在对数空间里算误差。 损失跨的范围很大,直接在线性空间里最小二乘,误差会被最大的那些点主导。Chinchilla 最小化的是 log⁡L^−log⁡L\log \hat{L} - \log L 的 Huber 损失。
  3. 小心非凸。 指数出现在幂上,目标函数是非凸的,不同初始值会收敛到不同的点。Chinchilla 从一个初始值网格出发跑 L-BFGS。我们的代码(scaling_tools.py)用了一个更简单的办法——变量投影(variable projection):指数 (α,β)(\alpha, \beta) 一旦固定,模型对 (E,A,B)(E, A, B) 是线性的,可以直接解;于是只需在指数的网格上搜索,确定、不需要初始值。
  4. 排除不属于”幂律区”的点。 训练太短的点(小数据区)、明显没训练好的点,不要放进去(§4.4)。
  5. 报告不确定性。 换一个子集、换一个种子、bootstrap,看参数变多少。

7.2 外推:成功与失败

代码 03 在玩具上做了一个”假装还没训练大模型”的实验:只用 d≤32d \le 32 的四个宽度拟合,预测 d=48d = 48、64。

先看只拟合一个切片会怎样(代码 03 演示 1)。固定 D=2D = 2M、用全部 6 个宽度拟合 L(N)=E+AN−αL(N) = E + A N^{-\alpha},得到 E=0.8611E = 0.8611;固定 d=64d = 64 拟合 L(D)L(D),得到 E=0.8602E = 0.8602。两个”下限”都比真值 0.7722 高——不是拟合坏了,而是问题问错了:固定 DD 时,N→∞N \to \infty 的极限是”EE + 数据不够造成的损失”,不是 EE。

再看联合拟合(代码 03 演示 2)。用 18 个点(6 个宽度 × D≥0.5D \ge 0.5M)拟合 E+A/Nα+B/DβE + A/N^\alpha + B/D^\beta:E=0.6781E = 0.6781(真值 0.7722,低了约 12%),α=0.575\alpha = 0.575,β=1.363\beta = 1.363。18 个残差里 14 个在 ±0.05 以内;最大的两个都在 d=16d = 16 那一行——恰好是噪声最大的设定。

外推(代码 03 演示 3):

模型实际单切片 + 下限单切片纯幂律联合拟合
d=48d = 48,D=1D = 1M0.9899——1.0106
d=48d = 48,D=2D = 2M0.90651.00180.79170.8990
d=64d = 64,D=1D = 1M0.9627——0.9737
d=64d = 64,D=2D = 2M0.88800.99560.69360.8620
d=64d = 64,D=0.5D = 0.5M1.1499——1.2701
  • 单切片的两种做法错在相反的方向:带下限的拟合把”曲线在 d≤32d \le 32 变平”当成了”快到下限了”(它拟合出 E=0.9898E = 0.9898),预测偏高约 0.1;纯幂律假设曲线永远是直线,预测偏低 0.1–0.2。
  • 联合拟合在 D≥1D \ge 1M 的四格上平均误差只有 0.016,和种子噪声相当——用上两个方向的全部信息,比只看一个切片可靠得多。但在 D=0.5D = 0.5M 上偏高约 0.12:那里只有 488 步,训练还在快速变化,大模型在那里的表现和小模型不一样,小模型的数据给不出它的形状。外推只在”和拟合数据同一个区域”里可靠。

再往外推。 纯幂律在 N≈N \approx 65,742 时就预测出低于熵率的损失——这在信息论上是不可能的(第 1 讲 §2.4)。联合拟合的下限是 0.708,也比真值低:NN 很大时它同样预测出低于 EE 的损失,只是错得少得多。“损失最终停在哪里”是外推里最不可靠的部分。

7.3 外推为什么这么脆弱

代码 03 演示 4 把脆弱性拆开来看:

(a) EE 和 α\alpha 互相抵消。 把 L(N)L(N) 切片的下限 EE 固定成不同的值,再拟合 AA、α\alpha:

固定的 EE拟合出的 α\alpha对数误差 rmse预测 N=106N = 10^6 时的 LL
0(纯幂律)0.1790.08330.5380
0.60.4040.05740.6929
0.7722(真值)0.6270.03610.7939
0.850.8050.02670.8569

除了 E=0E = 0 明显更差,其余几行的 rmse 只差几个百分点(0.0574 到 0.0267),和种子噪声(代码 02 演示 4:0.021–0.131 bit/字符)同一个量级;指数却从 0.4 变到 0.8,对 N=106N = 10^6 的预测从 0.69 变到 0.86。范围窄时,“下限高、指数大”和”下限低、指数小”几乎一样好——参数不可辨识。这个切片上误差最小的反而是偏高的 EE(它把”数据不够”的那一块也算进了下限)。

(b) 少一个点,结论就变。 联合拟合时去掉 6 个宽度中的一个,β\beta 在 1.15–1.56 之间变,推出的分配指数 aa 在 0.66–0.73 之间变,EE 在 0.64–0.72 之间——6 次拟合的 EE 全都低于真值 0.772。

(c) 和噪声比。 只换初始化种子,d=16d = 16、D=0.5D = 0.5M 的损失就从 1.7990 变成 1.6678。

把这些和真实研究对照:Chinchilla 用了 400 多次训练;Besiroglu et al. (2024) 重新分析 Chinchilla 的方法 3,发现论文报告的置信区间窄得不合理(他们估计要 60 万次以上的实验才可能那么窄),重新拟合后得到 E=1.8172E = 1.8172、A=482.01A = 482.01、B=2085.43B = 2085.43、α=0.3478\alpha = 0.3478、β=0.3658\beta = 0.3658,推出约 20 token/参数,和方法 1、2 一致——而原来的拟合推出的比例要大得多。代码 05 演示 3 还展示了一个更小的细节:只把指数从两位小数(0.34、0.28)换成未四舍五入的值(0.3392、0.2849),在 Gopher 的算力上推出的最优模型就从 32.2B 变成 40.3B,token/参数从 92.6 变成 59.1。外推对指数极其敏感,报告拟合结果时要给足位数和不确定性。

总结起来,一条规模定律会以这些方式失败:

失败方式后果本讲的例子
没有下限项外推到足够远,一定会预测出不可能的损失代码 03 演示 3 (c)
只看一个切片下限偏高,混进了另一个资源的瓶颈代码 03 演示 1
范围窄、点少EE 和指数不可辨识;少一个点结论就变代码 03 演示 4
包含”小数据区”的点曲线形状被训练初期的剧烈变化扭曲代码 02 演示 2
学习率调度不匹配曲线形状被系统地歪曲代码 04 演示 3
超参数没有随规模重新调某一端的模型吃亏,指数被歪曲lr_for_width;Porian et al. 2024
参数 / 算力的数法不一致指数改变代码 04 演示 4
噪声单次训练的差别不可信代码 02 演示 4
外推到另一个”区域”小模型给不出大模型在那里的行为代码 03 演示 3 的 D=0.5D = 0.5M

Winter 2022 的笔记引用了 Levine et al. (2021) 的一个提醒:“规模定律有时会把我们引入歧途”——当规模定律被用来做设计决策时,它本身的偏差会被固化进模型里。


8. 规模定律拿来做什么 · What scaling laws are used for

8.1 预测一次大训练

最直接的用途:开始一次昂贵的训练之前,先知道它大概会到哪里。GPT-4 技术报告(2023)专门有一节”可预测的规模”(predictable scaling):他们用带不可约项的幂律 L(C)=aCb+cL(C) = aC^b + c,从用的算力最多只有 GPT-4 万分之一的模型,在训练开始后不久就预测了 GPT-4 的最终损失;还用最多千分之一算力的模型预测了 HumanEval 编程题上的通过率(用”平均对数通过率”这个光滑的指标)。Llama 3(2024)先在 6×10186 \times 10^{18} 到 102210^{22} FLOPs 之间做 IsoFLOP 实验,再外推到 3.8×10253.8 \times 10^{25} FLOPs 来决定旗舰模型的大小(§11)。

8.2 选超参数

Winter 2022 笔记的”模型工程”部分强调:规模定律让我们能在小模型上回答”大模型该怎样训练”:

  • 优化器:Hestness et al. 比较了 Adam 和 SGD 各自的规模曲线;
  • 深度:多少层之后收益递减;
  • batch 大小:Kaplan 发现”临界 batch 大小”随损失下降而增大(Bcrit∝L−1/αBB_{\text{crit}} \propto L^{-1/\alpha_B},αB≈0.21\alpha_B \approx 0.21),最大的模型收敛时约 100–200 万 token——这解释了为什么大模型可以用越来越大的 batch,对数据并行(第 9 讲)是好消息;
  • 学习率:最优学习率随模型变大而变小。我们的代码也遇到了这一点:写代码前的学习率扫描发现,宽度 64 的模型在 0.04 的学习率下明显变差,所以 lr_for_width 让更宽的模型用更小的学习率。2022 年提出的 μP(maximal update parametrization)等方法试图让超参数在不同宽度之间直接”搬过去”。

8.3 比较架构和数据:比曲线,不比单点

在一个规模上 A 比 B 好,不代表在大规模上也好。正确的比较是比两条规模曲线:

  • 如果两条线平行,A 永远好一个常数倍——“A 更好”可以外推;
  • 如果两条线斜率不同,它们会在某处相交——小规模上的赢家可能是大规模上的输家。

Kaplan 用这种方法比较了 Transformer 和 LSTM:Transformer 的优势随规模扩大,差别主要来自上下文后部的 token——LSTM 用不好长上下文。Winter 2022 笔记还提到一个关于数据的观察:数据的构成主要改变曲线的偏移(offset),而不是斜率——换一个分布评测,曲线整体上下移动,斜率差不多不变。这让”在小规模上比较数据配方”成为可能(第 2 讲)。

8.4 做预算

给定算力,Nopt(C)N_{\text{opt}}(C) 和 Dopt(C)D_{\text{opt}}(C) 直接告诉你该训练多大的模型、准备多少数据(§6);反过来,给定一个目标损失,规模定律告诉你大约要多少算力。Winter 2022 笔记的问题”更大的模型还是更多的数据?买更多 GPU 还是收集更多数据?“就是在问这个。

8.5 预测能力——以及它的边界

Winter 2022 笔记的最后一部分把规模定律用在了一个更大胆的问题上:更大的语言模型能解决所有问题吗? 方法是:对每个任务画”准确率 vs 规模”的曲线,再延长它。例子:GPT-3 在 Winograd 指代消解上(50 个示例)是 77%,按这条线外推,“大约再大 64 倍”就能到人类水平;SAT 类比题在对数坐标下也是一条清楚的直线。但也有不乐观的曲线:WiC(判断一个词在两个句子里是否同义)几乎不随规模变化。还有一类更奇怪的:在某个规模附近突然跳上去——笔记称之为”相变”(phase transitions)。下游任务上的这些现象,正是第 5 讲”涌现”的主题。


9. 局限 · Limits

9.1 损失 ≠ 下游能力

规模定律描述的是预训练损失,一个平均到每个 token 的光滑量。我们真正关心的往往是下游任务的准确率,而后者可以和损失很不一样:

  • 一个需要好几步都对才算对的任务(多位数加法、exact match),在损失平稳下降时,准确率可能长期接近 0,然后在某个规模附近快速上升;
  • PaLM 论文发现,在 BIG-bench 的约 25% 的任务上,从 62B 到 540B 的提升远远超过从 8B 到 62B 的趋势外推(§10)。

这些”涌现能力”是真实的现象,还是评价指标造成的错觉?第 5 讲专门讨论。一个实用的做法是 Llama 3 用过的两步法:先用规模定律预测一个光滑的量(正确答案的对数似然),再把它映射到准确率(GPT-4 则直接预测”平均对数通过率”这种光滑的量)。

9.2 数据受限:重复几遍还值得吗?

Chinchilla 的建议有一个隐含前提:数据是无限的,每个 token 都是新的。可是按”约 20 token/参数”,一个 1T 参数的模型就要约 20T token——高质量的公开文本没有那么多。数据不够时,只能把同样的数据读好几遍。

Muennighoff et al. (2023) 做了 400 次训练(最大 90 亿参数、最多 9000 亿 token)研究这个问题。结论:在固定算力下,重复到 4 个 epoch,损失和全部用新数据几乎没有差别(8.7B 的模型 4 个 epoch 只比单遍高 0.5%);之后重复的价值迅速衰减,直到几乎为零。他们提出了”有效数据量”的公式:

D′=U+U⋅R∗(1−e−R/R∗),D' = U + U \cdot R^* \left(1 - e^{-R / R^*}\right),

UU 是不重复的 token 数,RR 是重复次数(epoch − 1),拟合得到 R∗≈15.4R^* \approx 15.4。代码 05 演示 5 算了一下:

epoch 数有效 token(× U)平均每个 token 值多少
43.7393.1%
1610.5866.1%
4015.1737.9%
∞16.39→ 0

无论重复多少遍,有效数据最多只有 UU 的约 16 倍。他们还发现,数据受限时多出来的算力应该更多地花在”多读几遍”上而不是加参数;混入代码数据可以让有效 token 翻倍。这把规模定律从两个资源变成了三个(参数、不重复的数据、重复次数),也和第 2 讲的去重、数据质量问题直接相关。

9.3 推理成本:为什么要”过度训练”小模型

Chinchilla 回答的是”训练算力固定时,怎样得到最低的损失”。但一个模型训练出来之后要被用很多次,每次推理每个 token 约 2N2N 次浮点运算——模型越大,每次使用越贵。如果一个模型要服务大量请求,总成本里推理可能远大于训练。

Sardana & Frankle (2023) 把推理成本加进了 Chinchilla 的式子:对预期有大量推理需求(约 10 亿次请求)的模型,应该训练比 Chinchilla 最优更小、更久的模型;他们的实验里,token/参数一直到 10,000 模型仍在变好。代码 05 演示 4 用 Besiroglu et al. 重新拟合的参数做了同样的计算:目标是达到”Chinchilla 预算下计算最优模型”的损失,推理量越大,最省的方案越往”小模型 + 多数据”移:

推理 token 总数最省的 NNDDtoken/参数比”计算最优 + 同样推理”省
072.2B1.33T180.0%
101210^{12}57.1B1.72T302.5%
101310^{13}34.1B3.72T10928.6%
101410^{14}20.9B13.1T62961.2%

这就是 LLaMA 和 Llama 3 的经济学。LLaMA 论文(2023)写道:Hoffmann et al. 建议在 200B token 上训练 10B 的模型,但他们发现 7B 模型在 1T token 之后还在变好——他们关心的是”在给定的推理预算下最好的模型”。Llama 3 的 8B 模型读了超过 15T token,Meta 说它的 Chinchilla 最优量约 200B token,而模型在 15T token 时仍然”按对数线性继续变好”。§3.3 那张表里 token/参数从 20 涨到近 2000,原因就在这里。

9.4 外推的边界

最后,任何规模定律都是一个范围内的经验规律:

  • Kaplan 自己指出,他们的 L(C)L(C) 和 L(D)L(D) 在约 10410^4 PF-days 处必然矛盾(§5.4);
  • Chinchilla 在高算力端看到 log⁡Nopt\log N_{\text{opt}} 的凹性;
  • Llama 3 发现 IsoFLOP 曲线在大算力时谷底越来越平——最优点附近选大一点、小一点的模型,损失差别越来越小(所以他们选了 405B,而不是外推出的 402B);
  • 我们的玩具(§7.2):外推到”另一个区域”(训练步数很少)时误差突然变大。

10. 案例:PaLM 与规模 · Case study: PaLM

1/25 的客座报告来自 PaLM 的作者之一 Aakanksha Chowdhery,题目是 Pathways Language Model (PaLM) and Model Scaling。下面依据 PaLM 论文和 Google 的博客,从”规模”的角度看这个模型;它的训练工程(Pathways、损失尖峰、并行)留给第 10 讲。

PaLM 是一次规模实验。 2022 年 4 月发布,三个大小:8B、62B、540B。540B 是 118 层、宽度 18432、48 个注意力头的 decoder-only Transformer。三个模型用完全相同的数据(780B token,单遍、同样的打乱顺序)和相同的训练设置(除了 batch 大小)训练——这让它们构成了一条干净的规模曲线。540B 在 6144 块 TPU v4 上训练,模型 FLOPs 利用率(MFU)46.2%、硬件 FLOPs 利用率 57.8%,是当时这个规模上最高的(第 8 讲解释这两个数)。

从算力账本看 PaLM(代码 05 演示 1、2):C=6ND≈2.53×1024C = 6ND \approx 2.53 \times 10^{24} FLOPs、29,250 PF-days,每个参数只看了 1.4 个 token——典型的”Kaplan 时代”分配。同样的算力,不同的规则会怎样分配?

规则NNDD
PaLM 实际540B780B
Kaplan 表 62.37T178B
每参数 20 token145B2.9T
Chinchilla 方法 3(原始拟合)62.8B6.71T

PaLM 论文发表时(2022 年 4 月)Chinchilla 刚刚出现(2022 年 3 月)。PaLM 的作者在”规模的开放问题”一节里正面讨论了它:Chinchilla(70B / 1.4T)在相近的算力下大幅超过 Gopher(280B / 300B),说明 Gopher 相对它的大小训练不足;但这些结果还不足以判断 PaLM 540B 该怎样分配。他们提出的问题是:**一个在 7T token 上训练的 62B 模型,和在 780B token 上训练的 540B 模型相比,会怎样?**他们没有做这个实验(太贵),但指出:如果小模型的下游表现相当,它会更好,因为推理成本随模型大小增长——这正是 §9.3 的逻辑。练习 12 用 Chinchilla 的拟合式估算了这个问题。

平滑的规模与”不平滑”的能力。 PaLM 的规模结果同时展示了两面:

  • 平均来看,规模的回报是平滑的、对数线性的:“从 62B 到 540B 的提升,通常和从 8B 到 62B 差不多”;博客也说,在与 Gopher、Chinchilla 共有的 58 个 BIG-bench 任务上,表现随规模的变化是对数线性的,“还没有饱和”。
  • 但在大约 25% 的 BIG-bench 任务上,540B 的表现远远超过按 8B → 62B 对数线性外推的预期。他们把这叫做”不连续的改进”(discontinuous improvements):例如 logical_sequence 任务,外推预测约 37%,实际 87%。在 150 个任务里,25% 的任务超出外推 10 个百分点以上,15% 超出 20 个百分点以上。

再加上思维链提示(chain-of-thought),PaLM 540B 在 GSM8K 小学数学题上(8-shot)解出了 58%,超过了此前用 GPT-3 微调加计算器和验证器的 55%。损失按幂律平稳下降,某些能力却像是”突然出现”——这正是 1/23 讲座后半和第 5 讲的主题。


11. 2023 年之后 · Since 2023

CS324 Winter 2023 开课时,Chinchilla 刚发表不到一年。此后规模定律的发展可以概括为:“计算最优”不再是唯一的目标,规模的含义变宽了。这里只列和本讲直接相关、比较确定的几条。

  • 规模定律成了训练大模型的标准流程。 GPT-4 技术报告(2023.3)用小模型预测了最终损失和编程能力(§8.1)。Llama 3(2024)在 6×10186 \times 10^{18}–102210^{22} FLOPs、4000 万到 160 亿参数之间做 IsoFLOP 实验,拟合 N∗(C)=ACαN^*(C) = A C^\alpha 得到 (α,A)=(0.53,0.29)(\alpha, A) = (0.53, 0.29),外推到 3.8×10253.8 \times 10^{25} FLOPs 建议 402B 参数、16.55T token——最终训练了 405B / 15.6T。他们还用”两步法”在训练前预测了 ARC-Challenge 上的准确率,结果只略低于实际。
  • Chinchilla 的结论经受住了复现,但细节被修正。 Besiroglu et al. (2024) 发现方法 3 的原始拟合有问题,重新拟合后得到约 20 token/参数,和方法 1、2 一致;Pearce & Song (2024)、Porian et al. (2024) 解释了 Kaplan 为什么得到 0.73(参数数法、规模、热身、最后一层的计算量、优化器调参,§6.4)。“约 20 token/参数”作为训练算力最优的经验法则基本站住了。
  • “过度训练”小模型成为常态。 因为推理成本(§9.3),开放权重模型普遍远超计算最优:LLaMA-7B 约 150 token/参数,Llama 3 8B 接近 2000。“计算最优”从”该怎样训练”变成了”一个参照点”。
  • 数据成了瓶颈。 当模型想读十几万亿 token 时,“不重复的高质量数据有多少”成了核心问题:数据受限的规模定律(Muennighoff et al. 2023,§9.2)、更激进的数据过滤与配比(FineWeb、DCLM 等,第 2 讲)、合成数据。规模定律也开始被用来比较数据配方:同样的算力,哪一种数据的曲线更低。
  • 学习率调度不再绑死训练长度。 “常数学习率 + 最后一段冷却(cooldown)“一类的调度(例如 warmup-stable-decay)被证明可以达到和余弦调度相近的效果,同时允许从一次长训练的中途分出多个”已退火”的检查点;Hägele et al. (2024) 指出这能让规模定律实验少训练很多次。这正好绕开了 §6.4 (1) 的问题。
  • 推理时的计算也有规模定律。 2024 年起,OpenAI 的 o1、DeepSeek-R1 等”推理模型”用强化学习训练模型在回答前生成很长的思维链;它们的表现随训练时的强化学习算力、也随推理时”思考”的长度平稳提高。Snell et al. (2024) 系统研究了”推理时算力怎样分配”:按题目难度自适应地分配推理计算,效率比 best-of-N 高 4 倍以上;在算力匹配的比较中,对小模型有一定成功率的题目,增加推理计算可以胜过一个大 14 倍的模型。于是”规模”有了三个轴:预训练、后训练(RL)、推理时——每个轴都可以有自己的规模定律,第 5 讲(思维链)和第 7 讲(强化学习对齐)会接着讨论。

哪些结论仍然成立?损失随规模平滑下降、可以用小实验预测大实验——这一点被反复验证,是今天所有大模型训练的基础。哪些被修正了?Kaplan 的分配指数(被 Chinchilla 修正);“计算最优就是最优”(被推理成本修正);“数据是无限的”(被数据受限的现实修正);以及**“规模只指参数和预训练数据”**(被推理时计算扩展)。


12. 小结 · Summary

  1. 规模定律是把资源(NN、DD、CC)映射到损失的简单函数。它的价值在于外推:在小模型上量出曲线,预测还没训练的大模型——“在小模型上调参,外推到大模型”。
  2. 幂律在对数坐标下是直线,指数是”每乘以 kk 降多少”的固定比例;Kaplan 的 αN≈0.076\alpha_N \approx 0.076 意味着参数翻倍损失只降 5.1%。不可约损失 EE 让 LL 的曲线变弯,但 L−EL - E 仍是直线;画图和拟合前先想清楚纵轴。
  3. 为什么是幂律:估计误差的多项式收敛、数据的内在维数(维数越高指数越小)、Zipf 分布的知识块(同时解释参数和数据指数)。它们解释形状,不能预测指数。
  4. C≈6NDC \approx 6ND:前向 2、反向 4。对大模型很准(注意力只多出约 nctx/12dn_{\text{ctx}}/12d),对上下文相对宽度很长的小模型会低估。
  5. Kaplan (2020):平滑幂律、形状不太重要(在合理范围内)、大模型样本效率更高、“训练大模型并提前停止”、Nopt∝C0.73N_{\text{opt}} \propto C^{0.73}。
  6. Chinchilla (2022):NN 和 DD 等比例增长(a≈b≈0.5a \approx b \approx 0.5),约 20 token/参数;GPT-3、Gopher 训练不足;Chinchilla 70B / 1.4T 用 Gopher 的算力全面超过了它。三种方法:训练曲线下包络、IsoFLOP 抛物线、参数化拟合 E+A/Nα+B/DβE + A/N^\alpha + B/D^\beta(由它推出 a=β/(α+β)a = \beta/(\alpha+\beta))。
  7. 分歧的原因:学习率调度和训练长度不匹配(中途检查点的损失被高估、曲线形状被歪曲)、规模偏小、非嵌入参数的数法;2024 年的复现认为热身、最后一层的计算量和优化器调参同样关键。
  8. 拟合与外推很脆弱:玩具实验里,单切片拟合出的下限偏高(0.86 vs 真值 0.77),纯幂律很快预测出低于熵的损失,EE 和指数互相抵消,少一个点结论就变;联合拟合在同一区域内外推误差和噪声相当(0.016),换一个区域就失效。
  9. 用途:预测大训练、选超参数、比较架构和数据(比曲线不比单点)、做预算、预测能力。局限:损失 ≠ 下游能力(第 5 讲)、数据受限(重复 4 遍几乎无损,之后迅速衰减)、推理成本(过度训练小模型更划算)、外推的边界。
  10. 2023 年之后:规模定律成为标准流程;Chinchilla 经受住了复现;为推理成本”过度训练”小模型成为常态;数据成为瓶颈;推理时计算也有了规模定律。

13. 常见误区 · Common pitfalls

  1. “规模定律说损失会一直按幂律降到 0。” 损失有下限(文本的熵)。没有不可约项的幂律只能在一个有限范围内用;外推足够远,一定会预测出不可能的损失(代码 03 演示 3:N≈6.6N \approx 6.6 万时就低于熵了)。
  2. “曲线变平了,说明规模的回报没了。” 可能只是离 EE 近了:LL 的局部斜率越来越小,L−EL - E 的斜率可以不变(代码 01 演示 1)。也可能是另一个资源成了瓶颈(固定 DD 加 NN)。
  3. “Chinchilla 证明了每个模型都应该训练 20 token/参数。” 20 token/参数是训练算力最优,前提是只算训练成本、数据无限。要部署给很多人用的模型,最优点远在 20 之外(§9.3);数据不够时又是另一回事(§9.2)。
  4. “Kaplan 错了,Chinchilla 对了。” Kaplan 的大部分发现(平滑幂律、可预测性、大模型样本效率更高)都站住了;被修正的主要是分配指数,而原因是实验细节(调度、数法、规模),不是方法本身。规模定律的结论对细节敏感,这才是教训。
  5. “在小规模上 A 比 B 好,所以大规模上 A 也更好。” 要比的是两条曲线的斜率,不是一个点(§8.3)。
  6. “拟合误差小,外推就可靠。” 范围窄时,很多组参数拟合得一样好、外推却天差地别(代码 03 演示 4)。外推的可靠性来自范围宽、点多、超参数调好、和目标处于同一区域。
  7. “一个长训练的中途检查点,等于训练那么长的模型。” 学习率调度没有走完的检查点会被系统地高估(或者在很短的训练里被低估),用它拟合会歪曲曲线(代码 04 演示 3)。
  8. “6ND 就是真实的计算量。” 它只数了矩阵乘法里和参数对应的部分;注意力、上下文很长、模型很窄时会低估(代码 01 演示 3)。另外,6ND 是”需要的浮点运算”,不是”花的时间”——硬件利用率是另一回事(第 8 讲)。
  9. “损失按幂律平滑下降,所以每种能力也平滑地变好。” 下游任务可以长期不动、然后快速上升(PaLM 在约 25% 的 BIG-bench 任务上的”不连续改进”)。损失和能力的关系是第 5 讲的主题。
  10. “玩具实验里 token/参数是几十到一百多,所以真实 LLM 也应该这样。” 玩具和真实世界的指数不同,数字不能搬;能搬的是方法(§6.3)。

14. 练习 · Exercises

练习 1(幂律的”价格”) Kaplan 的数据指数 αD≈0.095\alpha_D \approx 0.095。只增加数据(参数足够),要让损失降低 10%,数据要乘以多少?降低一半呢?

参考答案

L∝D−0.095L \propto D^{-0.095},要 LL 乘以 0.9:DD 乘以 0.9−1/0.095=e0.1054/0.095=e1.109≈3.00.9^{-1/0.095} = e^{0.1054/0.095} = e^{1.109} \approx 3.0 倍。要减半:21/0.095=210.5≈15002^{1/0.095} = 2^{10.5} \approx 1500 倍。损失降 10% 就要 3 倍的数据,这就是”规模的回报很贵”(§2.1)。当然,这是没有不可约项的纯幂律;实际上越接近 EE,“损失降 10%“越难——到了 L<1.1EL < 1.1E 时,无论多少数据都不可能再降 10%。

练习 2(多少数据才不过拟合) 用 Kaplan 的经验式 D≳5×103⋅N0.74D \gtrsim 5 \times 10^3 \cdot N^{0.74} 估算:N=109N = 10^9(非嵌入参数)的模型至少需要多少 token?和 WebText2 的大小(约 2.29×10102.29 \times 10^{10} token)比一比。N=1011N = 10^{11} 呢?

参考答案

N=109N = 10^9:N0.74=106.66≈4.6×106N^{0.74} = 10^{6.66} \approx 4.6 \times 10^6,D≳2.3×1010D \gtrsim 2.3 \times 10^{10}——正好约等于 WebText2 的大小,这就是 Kaplan 说”10 亿参数以下的模型在 WebText2 上训练几乎不会过拟合”的来源。N=1011N = 10^{11}:N0.74=108.14≈1.4×108N^{0.74} = 10^{8.14} \approx 1.4 \times 10^8,D≳7×1011D \gtrsim 7 \times 10^{11} token。注意这是”不明显过拟合”的最低需求,用的是 Kaplan 的次线性指数 0.74;按 Chinchilla 的计算最优,101110^{11} 参数应该读约 2×10122 \times 10^{12} token,多出好几倍。

练习 3(推导计算最优分配) 从 L(N,D)=E+AN−α+BD−βL(N, D) = E + A N^{-\alpha} + B D^{-\beta} 和约束 6ND=C6ND = C 出发,推导 §6.2 的 NoptN_{\text{opt}}。然后用 Chinchilla 发表的 α=0.34\alpha = 0.34、β=0.28\beta = 0.28 算出 aa 和 bb,和论文表 2 的方法 3(0.46、0.54)比较。

参考答案

代入 D=C/(6N)D = C/(6N):L(N)=E+AN−α+B(6N/C)βL(N) = E + A N^{-\alpha} + B (6N/C)^{\beta}。对 NN 求导:−αAN−α−1+βB(6/C)βNβ−1=0-\alpha A N^{-\alpha - 1} + \beta B (6/C)^\beta N^{\beta - 1} = 0,即 αAN−α=βB(6N/C)β=βBD−β\alpha A N^{-\alpha} = \beta B (6N/C)^\beta = \beta B D^{-\beta}。解出 Nα+β=αAβB(C/6)βN^{\alpha+\beta} = \frac{\alpha A}{\beta B} (C/6)^\beta,所以 Nopt=G(C/6)β/(α+β)N_{\text{opt}} = G (C/6)^{\beta/(\alpha+\beta)},G=(αA/βB)1/(α+β)G = (\alpha A / \beta B)^{1/(\alpha+\beta)}。

a=0.28/0.62≈0.452a = 0.28/0.62 \approx 0.452,b=0.34/0.62≈0.548b = 0.34/0.62 \approx 0.548,四舍五入后就是表 2 的 0.46 和 0.54(用未四舍五入的 α=0.3392\alpha = 0.3392、β=0.2849\beta = 0.2849 得 a≈0.457a \approx 0.457)。第一个等式的直觉:最优点上,再把一点算力从数据挪到参数(或反过来),两项的变化正好抵消。

练习 4(6ND 与墙上时间) LLaMA-65B 在 1.4T token 上训练,论文说在 2048 块 A100 上每块 GPU 每秒处理约 380 个 token。(a) 训练要多少天?(b) 每块 GPU 实际做了多少 FLOP/s?A100 的 bf16 峰值约 312 TFLOP/s,利用率大约多少?

参考答案

(a) 1.4×1012/(380×2048)≈1.8×1061.4 \times 10^{12} / (380 \times 2048) \approx 1.8 \times 10^6 秒 ≈ 20.8 天(论文说约 21 天)。

(b) 每个 token 6N=6×65.2×109≈3.9×10116N = 6 \times 65.2 \times 10^9 \approx 3.9 \times 10^{11} FLOPs,乘以 380 token/秒 ≈ 1.5×10141.5 \times 10^{14} FLOP/s = 149 TFLOP/s,约为峰值的 48%。这个比例就是”模型 FLOPs 利用率”(MFU),和 PaLM 报告的 46.2% 是同一个量级(第 8 讲)。

练习 5(20 token/参数) 你有 C=1024C = 10^{24} FLOPs。按”每参数 20 token”,该训练多大的模型、读多少 token?按 Kaplan 表 6 的 Nopt=1.3×109⋅CPF-day0.73N_{\text{opt}} = 1.3 \times 10^9 \cdot C_{\text{PF-day}}^{0.73} 呢?

参考答案

6⋅N⋅20N=10246 \cdot N \cdot 20N = 10^{24} → N=1024/120≈9.1×1010N = \sqrt{10^{24}/120} \approx 9.1 \times 10^{10}(约 91B),D≈1.8×1012D \approx 1.8 \times 10^{12}(约 1.8T)。

Kaplan:C=1024/8.64×1019≈11,574C = 10^{24} / 8.64 \times 10^{19} \approx 11{,}574 PF-days,C0.73=e0.73×9.357=e6.83≈925C^{0.73} = e^{0.73 \times 9.357} = e^{6.83} \approx 925,N≈1.2×1012N \approx 1.2 \times 10^{12}(约 1.2T 参数),D=C/6N≈1.4×1011D = C/6N \approx 1.4 \times 10^{11}(约 140B token)。两种规则的模型大小差 13 倍——这就是 2022 年前后大模型设计方向的转变。

练习 6(切片的”下限”) 代码 03 演示 1 里,固定 D=2D = 2M 拟合 L(N)L(N) 得到下限 0.8611,比真值 0.7722 高。(a) 用 L=E+A/Nα+B/DβL = E + A/N^\alpha + B/D^\beta 解释这个差别大约等于什么。(b) 设计一个实验,让单切片拟合出的下限接近真正的 EE。

参考答案

(a) 固定 DD,N→∞N \to \infty 时 L→E+B/DβL \to E + B/D^\beta。所以单切片的下限估计的是 EE + “数据只有 2M 造成的损失”,而不是 EE。用代码 03 演示 2 的联合拟合(B=2.36×107B = 2.36 \times 10^7,β=1.363\beta = 1.363),D=2D = 2M 时这一项约 2.36×107×(2×106)−1.363≈0.062.36 \times 10^7 \times (2 \times 10^6)^{-1.363} \approx 0.06,所以这个极限大约是 0.77+0.06≈0.830.77 + 0.06 \approx 0.83。单切片拟合出 0.86,比它还高一点:只有 6 个点时,下限和指数互相抵消(§7.3),切片的下限本身也估不准。

(b) 让另一个资源不成为瓶颈:对每个 NN,用足够多的数据训练(或者像 Kaplan 那样用大数据集、在验证损失不再下降时提前停止),然后再拟合 L(N)L(N)。代价是每个点都要训练更久。另一个办法是直接做联合拟合,把两个资源的效应分开。

练习 7(改一行:把小数据区放进拟合) 在 03_fit_and_extrapolate.py 里把 D_MIN = 500_000 改成 250_000,重新运行。预测联合拟合的 EE、β\beta 会往哪个方向变,外推误差会变好还是变坏?然后运行验证。

参考答案

预测:D=0.25D = 0.25M 的点(244 步)离 EE 很远、排序不规则(代码 02 演示 2)。把它们放进去,拟合要用”数据项”去解释 0.25M → 0.5M 之间巨大的下降,B/DβB/D^\beta 这一项会变得更大、更陡,或者把一部分损失推给 EE——最可能的结果是 EE 往下掉、残差变大;外推到 D≥1D \ge 1M 的格子时误差变大。

我在一份代码副本里做了这个改动(没有改动课程目录里的文件):联合拟合用 24 个点,EE 从 0.6781 降到 0.6401(离真值更远),rmse 从 0.0415 升到 0.0525;只用 d≤32d \le 32 拟合、外推到 D≥1D \ge 1M 的四格,平均误差从 0.016 变成 0.024。方向都和预测一致。这说明了 §7.1 第 4 条:拟合之前先决定哪些点属于”幂律区”,而且这个决定会影响结论,应该在报告里写明。

练习 8(改一行:同一个学习率) 把 scaling_tools.py 里 lr_for_width 改成对所有宽度都返回 0.04,删掉 cache/sweep.json,重跑代码 02 和 03。预测哪一端的模型会吃亏、拟合出的 α\alpha 会变大还是变小。

参考答案

写代码前的学习率扫描(README”关于实验结果”)显示:宽度 64 的模型在 0.04 时明显比 0.01 差,窄模型则偏好 0.04。所以统一用 0.04 时,宽的一端会吃亏,它们的损失变高;L(N)L(N) 曲线在大 NN 处被”压平”,拟合出的 α\alpha 会变小(看上去”加参数的回报更低”),下限 EE 可能变高。反过来,如果统一用 0.01,窄的一端吃亏,曲线在小 NN 处被抬高,α\alpha 变大。

这就是 Porian et al. (2024) 说的”优化器超参数没有随规模调”会歪曲规模定律。真实研究里,每个规模都要单独调学习率,或者用 μP 这类方法让最优学习率在不同宽度之间保持不变。

练习 9(中途检查点的偏差方向) Chinchilla 认为 Kaplan 用中途检查点会高估最优模型大小随算力增长的速度(aa 偏大)。(a) 解释这个机制:在固定的长调度下,同一个算力预算里,大模型和小模型各处在调度的哪个位置?偏差怎样随算力变化?(b) 为什么我们的玩具(代码 04 演示 3)里偏差的方向不同?

参考答案

(a) 所有模型用同一个长调度。在一个固定的算力预算 CC 上,大模型读的 token 少(D=C/6ND = C/6N 小),处在调度的早期,学习率还高,损失被高估得多;小模型处在调度的后期,被高估得少。所以在每个预算上,偏差都把最优点推向更小的模型。随着 CC 增大,所有模型都更接近调度的终点,偏差变小,最优点回到正确的位置附近。于是”最优模型大小随算力增长”在小预算上被压低、在大预算上恢复——斜率 aa 被高估了。

(b) 这个机制假设”走得越少,被高估得越多”。在玩具里不是这样:走到 12% 时(只有约 244 步),匹配调度的短训练学习率衰减得太早,反而比中途检查点更差(平均 −0.1185);走到 25%–50% 时才是中途检查点更差。偏差随”走了多少”的变化不是单调的,它对拟合的影响也就不同。共同的结论是:偏差随位置变化,所以改变了曲线的形状;方向取决于细节,这也是为什么 2024 年的复现要逐项控制这些细节。

练习 10(推理成本的账) 用代码 05 演示 4 的设定,手算”推理 101310^{13} token”一行:计算最优模型(72.2B / 1.33T)加上推理,总共多少 FLOPs?过度训练的 34.1B / 3.72T 模型呢?验证输出里的”省 28.6%”。

参考答案

计算最优:训练 6×72.2×109×1.33×1012≈5.76×10236 \times 72.2 \times 10^9 \times 1.33 \times 10^{12} \approx 5.76 \times 10^{23},推理 2×72.2×109×1013≈1.44×10242 \times 72.2 \times 10^9 \times 10^{13} \approx 1.44 \times 10^{24},合计约 2.02×10242.02 \times 10^{24}。过度训练:训练 6×34.1×109×3.72×1012≈7.61×10236 \times 34.1 \times 10^9 \times 3.72 \times 10^{12} \approx 7.61 \times 10^{23},推理 2×34.1×109×1013≈6.8×10232 \times 34.1 \times 10^9 \times 10^{13} \approx 6.8 \times 10^{23},合计约 1.44×10241.44 \times 10^{24}。1−1.44/2.02≈28.6%1 - 1.44/2.02 \approx 28.6\%。训练多花了约 32%,推理省了一半以上。一个模型被用得越多,推理那一项越大,“小模型 + 多数据”越划算。

练习 11(数据不够时) 你只有 500B 个不重复的高质量 token,但算力够读 2T token。按 Muennighoff 的公式,有效数据相当于多少不重复的 token?如果算力够读 8T 呢?

参考答案

2T = 4 个 epoch,R=3R = 3:代码 05 演示 5 的表给出有效 token 为 3.73U≈1.873.73 U \approx 1.87T,每个 token 平均值 93.1%——几乎和 2T 新数据一样好。8T = 16 个 epoch,R=15R = 15:有效 10.58U≈5.310.58 U \approx 5.3T,平均每个 token 只值 66.1%。这时更好的选择可能是:少读几遍、把多出来的算力分一部分给参数(Muennighoff 的建议是数据受限时优先多读几遍,但不要指望无限重复),或者想办法找更多数据(代码、合成数据、更宽松的过滤,第 2 讲)。

练习 12(PaLM 的开放问题) PaLM 论文问:在 7T token 上训练的 62B 模型和在 780B token 上训练的 540B 模型相比会怎样?(a) 两者的训练算力各是多少?(b) 用 Chinchilla 发表的参数化拟合(E=1.69E = 1.69,A=406.4A = 406.4,B=410.7B = 410.7,α=0.34\alpha = 0.34,β=0.28\beta = 0.28)预测两者的损失。(c) 这个预测有什么局限?

参考答案

(a) 62B / 7T:6×62×109×7×1012≈2.6×10246 \times 62 \times 10^9 \times 7 \times 10^{12} \approx 2.6 \times 10^{24};540B / 780B:2.53×10242.53 \times 10^{24}(代码 05)。几乎相同的算力。

(b) 62B / 7T:A/Nα=406.4/(6.2×1010)0.34≈0.087A/N^\alpha = 406.4 / (6.2 \times 10^{10})^{0.34} \approx 0.087,B/Dβ=410.7/(7×1012)0.28≈0.104B/D^\beta = 410.7 / (7 \times 10^{12})^{0.28} \approx 0.104,L≈1.69+0.087+0.104≈1.881L \approx 1.69 + 0.087 + 0.104 \approx 1.881。540B / 780B:代码 05 演示 3 给出 1.9239(参数项 0.0417,数据项 0.1922)。按这个式子,62B / 7T 的损失更低,而且推理便宜近 9 倍。

(c) 局限:Chinchilla 的拟合来自 MassiveText 数据和它的分词器,PaLM 的数据和分词器不同,绝对数字不能比;方法 3 的原始拟合本身有问题(§7.3);7T token 远超 Chinchilla 实验的范围(最多 500B token),而且 PaLM 的数据只有 780B 个 token,要读 7T 就得重复约 9 遍——又回到了数据受限的问题(§9.2)。下游能力也不一定跟着损失走(§9.1)。所以 PaLM 的作者说”这些结果还不能回答这个问题”是谨慎的。


15. 延伸阅读 · Further reading

原课阅读(按建议顺序)

本讲的核心补充

2023 年之后

相关的理论图景

  • Hutter, Learning Curve Theory(2021);Michaud et al., The Quantization Model of Neural Scaling(2023):Zipf 分布的”知识块”怎样产生幂律(§2.3 (c))。
  • Henighan et al., Scaling Laws for Autoregressive Generative Modeling(2020):同样的规律出现在图像、视频、数学等模态上(第 14 讲)。

如果你学过本目录下的 CS336,它的规模定律两讲讲得更偏实现(怎样在有限预算下自己做 IsoFLOP 实验),可以和本讲对照。


16. 下一讲预告 · Next lecture

这一讲的主角是一个平滑的量:预训练损失。它按幂律下降,可以从小模型预测大模型。但 §8.5 和 §10 留下了一个悬念:损失平滑地变化,能力却好像会”突然出现”——GPT-3 的少样本学习、PaLM 在四分之一的 BIG-bench 任务上的”不连续改进”、思维链提示只在大模型上才有用。

第 5 讲:涌现能力与上下文学习——思维链、提示与”它为什么能工作”。 什么叫”涌现”?它是规模带来的真实质变,还是评价指标(exact match vs 逐 token 的对数似然)造成的错觉?上下文学习(in-context learning)为什么能工作——是隐式的贝叶斯推断、训练数据的分布性质,还是”在前向传播里做梯度下降”?scratchpad 和 chain-of-thought 为什么能让模型做多步推理?代码会用同一组模型、不同的指标看”涌现”,并在玩具世界里研究上下文学习。

← 返回课程目录