从2020年之后,大模型圈子里几乎没有人能绕过Scaling Laws这个词。但真正让这个概念变得像今天这样“可量化、可规划”的,是2022年那篇被简称为Chinchilla的工作。它给出的结论,用大白话翻译就是:训练算力在涨的时候,模型参数量和训练数据量必须按大致相同的比例一起涨,谁拖后腿,谁就是算力浪费的元凶。
很多第一次接触这个结论的人会觉得反直觉。因为在早期的Scaling Laws研究里,大家普遍相信“参数比数据更重要”——也就是同等的算力预算下,应该优先把模型做大。Chinchilla直接把这条经验推翻了,它用一个非常朴素的方法重新测量了“最优配置”:在固定的计算预算下,把参数量和训练数据量组合起来扫一遍,看哪个组合能把损失压到最低。结果发现,最优的参数量N和数据量D对算力C的依赖几乎是对称的,各自约等于C的0.5次方,而且最优数据量约为最优参数量的20倍左右。
读到这里你可能已经猜到了,这篇就是拿来拆公式、讲实操的。我会先带你把Chinchilla这套理论吃透,再给你一套可以直接套用的估算流程:给你一份算力预算,你怎么推算参数量和训练数据量。顺便把我自己踩过的一些关于单位换算、FLOPs利用率以及“过训练”的坑也交代清楚。
1. 为什么2022年的Chinchilla能成为Scaling Laws的分水岭
1.1 先搞清楚Scaling Laws到底在回答什么问题
Scaling Laws,直译是“缩放定律”。在大模型语境下,它研究的是模型性能与三个资源变量之间的关系:模型参数量N、训练数据量D、训练总算力C。这里的C通常指的是浮点运算量,单位是FLOPs(Floating Point Operations)。模型训练得越好,损失(Loss)越低,而Scaling Laws想回答的问题就是:在给定的算力预算下,N和D应该各取多少,才能让Loss最小。
这本质上是一个资源分配问题。不要小看这个问题的价值:大模型训练成本动辄上千万,如果你只盯着“模型参数要多大”却忽略了“数据要够不够”,很可能花了大价钱却得到一个没有喂饱的模型。反过来说,如果你盲目堆数据,但模型容量不足,多出来的数据也只会变成边际收益几乎为零的无效算力消耗。
1.2 旧版结论:参数是长板,数据是短板的时代
在Chinchilla出现之前,业内比较流行的是2020年那批Scaling Laws结论。当时的研究者用大量不同规模的模型做实验,发现一个很有意思的规律:模型Loss随参数量N的增加而下降的速率,明显快于随数据量D增加的速率。换算成幂律指数,大约是N$^{0.73}$对D$^{0.095}$这种量级。这给人的直觉就是:同样花一份算力,拿去扩参数比拿去扩数据更划算。
于是那段时间,大家做模型的时候普遍更看重“把参数堆上去”,训练数据量反而有点被边缘化。很多模型训练了几百B个token就算很不错了,而参数量动辄几百B。当时谁要是说“你的数据不够”,通常得到的回应是“先把模型做大再说”。现在回头看,大量算力就是在这种“参数-数据配置失衡”中被悄悄浪费掉的。
1.3 Chinchilla带来的反转:参数和数据必须一起涨
Chinchilla这篇研究,并没有用复杂的原理,而是直接做了大量对照实验。他们在不同的算力预算下,分别训练了多个不同规模的模型,然后画出一张张Loss等高线图。每条等高线代表一个算力预算下,Loss随着N和D组合变化的分布。
结果非常清晰:在每个算力预算下,Loss最低点并没有出现在“参数更多”的那一侧,而是出现在N和D相对均衡的位置。随着预算C增加,最优的N和D都在增加,而且速率非常接近——各自约等于C的0.5次方。换句话说,算力提升一倍,理想的参数规模和数据规模都应该同比增加。这才是“算力涨,参数和数据一起涨”的原始出处。
从直觉上也非常好理解:参数是模型的“容量”,数据是模型的“燃料”。容量大但燃料少,模型没有足够机会学透;燃料多但容量小,再多燃料也烧不进去。只有在同一坡度上同时提高,才能让两者的配合保持在最优比例上。
2. 核心公式拆解:算力预算到最优配置的换算
2.1 两个公式和它们的现实含义
标题里给出的是两个非常紧凑的最优配置公式:
[ N_{opt} = K^N \cdot C^a ]
[ D_{opt} = K^D \cdot C^b ]
其中,a和b是对算力C的幂指数。Chinchilla的关键发现是:
[ a \approx b \approx 0.5 ]
同时,K^N和K^D是基于实验标定的系数。这个公式的现实含义非常直白:如果你手里有一笔算力预算C,那么最划算的参数规模大概是K^N乘以C的平方根,最划算的数据量大概是K^D乘以C的平方根。注意,不是“C越大参数占比越高”,而是“两边等比增长”。很多人只记住了0.5次方,却没意识到真正重要的是两个指数相等。
如果把公式两边都取对数,你就会看到一条更直观的线性关系:
[ \log N_{opt} = \log K^N + a \log C ]
也就是说,在双对数坐标下,最优参数量与算力预算是一条直线,斜率就是0.5。你在实际项目里可以用一张双对数表格快速自查:如果一个模型的参数量增长了一倍,那么它的最优数据量也应该增长一倍,而不是不变或只增加一小半。
2.2 幂指数为什么恰好是0.5
很多刚接触这些公式的工程师会问:为什么是0.5,而不是0.7或者0.3?这里有一个非常漂亮的推导逻辑。假设模型Loss可以被分解成三部分:不可约误差E、因参数量不足带来的误差、因数据量不足带来的误差。写成幂律形式就是:
[ L(N, D) = E + \frac{A}{N^\alpha} + \frac{B}{D^\beta} ]
其中,α和β是拟合出来的幂指数,A和B是常数。训练一个模型的总算力,通常近似满足:
[ C \approx 6ND ]
这个6倍关系来自一个token在模型上做一次前向传播和一次反向传播,每个参数大约需要6次浮点运算(2次前向、4次反向),这是一个被大量实验验证的近似值。
现在的问题变成:约束C=6ND,如何分配N和D使L(N,D)最小?这是一个典型的约束最优化问题。用拉格朗日乘子法对N和D求偏导,令其等于零之后,你会得到一个非常整齐的结果。最优点两侧的幂律指数会决定最终的最优分配:如果α和β相差很大,那么指数也会相差很大;如果α和β接近,那么最优配置就对C呈对称的0.5次方。
Chinchilla论文中对α和β的拟合结果大约在0.3上下,两者非常接近。当α≈β时,解出来的最优指数自然就是0.5。所以本质上,a=b=0.5不是某个神秘常数,而是Loss曲面对参数和数据的“弹性”基本对称导致的必然结果。
2.3 D/N≈20倍:这个数字是怎么来的
如果从公式本身来看,D与N的比值可以直接算出来:
[ \frac{D_{opt}}{N_{opt}} = \frac{K^D C^b}{K^N C^a} ]
当a=b时,指数部分抵消,比值约等于K^D / K^N,也就是一个与算力C无关的常数。Chinchilla的实际实验标定下来,这个比值大概在20左右。
20倍意味着什么?一个70B参数的模型,最优训练数据量大约是70B乘以20,也就是1.4T个token。这也是论文中那个著名的Chinchilla模型本身使用的配置:70B参数、1.4T训练token。你要注意,当时很多大模型都追求“超大参数+相对较小的数据集”,因此读到这个数字时,很多人的第一反应都是:原来之前大家把数据量远远低估了。
这个20倍也解决了一个长期困惑:为什么有些模型明明参数量极大,却总觉得“知识储备不够”“泛化能力不足”。当你回头看它训练时只用了不到它参数10倍的token,你就明白了——它在数学上就没有被喂到最优状态。
2.4 K值的标定依赖实验而非理论
标题里特别注明了“K^N、K^D基于实验标定”,这一点非常关键。K值不是由理论推导出来的,它是通过在不同算力预算下训练一系列模型、然后做回归拟合得到的。具体方法基本是这样的:先在几个不同量级的算力预算下,分别训练若干组(N, D)组合的模型,记录各自的Loss;然后找出每个算力预算下的最小Loss点,这些点对应的N和D就是“最优配置点”;最后,把这些最优配置和对应的C放在双对数坐标系里做线性回归,斜率为指数,截距就是K。
正因为K依赖实验标定,它天然受到数据分布、分词器、模型结构、训练策略等因素的影响。不同的语料质量、不同的词汇表大小、不同的BatchSize调度,都会让K的实际数值发生偏移。所以在实际项目里,最稳妥的做法不是直接拿别人论文里的K硬套,而是先跑一个小规模的标定实验,再用自己的K值去推算大规模训练的最优配置。
3. 上手实操:从算力预算推算参数量和训练数据量
3.1 先把单位对齐:FLOPs、参数个数、token数
实操中最容易翻车的不是公式本身,而是单位。C的单位是FLOPs,N的单位是参数个数,D的单位是token个数。三者在数值上量级差距极大,稍不注意就会算错一个数量级。
首先明确FLOPs的估算方式。对于一个参数量为N、训练token数为D的标准Transformer模型,一次训练的总计算量近似为:
[ C \approx 6ND ]
为什么是6?因为前向传播中每个token、每个参数大约需要2次FLOPs,反向传播大约是前向的2倍,也就是4次FLOPs,加在一起就是6。这个近似在业界已经用了很久,对于大多数稠密Transformer模型都足够准确。如果你训练的模型有稀疏激活、混合专家结构,或者有很长的序列且使用了大量padding,那6这个系数就要重新评估了。
所以整个计算链条应该是:先确定预算C,然后反推N和D。反过来,如果你已经确定了一个模型规模N,想估算训练D个token要花多少算力,也直接套C=6ND即可。
3.2 推导用的完整计算例子
我们用一个具体例子把流程走一遍。假设你手里有一笔训练预算C=1e23 FLOPs,这是当年训练70B级别模型的数量级。按照简化标定公式:
[ N_{opt} \approx 0.09 \cdot C^{0.5} ]
[ D_{opt} \approx 1.8 \cdot C^{0.5} ]
先算C的平方根:
[ \sqrt{1e23} = 3.16e11 ]
于是:
[ N_{opt} \approx 0.09 \times 3.16e11 = 2.84e10 ]
也就是约28.4B参数。再算:
[ D_{opt} \approx 1.8 \times 3.16e11 = 5.69e11 ]
也就是约570B个token。D除以N正好约等于20。最后验证一下算力:
[ 6 \times 2.84e10 \times 5.69e11 = 9.7e22 ]
和1e23基本吻合。到这里你就知道了,如果预算是1e23 FLOPs,最优方向是训练一个28B参数模型,吃570B token,而不是训练一个70B参数模型但只喂300B token。
再举一个更常见的场景:如果你只想用1e21 FLOPs做一个小型验证,那结果大约是:
[ \sqrt{1e21} = 3.16e10 ]
[ N_{opt} \approx 0.09 \times 3.16e10 = 2.84e9 ]
约2.8B参数。数据量约57B token。哪怕只有几百亿token预算的团队,也能用这套公式做个初步的成本测算。
3.3 别忘了FLOPs利用率(MFU)
公式里的C是“有效算力”,也就是GPU真正用来做矩阵乘法和反向传播的那部分算力。但现实中,无论是数据中心里的多卡通信、数据加载、评估脚本,都占用了GPU时间。很多时候,你买的算力并不能全部转化为公式里的C。
这就必须引入MFU(Model FLOPs Utilization,模型浮点运算利用率)的概念。MFU描述的是实际完成的有效FLOPs与硬件峰值FLOPs的比值。一个训练效率做得不错的集群,MFU大概在30%到50%之间;如果数据加载、通信、日志、检查点保存做得粗糙,MFU掉到20%以下也不奇怪。
所以,当你按预算金额去采购集群时,应该这么换算:假设你购买了价值相当于10个GPU年算力的集群,GPU峰值运算能力是X FLOPs,但MFU只有40%,那么真正用于训练的C大约是:
[ C_{有效} = 10 \times 365 \times 86400 \times X \times 0.4 ]
在预算估不准的情况下,更建议先在一个小规模模型上测出你集群的MFU,再把这个MFU代进公式里推大规模参数和数据配置。否则你可能会在“算力充足”的幻觉下错配模型规模,训练到一半发现时间和预算都不够了。
3.4 实操中的常见取舍:过训练到底行不行
Chinchilla给出的“最优配置”是一个纯经济学意义上的最优解,它告诉你在固定算力下如何获得最低Loss。但在现实中,很多模型并不是严格按这个最优走,而是会选择“过训练”(over-training):让参数量低于最优值,然后把数据量拉得远超20倍。
过训练的原因通常有两种。第一种是为了部署更小的模型:小模型在推理时更快、更省显存,如果同样的效果可以用更小的参数达到,那就用更多数据换取更小的体积,牺牲一部分训练效率来换推理效率。第二种是因为数据本身就是免费或者低成本的,但推理成本虽然更昂贵——与其训练一个最优但很大的模型,不如训练一个稍小但数据更多的模型。
所以,如果在实际项目里遇到“模型怎么选型”的问题,我的建议是:先用Chinchilla公式算出“算力最优解”,再根据你的推理预算、部署限制、数据积累速度来决定是否要往“过训练”方向偏离。方向偏离本身没有错,但你要清楚偏离之后,你牺牲的是训练阶段的算力效率。
4. 这些年来Scaling Laws在实际落地中的验证与修正
4.1 主流大模型基本都踩在线上
Chinchilla发布后的大模型路线,其实很大程度上印证了这套公式的有效性。后来很多放出训练细节的大模型,其参数-数据比例大致都落在了每参数20到30个token附近。70B级别模型普遍训练1.2T到1.5T以上token,一些更大的模型也开始把训练数据规模做到数T甚至数十T。这个趋势本质上就是Chinchilla指出的方向:数据量必须和参数量同步涨。
而且不止是预训练阶段,连后续的“继续训练”阶段也在遵循这个逻辑。如果你要在一个领域内继续训练一个大模型,数据量不够时,再多的微调轮次也无济于事;只有保证足够多的高质量领域数据,才能让大模型的领域能力稳定提升。这和公式所体现的“数据是硬约束”是一个道理。
要注意的是,很多后发的模型会宣传自己的训练token数远超20倍,并标榜“数据高效”。这并不矛盾,因为他们在用更大的数据量换取更小的参数量,本质上是选择了过训练路线。从算力最优的角度看,它并不是最优配置,但从部署或推理成本的角度看,可能非常合理。
4.2 幂律公式失效的边界场景
Scaling Laws本质上是一个经验拟合工具,不是物理定律。它的适用范围有几个明显的边界。第一,数据质量极度恶化时,幂律关系会失效:如果你在一个充满重复文本的数据集上持续训练,损失下降会很快收敛到瓶颈,增加数据量不再有效。第二,当模型结构发生重大变化时,指数和系数都可能改变:从稠密Transformer换到稀疏MoE,FLOPs与参数的关系就变了,6ND这个近似不再成立。第三,多模态、代码模型这些领域,不同模态的数据维度差异巨大,简单的幂律很难覆盖。
所以在实际应用时,我一般会把Chinchilla公式当作“初始设计参考”,而不是“精确算命的工具”。你用它确定大方向,再用小规模的标定数据去修正K值,最终得到一个属于自己任务和数据的公式。这个过程本身,往往比直接套用公式更值得做。
4.3 训练方法升级后,公式还能用吗
近两年来,训练方法本身也在不断进化:更长的训练序列、更强的学习率调度、更科学的BatchSize缩放、更先进的数据过滤技术,这些都会让损失下降得更快。于是有人会问:这些变化会不会让Chinchilla的结论失效?
从实验结果看,Chinchilla揭示的“N和D应同比扩”这个平衡关系,并没有被根本推翻。训练方法提升的是整体效率,相当于把公式里的K系数往更优的方向移动,而不是让0.5次方的平衡点消失。数据过滤和清洗,会改变有效数据量D的“质量系数”,但不会改变“容量和燃料要匹配”的基本原理。模型结构的改变才会让公式重建,而训练技巧的提升,通常只是让K更好。
4.4 用Scaling Laws做小成本预训练的实用心得
最后聊一点个人实操体会。如果你和我一样,不是那种动辄几千张卡的大团队,只有一两张消费级显卡,也能用上Scaling Laws的思路。做法很简单:确定你的可承受训练时间,然后用MFU算出一个真实的C,代入公式算出N_opt和D_opt。哪怕你最终只是训练一个几十M到几百M的小模型,这个推演也能帮你决定该用多小的模型,该准备多少数据,这样才不会浪费时间和电费。
我踩过的一个典型坑是:把“参数总量”和“训练token数”混在一起估算,导致以为算力预算很大,结果按C=6ND反推才发现差了一个数量级。另外,在小规模上标定K值时,要确保训练轮数(epoch)不要过多,否则会把“数据重复”的收益误当成Scaling Laws真实的拟合信号。这些都是文档里不会写,但实际特别影响判断的细节。
收藏好这两个公式,遇到实际问题时把它当作一张地图:它不会告诉你每一步路怎么走,但它能帮你避开最危险的方向。基于你手里的算力,先算出参数和数据的最佳比例,再根据自己的部署需求决定往哪边偏移,我认为这是Chinchilla留给我们所有人最实在的一笔财富。