04. 算力账与规模定律:训练要多少卡多少天
上一篇算的是空间账:8B 全参训练光是权重、梯度和优化器状态就要约 128.5 GB,一张卡放不下。这一篇算时间账。资料助手团队准备用 1 万条问答做一次 LoRA 微调,想知道一张 H100 要跑多久;顺便也好奇,Meta 训练 Llama-3.1-8B 这样的底座到底花了多少卡时。读完你应该能用参数量和 token 数手算一次训练的运算量,用 MFU 把它换成 GPU 小时,解释 Chinchilla 规模定律说的“每个参数约 20 个 token”,以及为什么 Llama 3 的 8B 模型偏偏训练了将近 1900 个 token/参数。
每个参数、每个 token,大约 6 次运算
先看最小的单位。Transformer 里绝大部分计算是矩阵乘:输入向量 x 乘以权重矩阵 W,得到输出 y。输出的每一个元素都是一串“权重 × 输入,再累加”。所以一个 token 经过一层线性层时,每个权重恰好参与一次乘法和一次加法,也就是 2 次浮点运算(FLOPs,floating-point operations,下面简称“次运算”)。整个模型的参数几乎都在这些矩阵里,于是一个 token 走完一次前向,大约是 2 × 参数量 次运算。
反向传播要做两件事,各自又是一次与前向同样规模的矩阵乘:一是把梯度传回给上一层的输入(对激活求梯度),好让更前面的层继续算下去;二是算出这一层权重自己的梯度(对权重求梯度),给优化器更新用。两件事合起来约 4 次运算,是前向的 2 倍。前向 2 次加反向 4 次,每个参数每个 token 约 6 次:
text
训练运算量 C ≈ 6 × N × D
N:模型参数量
D:训练用的 token 总数
6:前向 2 次 + 反向 4 次
Llama-3.1-8B 预训练:6 × 8.03×10⁹ × 15×10¹² ≈ 7.2×10²³ 次运算7.2×10²³ 是什么量级?一张 H100 的 BF16 稠密峰值是 989 TFLOPS,也就是每秒 9.89×10¹⁴ 次。哪怕它一直满速运转,也要 7.3×10⁸ 秒,约 23 年。
这个公式有两处近似,方向相反。它没有算注意力里 Q×Kᵀ 和“注意力权重 × V”这两步,它们的运算量随上下文长度增长,与参数量无关;按因果掩码下平均每个 token 只看前一半上下文粗估,8B 模型在 8K 上下文时每个 token 多出约 2 × 32 层 × 8192 × 4096 ≈ 2.1×10⁹ 次,约为前向 2N 的 13%,不利用掩码、按完整注意力计算则再翻一倍。另一方面,输入词嵌入是查表,不做矩阵乘,那 5.25 亿参数其实没花 6 次运算,又让公式多算了约 6%。两项量级都在一成左右,所以 6ND 适合做粗算,不适合拿来精确到百分之几。
MFU:峰值能打几折
GPU 不可能一直跑在峰值。等通信、等数据、做 LayerNorm 和 softmax 这类搬运多于计算的操作(推理系列第 6 篇讲过“访存受限”),流水线里还有空等的时间。衡量“实际用上了多少算力”的常用指标叫 MFU(Model FLOPs Utilization,模型算力利用率):
text
MFU = 每秒实际训练的 token 数 × 6N ÷ 硬件峰值 FLOPS分子只按 6N 计入“模型本该做的运算”,激活重计算多跑的那次前向不算(含重计算的口径叫 HFU,硬件算力利用率)。这样不同框架、不同显存策略之间可以公平比较:省显存而多算的部分,不会被当成“更高效”。
几个公开数字可以建立直觉。PaLM 论文(2022)统计过:GPT-3 在 V100 上约 21%,Gopher 约 33%,PaLM 540B 在 TPU v4 上 46.2%。Llama 3 论文(2024)报告 405B 在 H100 上的 MFU 为 38%—43%。大规模预训练做到 40% 左右已经是工程团队精心调优的结果。
还要注意峰值取哪个数。NVIDIA 官网上 H100 SXM 的 BF16 写的是 1,979 TFLOPS,脚注注明是“稀疏”口径,要求矩阵里一半元素按特定规则为零;普通训练用不上,稠密峰值是它的一半,989 TFLOPS。
把 7.2×10²³ 换成卡时
假设 MFU 为 40%,每张 H100 每秒实际完成 989×10¹² × 0.4 ≈ 3.96×10¹⁴ 次有效运算:
text
总卡·秒 = 7.2×10²³ ÷ 3.96×10¹⁴ ≈ 1.83×10⁹
GPU 小时 = 1.83×10⁹ ÷ 3600 ≈ 50.7 万如果用 1024 张卡、扩展时效率不掉,约 496 小时,三周左右。下面把这五步和公开数字放在一起:
Llama 3.1 模型卡记录的 8B 训练用了 146 万 H100 GPU 小时,是手算的约 2.9 倍。反过来,如果把差距全部归到利用率上,等效 MFU 只有:
text
7.2×10²³ ÷ (146万 × 3600 × 989×10¹²) ≈ 14%模型卡没有说明这 146 万小时包含哪些工作,也没有公布 8B 的并行配置和 MFU,所以差距由什么构成无法从公开资料判断。能确定的是方向:6ND 只数了理想的矩阵乘,而真实的卡时只会比它多。手算结果是下限,不是预算。
同样的方法套到 405B 上,结果贴近得多。Llama 3 论文给出 405B 用 15.6T token、3.8×10²⁵ 次运算,6 × 405×10⁹ × 15.6×10¹² ≈ 3.79×10²⁵,公式本身吻合。按论文里 16,384 卡时的 41% MFU 折算约 2600 万 GPU 小时,模型卡是 3084 万;倒推等效 MFU 约 35%,与论文报告的 38%—43% 相差不大。大模型的训练记录最完整,公式也最接近实际。
做自己的预算时,先用 6ND 算出下限,再用自己集群实测的 MFU 替换 40%,最后为重跑、实验和评估留出余量。
资料助手的 LoRA 微调要多久
回到资料助手。团队整理了 1 万条问答,平均每条(问题加回答)约 1000 个 token,想在 Llama-3.1-8B 上做 LoRA,r=16,作用于全部 7 种线性层(第 10 篇细讲)。数据总量:
text
D = 1万条 × 1000 token = 10⁷ token(一轮)LoRA 冻结了底座,但并没有让计算变成原来的 0.52%。前向仍要让每个 token 走完整个 8B 模型,2N 一次不少;反向时,冻结权重不需要自己的梯度,那一半可以省掉,但“传回给上一层输入的梯度”必须照算,否则更靠前的 LoRA 层拿不到梯度。适配器自己的参数只占 0.52%,运算可以忽略。所以:
text
LoRA 每 token ≈ 2N(前向)+ 2N(对激活求梯度)= 4N,约为全参的 2/3
一轮运算量 ≈ 4 × 8.03×10⁹ × 10⁷ ≈ 3.2×10¹⁷ 次
一张 H100,MFU 40%:3.2×10¹⁷ ÷ 3.96×10¹⁴ ≈ 810 秒 ≈ 14 分钟单卡、小批量的微调很难跑到 40%。按更保守的 20% 估算约 27 分钟;如果为了省显存开了激活重计算(第 3 篇),每步多一次前向,回到约 6N,就是 41 分钟左右。训练 3 轮,大约一到两个小时。
| 场景 | 每 token 运算 | 一轮总量 | H100 单卡、MFU 20% |
|---|---|---|---|
| LoRA,不重计算 | 约 4N | 3.2×10¹⁷ | 约 27 分钟 |
| LoRA,开激活重计算 | 约 6N | 4.8×10¹⁷ | 约 41 分钟 |
| 全参 SFT(显存要多卡,见第 8 篇) | 约 6N | 4.8×10¹⁷ | 合计约 41 卡·分钟 |
| 预训练 15T token | 6N | 7.2×10²³ | 约 100 万卡·小时 |
以上都是估算。对资料助手来说,结论很清楚:一次小规模微调,算力不是瓶颈,整理数据、写评测集、反复看坏例子花的时间要多得多。
这个估算有几种情况会明显偏离。样本长短不一时,如果不做样本打包,短样本会被补齐到批内最长长度,补齐的 token 也要计算,实际算量可能翻倍(第 9 篇讲打包)。样本很长时,前面忽略的注意力运算开始占大头:按同样的因果掩码口径粗估,32K 上下文时这一项约为 2N 的一半,128K 时约为 2N 的两倍。用 QLoRA 时,底座是 4 bit,每次计算前要先把权重反量化回 BF16,运算量公式不变,但单步耗时通常比 LoRA 更长。估出来的时间和实测差得很远时,先查这三项。
规模定律:loss 怎样随规模下降
知道了一次训练花多少算力,下一个问题是:同样的算力,应该造一个大模型少读点数据,还是一个小模型多读点数据?这就是规模定律(scaling laws)要回答的。它是从大量实验中拟合出的经验公式:在其他设置合理时,模型在同分布测试集上的 loss,随参数量、数据量和算力按幂律平滑下降。
OpenAI 的 Kaplan 等人在 2020 年第一次系统地拟合了这些关系,趋势跨越了七个数量级以上。他们的结论之一是:算力增加时,最优做法是把大部分算力花在加大模型上,最优参数量大约按算力的 0.73 次方增长,数据量只按约 0.27 次方增长;也就是训练很大的模型、用相对少的数据、远未收敛就停。那几年的大模型几乎都是这个配比:GPT-3 175B 训练了 3000 亿 token,Gopher 280B 也是 3000 亿,每个参数只有一两个 token。
DeepMind 的 Chinchilla 论文(Hoffmann 等,2022)训练了 400 多个模型,从 7000 万到 160 亿参数、50 亿到 5000 亿 token,得出了不同的结论:参数量和 token 数应该同比例增长。按论文给出的最优配比表,10 亿参数对应约 202 亿 token,100 亿参数对应约 2051 亿 token,比例大致是每个参数 20 个 token。他们用和 Gopher 相同的算力训练了 70B 参数、1.4T token 的 Chinchilla,在大多数评测上超过了 4 倍大的 Gopher。两篇论文结论不同,Chinchilla 论文指出的一个原因是:Kaplan 的实验对所有模型使用了固定的训练长度和学习率衰减设置,而学习率衰减与实际训练 token 数匹配时,最终 loss 才最好。
把“每参数 20 token”代回 6ND,可以直接算出某个算力预算下的最优模型:
text
C = 6 × N × D,D = 20N → C = 120 N² → N = √(C / 120)
以 Llama-3.1-8B 的 7.2×10²³ 次运算为预算:
N = √(7.2×10²³ / 120) ≈ 7.7×10¹⁰(约 770 亿参数)
D = 20N ≈ 1.5×10¹²(约 1.5T token)同一笔算力,Chinchilla 会建议训练一个约 77B 的模型、读 1.5T token,而不是 8B 读 15T。
为什么小模型要“过度训练”
Chinchilla 的最优,是训练算力的最优:花同样的训练成本,得到最低的 loss。但模型训练一次,要被调用成千上万次。推理时每生成一个 token 约需 2N 次运算,权重也要常驻显存,77B 的模型每个 token 的推理成本大约是 8B 的十倍,还需要多张卡才放得下(推理系列第 16 篇算过 70B 的部署账)。
如果目标是“推理便宜、效果尽量好”,更合理的做法是选一个部署得起的尺寸,然后用远超最优点的数据把它训练到底。多花的训练算力只付一次,省下的推理成本每天都在累积。Llama 3 正是这样做的:
8B 每个参数读了约 1868 个 token,是 Chinchilla 最优点的九十多倍;70B 约 212 个;而旗舰 405B 只有约 39 个。Llama 3 论文里,405B 这个尺寸本身就是按规模定律定的:他们用自己拟合的公式外推到 3.8×10²⁵ 次运算,算出最优约为 402B 参数、16.55T token,最终选了 405B。大模型按规模定律定尺寸,8B 和 70B 则明显是按部署成本定的尺寸。
所以“过度训练”并不是浪费:大模型按训练成本选尺寸,小模型按推理成本选尺寸,小模型多读的数据换来的是同尺寸下更好的效果。
规模定律不承诺什么
规模定律常被引申成“模型越大越聪明”,用的时候要清楚它的边界。
它预测的是 loss,而且是与训练数据同分布的测试 loss,不是某个具体任务的准确率。从 loss 到“会不会算加班费”中间还隔着一层:Llama 3 团队专门做了两步拟合,先把算力映射到下游任务答案的负对数似然,再把似然映射到准确率,正是因为前者不能直接推出后者。
它只在拟合过的范围和条件下可靠。Chinchilla 的实验假设数据足够多、不重复;数据质量、配比、分词器、学习率调度一变,曲线的系数都会变。把小模型的拟合外推几个数量级,误差会被放大。
还有所谓“涌现”:某些能力在模型规模达到某个点后看起来突然出现。2023 年 Schaeffer 等人的研究认为,相当一部分“突然出现”来自评测指标本身是不连续的(例如只算完全答对),换成连续指标后,变化往往是平滑的。无论哪种解释,规模定律都不能告诉你“多少参数时会具备某项能力”。
对资料助手这样的小规模微调,规模定律几乎不适用:1 万条数据、几十分钟训练,没有一条可靠的曲线能预测效果。能回答“有没有变好”的,是业务评测集(第 21 篇)。
训练的时间账就是这样算的:每个参数每个 token 约 6 次运算,乘以参数量和 token 数得到总量,再除以峰值乘 MFU 得到卡时,手算结果是下限;LoRA 省的是显存和权重梯度,前向和对激活的反向一次不少,约为全参的 2/3。规模定律告诉我们训练算力怎样在模型和数据之间分配最省,而部署成本让小模型有理由远远读过那个点。账算好了,训练真正跑起来以后,怎样从曲线判断它是否健康,是下一篇的内容:读懂训练曲线。
