跳转到内容

规模与算力估算

"训练这个模型要多少卡、多久、多少钱?"——这是 AI Infra 最常被问到的问题,也是最容易被答错的。

本章把前面十章的东西串起来,给出一套可以在餐巾纸上完成的估算方法。目标不是精确,是量级正确:能回答"这是百万级、千万级还是亿级",通常就够做决策了。

机时=总 FLOPs单卡峰值算力×MFU\text{机时} = \frac{\text{总 FLOPs}}{\text{单卡峰值算力} \times \mathrm{MFU}}

三个量分别来自模型、硬件(第三章)和系统实现(第七章)。

这个式子只对计算受限的负载成立——判断依据回到第四章。最后一节讲不成立的情况。

对稠密 Transformer,前向的乘加主要来自矩阵乘。每个参数每个 token 约 2 FLOPs(一次乘、一次加),反向约为前向的两倍(要算输入梯度和权重梯度各一遍),于是训练总量:

C≈6NDC \approx 6ND

NN 是参数量,DD 是训练 token 数,系数 6 = 2(前向)+ 4(反向)。

推理只有前向:每生成一个 token 约 2N2N FLOPs。

其他负载的计数方式不同,思路一致——找到主导算子,数它的乘加:

负载主导算子每样本 FLOPs
Transformer矩阵乘2N×S2N \times S(前向)
CNN卷积∑l2CinCoutK2HW\sum_l 2 C_{in} C_{out} K^2 H W
MLP全连接∑l2dindout\sum_l 2 d_{in} d_{out}
推荐查表 + 小 MLP查表 ≈ 0,MLP 部分很小

用第三章的参考表。两个必须避开的错误:

  1. 用带稀疏的标称值——需要 2:4 结构化稀疏才能达到,绝大多数负载达不到。永远用稠密峰值。
  2. 精度对不上——FP8 的峰值是 BF16 的两倍,拿 FP8 峰值去估 BF16 训练会低估一倍时间。

用第七章的经验区间。千卡级取 35–50%,万卡级取 25–40%,MoE 再打折。

如果不确定,取 40% 做主估算,再用 30% 和 50% 各算一遍看范围。

问题:训练一个 70B 参数、15T token 的稠密模型,用 H100,需要多少资源?

C=6×(70×109)×(15×1012)=6.3×1024C = 6 \times (70 \times 10^9) \times (15 \times 10^{12}) = 6.3 \times 10^{24}

BF16 稠密峰值 989 TFLOPS,MFU 取 40%:

989×1012×0.40≈3.96×1014 FLOP/s989 \times 10^{12} \times 0.40 \approx 3.96 \times 10^{14} \ \text{FLOP/s} 6.3×10243.96×1014≈1.59×1010 卡⋅秒\frac{6.3 \times 10^{24}}{3.96 \times 10^{14}} \approx 1.59 \times 10^{10} \ \text{卡·秒}

换成卡·小时:1.59×1010/3600≈4.4×1061.59 \times 10^{10} / 3600 \approx 4.4 \times 10^{6},即约 440 万 GPU 小时。

用 2048 张卡:

4.4×1062048≈2160 小时≈90 天\frac{4.4 \times 10^{6}}{2048} \approx 2160 \ \text{小时} \approx 90 \ \text{天}

按 85% 计(故障、重启、检查点):

900.85≈106 天\frac{90}{0.85} \approx 106 \ \text{天}

云上 H100 每卡小时 2–4 美元:

4.4×106×(2∼4)≈880 万∼1760 万美元4.4 \times 10^{6} \times (2 \sim 4) \approx 880 \ \text{万} \sim 1760 \ \text{万美元}

自建集群按折旧摊销会低一些,但要加电力与运维,见训练成本模型。

见下一节。如果显存放不下,前面的时间估算就是空的。

MFU 取 30% / 40% / 50%,结果分别是:

MFUGPU 小时2048 卡天数成本($3/h)
30%590 万141 天1770 万
40%440 万106 天1320 万
50%350 万85 天1060 万

MFU 从 30% 提到 50%,省下 700 万美元和 56 天。 这就是为什么值得花几个工程师月去优化 MFU。

算力之外还要过容量这关。训练时每卡显存:

M≈16NPshard⏟模型状态+Mactivation⏟激活+Mbuffer⏟通信缓冲与碎片M \approx \underbrace{\frac{16N}{P_{\text{shard}}}}_{\text{模型状态}} + \underbrace{M_{\text{activation}}}_{\text{激活}} + \underbrace{M_{\text{buffer}}}_{\text{通信缓冲与碎片}}

16 字节/参数来自混合精度 Adam(第五章)。PshardP_{\text{shard}} 是状态的分片度。

接上例:70B 模型的状态是 16×70×109=112016 \times 70 \times 10^9 = 1120 GB。

  • 不分片:需要 14 张 80GB 卡才放得下状态,还没算激活。
  • 配置 TP=8、PP=4、DP=64、ZeRO-1:参数与梯度被 TP×PP=32 分掉,优化器状态再被 DP=64 分掉,每卡状态降到十几 GB,剩余空间留给激活。

激活内存的粗估:

Mact≈b×S×dmodel×L×kM_{\text{act}} \approx b \times S \times d_{\text{model}} \times L \times k

kk 取决于重计算策略——全量重计算时 kk 很小(只存 stage 边界),不重计算时 kk 可达数十。这就是为什么长上下文训练几乎必须开重计算。

给定算力预算 CC,参数 NN 与数据 DD 如何分配?

Chinchilla(Hoffmann et al., 2022)的实证结论是两者应同比例增长,计算最优点在每参数约 20 个 token。

但这只是训练最优。把推理成本计入后结论会变:

总成本≈6NDtrain⏟训练一次+2N⋅Dinference⏟推理无数次\text{总成本} \approx \underbrace{6ND_{\text{train}}}_{\text{训练一次}} + \underbrace{2N \cdot D_{\text{inference}}}_{\text{推理无数次}}

推理成本正比于 NN,与 DtrainD_{\text{train}} 无关。所以如果模型要被大量调用,应该"过度训练"一个更小的模型——用更多训练数据换更小的参数量。

这就是近年开源模型普遍远超 20 token/参数(常见 100–300)的原因。

一个粗略判据:令两项相等,

6NDtrain=2NDinference  ⟹  Dinference=3Dtrain6ND_{\text{train}} = 2N D_{\text{inference}} \implies D_{\text{inference}} = 3 D_{\text{train}}

当预期推理 token 总量超过训练量的 3 倍时,推理项开始主导,就值得压小 NN。对一个面向亿级用户的产品,这个条件几个月就满足了。

访存密集的负载不能用 FLOPs 估算。 对推荐系统、大模型的解码阶段、GNN,正确的通式是:

时间=必须读写的字节数有效带宽\text{时间} = \frac{\text{必须读写的字节数}}{\text{有效带宽}}

最重要的一个例子:解码速度上限

Section titled “最重要的一个例子:解码速度上限”

每生成一个 token 要把全部权重从显存读一遍,所以单请求的生成速度上限是:

tokens/s≤显存带宽模型字节数\text{tokens/s} \le \frac{\text{显存带宽}}{\text{模型字节数}}

70B 模型 BF16 存储约 140 GB,H100 带宽 3.35 TB/s:

3.35×1012140×109≈24 tokens/s\frac{3.35 \times 10^{12}}{140 \times 10^9} \approx 24 \ \text{tokens/s}

与算力完全无关。 换一块算力翻倍但带宽不变的卡,这个数字一点不会变。

这条公式直接推出推理优化的两条主线:

手段怎么起作用
量化减小分子——INT4 权重只有 35 GB,上限提到 ~96 tokens/s
批处理提高算术强度——同一次权重读取服务 BB 个请求,总吞吐 ×BB

通信受限的负载同理,用通信量除以有效带宽估算(第六章)。

你想估公式
稠密模型训练机时6ND÷(Ppeak×MFU)6ND \div (P_{\text{peak}} \times \mathrm{MFU})
推理单 token 算力2N2N FLOPs
推理单请求速度上限显存带宽 ÷ 模型字节数
训练显存16N/Pshard16N / P_{\text{shard}} + 激活
KV cache2LHkvdhSB×bytes2 L H_{kv} d_h S B \times \text{bytes}
流水线气泡(p−1)/m(p-1)/m
All-reduce 通信量2p−1p×2\frac{p-1}{p} \times 参数字节数
最优检查点间隔2Tckpt⋅MTBF\sqrt{2 T_{\text{ckpt}} \cdot \mathrm{MTBF}}
机器平衡点Ppeak/BpeakP_{\text{peak}} / B_{\text{peak}}
Amdahl 加速比1/((1−p)+p/s)1 / ((1-p) + p/s)

这十个公式覆盖了本书 90% 的估算需求。 建议打印出来贴在显示器旁边。

三条建议,来自反复踩坑:

一、先算量级,再算细节。 如果量级就不对(比如需要十万卡),后面的精细化毫无意义。

二、给出区间而非点估计。 "440 万 GPU 小时"听起来精确得可疑,"350 万到 590 万,取决于 MFU"更诚实也更有用。

三、显存校验必须做。 时间估算再漂亮,显存放不下就是零。而且显存问题往往需要改并行策略,反过来又影响 MFU 和时间。

  • 通式:机时 = 总 FLOPs ÷(峰值算力 × MFU),只对计算受限负载成立。
  • 稠密 Transformer 训练 C≈6NDC \approx 6ND,推理每 token 约 2N2N;MoE 用激活参数量算算力、总参数量算显存。
  • 完整算例:70B × 15T token ≈ 440 万 GPU 小时,2048 卡约 106 天,880 万–1760 万美元;精度 ±30%。
  • MFU 从 30% 到 50%,在这个例子里省 700 万美元和 56 天——这就是优化的价值。
  • Chinchilla 的 20 token/参数是训练最优;当预期推理量超过训练量 3 倍时,应过度训练更小的模型。
  • 访存密集负载改用"字节 ÷ 带宽"——70B 单请求生成上限 24 tokens/s,由带宽而非算力决定。
  • 估算纪律:先量级后细节、给区间不给点、显存校验必须做。