FP8 训练为什么能稳:把缩放因子的粒度与累加精度算清楚
把 671B 参数的模型用 8 位浮点训完而不炸,靠的不是「换个低精度类型」,而是两件可以被算清楚的事:把缩放因子的粒度切到 1×128 与 128×128,让离群值只污染自己所在的那一块;以及在 Tensor Core 只保留约 14 位有效位的前提下,每 128 个元素把部分和提升到 CUDA Core 做一次 FP32 全精度累加。本文从 E4M3 的位布局出发,推导共享缩放因子的下溢代价、分块的误差局部化收益、以及归约维度与累加区间共同决定误差上界的线性关系,逐条对照 DeepSeek-V3 技术报告的五个设计选择,并给出一份「在自己的训练栈里最小验证 FP8」的清单。
线上做训练的人第一次看 DeepSeek-V3 的技术报告,容易被一个数字绊住:一个 671B 总参数、每 token 激活 37B 的模型,在 14.8T token 上预训练只花掉 2.664M H800 GPU 小时,全过程没有出现不可恢复的 loss spike、也没有回滚。报告把这份成绩归因于架构与工程的共同作用:摘要点明的是 MLA 与 DeepSeekMoE(以及无辅助损失负载均衡、多 token 预测训练目标),而「首次在超大模型上验证 FP8 混合精度训练框架」是它在正文贡献清单里单列的一条。
摘要里那几条(MLA、DeepSeekMoE、负载均衡、多 token 预测)都是架构与训练目标层面的事,本文要讲的是正文贡献清单里单列的这条——FP8 混合精度框架。而它最容易被误读的地方在于:大家习惯性地把「FP8 训练」理解为「换一个数据类型,理论上算力翻倍」。这句话本身没错——报告也确实写了 GEMM 用 FP8「理论上把计算速度相对 BF16 翻一倍」——但它是结果,不是原因。真正需要解释的是另一个问题:
为什么低精度量化明明只有 3 位尾数,却能让一个 671B 模型的训练曲线几乎贴上 BF16 基线(报告给出的相对 loss 误差始终低于 0.25%)?
本文的答案是两句话,都会在下面被展开成可检验的算式:
- 浮点格式的相对精度是「免费」的,代价只出在下溢上。所以缩放因子共享的范围越大,被推出正规区的元素就越多——分块量化的全部收益,是把这份代价从整张量压缩到一小块。
- 量化之外还有第二重误差:累加。H800 的 Tensor Core 在对齐后只保留每个尾数积的高约 14 位,误差随归约长度 增长;把累加区间截断到 ,是让这个上界重新变小的一步。
为了让结论可用,本文还会做三件配套的事:把一次 FP8 训练里所有精度损失的来源列成一张清单(第七节),给出一个「不拉开一个 helper 分支就能验证 FP8」的最小实验方案(第十二节),以及把这条路线外推到 4 位时新增了哪些工程件(第十三节)。
文中涉及他人结论的部分都以标注出处的方式给出,凡属于本文自行展开的推导与算例,都在文末「本文自行推导」清单里单列,不与报告的数字混写。
一、先给直觉:低精度训练要解决的不是「位数少」,而是「范围挤」
先把悬念放一边,给一个不用公式的画面。
半精度(bf16)训练之所以几乎不费心,是因为 bf16 的 8 位指数已经把「大数到小数」的跨越能力给足了。真正的问题从来不是「一个数只能写 8 位」,而是:一个缩放因子要同时照顾一批数值。
FP8 的指数只有 4 位或 5 位,能覆盖的比值范围远比 bf16 窄。所以工程上必须先给一个张量配一个缩放因子,把它的最大绝对值映射到 FP8 能表示的最大值附近。这一步本身是标准做法(把输入分布对齐到格式的可表示区间),但它带来一个副作用:缩放因子是按「这一组里最大的那个数」定的。
于是,只要这一组里存在离群值,整组的小数值就得跟着这个离群值一起被压缩。压到什么程度会出问题?不是「精度不够」,而是掉出正规区——一旦掉进次正规区,尾数位会一位一位地被侵蚀;掉得更狠,直接变成 0。
这句话就是整篇文章的骨架:
分块量化不改变 FP8 的精度,它改变的是「有多少元素被离群值连坐」。
第二重误差来自计算本身。即使每个数都量化得无可挑剔, 维内积的累加过程仍然会丢精度——因为硬件累加器不是全精度的。这一重误差与调度、与缩放因子都无关,只能靠「定期把部分和搬到高精度寄存器」来截断。
二、符号与术语约定
本文出现的符号与格式名统一约定如下,后文不再重复解释。
| 符号 / 名称 | 含义 |
|---|---|
| / | 原始值 / 量化后的值 |
| 缩放因子(scale),一个分组共用一个 | |
| 一组元素的绝对值最大值(amax) | |
| MAX | 该浮点格式可表示的最大有限值 |
| 有效位数(含隐含的前导 1),决定相对精度 | |
| GEMM 的归约维度(内积长度) | |
| 累加区间:部分和被提升到高精度寄存器前,Tensor Core 连续累加的每段长度 | |
| 累加器在对齐后实际保留的有效位宽 | |
| 该格式正规区的最小二进制指数 | |
| E4M3 / E5M2 / E8M0 / E5M6 | 格式名,写作 ,符号位另计 1 位 |
| Fprop / Dgrad / Wgrad | 前向、激活反向、权重反向三类 GEMM |
| WGMMA | Warpgroup 级矩阵乘累加指令(Hopper) |
| 正规区 / 次正规区 | 带隐含前导 1 的指数区间 / 指数全 0 且无隐含 1 的区间 |
三、把 8 位浮点拆开看:指数换范围,尾数换精度
一个 IEEE 风格的二进制浮点数写作:
其中 是有效数字, 是尾数位。8 位浮点把「1 位符号 + 剩余 7 位」切成两种互斥的取舍方案,这就是 E4M3 与 E5M2 的全部区别:
| 格式 | 位布局(符号+指数+尾数) | 最大有限值 | 正规区最小值 | 有效位数 | 半 ulp 相对误差上界 |
|---|---|---|---|---|---|
| E4M3 | 1 + 4 + 3 | 448 | 4 | ||
| E5M2 | 1 + 5 + 2 | 57344 | 3 | ||
| E5M6(自定义) | 1 + 5 + 6 | — | — | 7 | |
| bf16 | 1 + 8 + 7 | 约 | 8 | ||
| fp32 | 1 + 8 + 23 | 约 | 24 |
这张表里有两个必须看懂的细节。
第一,E4M3 是「牺牲特殊值换范围」的产物。 按 FP8 格式论文的说明,E5M2 遵循 IEEE 754 对特殊值的约定(有正负无穷、NaN 占多个位型),而 E4M3 通过不表示无穷、并且只留一个位型表示 NaN 的方式,把省下来的编码空间让给了数值本身。所以同样是 8 位,E4M3 的尾巴更长、头顶更低;E5M2 的头顶更高(57344 对 448,约 128 倍,即 7 个二进区间、折合约 2.1 个十进制数量级)、但尾巴更短。这不是设计缺陷,而是两种明确的用途分工。
第二,E5M2 覆盖的「比值范围」约是 E4M3 的 倍。 用正规区上下限的比来衡量:
这就是 NVIDIA 的 FP8 使用口径里「前向用 E4M3、反向用 E5M2」的全部理由:反向传播的梯度对精度的容忍度更高、但对动态范围的需求更大。先记住 这个数,下一节它会直接变成一个判据。
四、形式化:共享缩放因子只在「下溢」时才伤人
设某分组的 amax 为 ,我们把 FP8 的最大值记作 MAX(E4M3 取 448)。标准做法是令
然后把每个元素量化成 ,其中 是「舍入到最近的 FP8 可表示值」。
现在来问一个很关键、但常被跳过的式子:在正规区内,量化后的相对误差有多大?
设 落在区间 。在这个二进区间内,相邻可表示值的间隔(ulp)是 ,四舍五入的误差不超过半个 ulp:
把 代回去,注意缩放因子在两侧同时出现并抵消:
结论看起来很反直觉,但它是浮点格式的核心性质:
只要不越界,浮点量化的相对误差与缩放因子无关,恒为 。
换句话说,一个共享的缩放因子不会让「小数值的相对误差变大」——它只会做两件事:把组内元素推出正规区(下溢),或者让它们撞上够不着的天花板(上溢)。训练里缩放因子通常按 amax 归一,上溢基本不发生,所以唯一真正的杀伤来自下溢。
这个结论还有一层重要的方法含义:讨论「FP8 精度够不够」时,用「有效位数少」当论据是错的论据。位数决定的是那个恒定的 ;真正随规模、随负载变化的风险因子是「有多少元素被挤出了正规区」。后面所有的工程措施,都是在动这个比例。
4.1 下溢的两道门槛
E4M3 的正规区下限是 。在缩放后的坐标系里,一个元素要保持「完整的 3 位尾数」,需要
次正规区的最小刻度是 (把 再按 3 位尾数细分成 8 档后的最小非零档,E4M3 共 7 个非零次正规值)。但要注意:本文的量化用的是四舍五入,所以量级超过半个刻度()的元素仍会被舍入到 保留下来——真正归零的门槛是半个刻度:
把两道门槛合并成一个更好用的形式。称一个分组「内部跨度」为组内 amax 与需要保留的最小有效量级之比:
这就是上一节那个 的去处。 一个共享缩放因子只能覆盖约 14.8 个二进区间;分组内部的跨度一旦超过这个数,分组里最靠下的一批元素就会被侵蚀。分组越大、越可能同时包含「巨大的离群通道」和「正常量级的小值」,也就越容易越界。
五、推导:分块把误差从「全局」压成「局部」
上一节给出了一个纯判据,这一节把它变成一个可以估影响的模型。
考虑一个隐藏维度为 的激活张量(本文算例统一取 ,属示例假设)。理想化地设:绝大多数通道的数值量级约为 ;另有 个「离群通道」,量级约为 ,并记跨度比 。这是 LLM 激活里真实存在的形态——离群通道的存在是低精度量化文献反复指出的核心困难,报告第 3.3 节也把「激活、权重与梯度中的离群值」列为低精度训练的主要限制。
方案一:整张量共享一个缩放因子。 此时 ,判据要求
也就是跨度比不能超过约 4.5 个数量级。一旦 更大,所有非离群元素一起掉出正规区(若 则直接归零)。这就是「一个离群值连坐整张量」的确切含义——不是比喻。
方案二:按 1×128 的 tile 分块共享。 报告对激活采用的就是这个粒度:每个 token、每 128 个通道一组。现在只有包含离群通道的那些块的 amax 被 支配;其余块的 amax 只由本块的 128 个样本决定。对量级 的样本,128 个样本的期望最大值约为 的 3 倍(正态情形下 个样本最大值的期望约为 , 时约 3.1),于是这些块的跨度比降到个位数,远在 之内。
受影响的比例因此可以被估出来。把每个 token 的 个通道切成 个块,若 个离群通道落在互不相同的块里,被污染的就是这些块:
(取 、 的算例;这个数字随 线性变化,属本文自算。)
对照一下就清楚了:同样的离群值,整张量缩放会伤到 100% 的元素,1×128 分块最多伤到 3.1%。这就是「分块把误差从全局压成局部」的量化版本。报告在权重侧用的是更粗的 128×128 块(128 个输入通道 × 128 个输出通道),理由也在这个框架内:权重矩阵的离群结构通常更平滑,用 128×128 已经足够把跨度比压下来,而更大的块能摊薄缩放因子本身的存储与计算开销。
值得单独记一笔的是为什么激活不能照抄权重的分块方式。报告在正文里明确提到:如果对激活也按权重那样的块方式分组缩放,会引发训练不稳定(细节放在其附录 B.2)。也就是说,激活与权重的分块粒度不同不是随手取值,而是被稳定性实验反向约束出来的——激活沿 token 方向按 128 通道切(1×128)才是能跑通的那一侧。
5.1 算例:走一遍一个 1×128 激活 tile 的量化
抽象推导容易滑过去,这里把数字代进去走一遍,顺便验证第四节那个「相对误差恒为 」的结论。
设一个 1×128 的激活 tile,绝大多数元素量级在 0.02–0.05,其中一个通道是离群值 12.5。
第一步,定缩放因子。 ,MAX 取 448:
第二步,查门槛。 保持完整 3 位尾数需要
而本 tile 里除离群值之外最小的元素也有 0.02 量级,是门槛的约 46 倍——整个 tile 的元素都留在正规区。这就是分块想要的结果。
第三步,估误差,并用两种算法互相验算。 对量级 0.03 的元素:
- 用第四节的相对误差上界:。
- 用 ulp 直接算:,落在二进区间 (),ulp 为 (缩放坐标),换算回原坐标是 ,半个 ulp 即约 。
两种算法给出 1.88e-3 与 1.74e-3,同量级且后者不超过前者——相对误差上界那套推导是对的。
第四步,把缩放因子换成「整张量共享」再走一遍。 假设这张量里还有另一个更大的离群值(比如 1000),于是
本 tile 里那些 0.02 量级的元素已低于门槛(0.02 < 0.0349),掉进次正规区:在缩放坐标里它们只能落在 的整数倍上,而 E4M3 的次正规档位总共只有 7 个。粗算一下误差:量级 0.02 的元素在缩放坐标约 0.00896,最近可表示的档位间隔 ,换算回原坐标的半个刻度是 ,相对误差约 10.9%(这是半刻度上界;该点按最近舍入实际约 9%)——比正规区里的 6.25% 明显恶化,而且元素越小越糟,继续小下去就归零。
同一个元素、同一个格式、同一组数据,唯一的差别就是缩放因子的粒度:6.25% 对 10.9%。这就是第五节那套「影响半径」论证的微观形态。
六、第二类误差:累加精度,以及为什么是 128
量化只是第一重误差。即使每个数都完美量化, 维内积的累加过程还会再丢一次精度。
6.1 硬件的实际行为
报告第 3.5.2 节在给硬件厂商的建议里给出了一个非常具体的描述:在当前 Hopper 架构的 Tensor Core 上,FP8 GEMM 的累加精度受限——对齐 32 个尾数积时,是按住其中最大的指数做右移对齐的,然后只取每个尾数积的高 14 位参与相加,超出这个范围的位被截断。 报告同时给出一个实测(§3.3.2):对两个随机矩阵、 的 GEMM,这种受限累加导致的最大相对误差接近 2%。
这段描述值得停一下:误差不是来自「存不下」,而是来自「对齐」。两个量级相差很远的数相加时,小的那个要右移才能和小数点对齐,右移过程中低位被丢掉——指数差越大,丢掉的有效位越多。误差上界因此与「参与累加的数之间的指数跨度」直接挂钩。
6.2 一个可用的数量级模型
设累加器保留 位有效位。第 次加法中,被丢弃的低位量级不超过
把 次加法串起来,有两种极端估值:
- 最坏情况(所有截断误差同号、互相不抵消):,相对最终结果的上界随 线性增长。
- 独立随机模型(每次截断误差近似独立、按随机游走叠加):。
代入 、:最坏情况给出 ,即 25%;随机游走给出 。报告实测的最大相对误差接近 2%——恰好落在两个界之间,这说明「界是保守的、真实硬件介于最坏与随机之间」这个判断是自洽的。(以上三个数字均为本文按该模型自算,不是报告的推导。)
这段模型还顺带解释了报告提到的另一句话:这个问题「在归约维度 较大时会更加明显」。原因就在模型里—— 越大,线性项越占上风,而 大正是大模型训练的常态(批量与宽度一涨, 就涨)。
6.3 把 截断: 的来历
既然误差上界与「连续累加的步数 」挂钩,最直接的干预就是限制 。
报告的做法是「提升到 CUDA Core 求高精度」:Tensor Core 的矩阵乘累加按受限位宽进行,但每累计到一个固定的元素区间 之后,就把这些部分和复制到 CUDA Core 的 FP32 寄存器上做一次全精度累加。根据报告的图 7 与正文,这个最小累加区间为 128 个元素,相当于 4 次 WGMMA;报告给出的判断是:这是「能显著改善精度、又不引入可观开销」的最小累加区间。
把 代回模型,上界立刻缩小:
对比 时的 25%:把累加区间从整段 截到 128,最坏界缩小 32 倍。 这就是「为什么是 128」——它不是魔法数字,它是把 的线性项按固定倍数折掉之后、在精度收益与指令开销之间选出的最小截断点。(0.78% 与 0.069% 为本文按该模型自算。)
报告还交代了这个改动的代价与它为何被隐藏:提升操作会降低单个 warpgroup 的 WGMMA 发射率;但在 H800 上通常有两个 WGMMA 并发存在,一个 warpgroup 做提升、另一个继续发射 MMA,两者重叠,Tensor Core 利用率得以维持。
妙的是,这套机制与上一节的分块缩放是同一个设计的两半:因为缩放因子是沿归约维度 分组给出的(每个 1×128 tile 一个),这些 per-group 缩放因子恰好可以在 CUDA Core 上、伴随高精度累加一起做反量化乘法,代价极小——报告第 3.3.2 节把它写成「与精确的 FP32 累加策略结合,可以高效实现标准 FP8 GEMM 不支持的分组缩放」。
6.4 把模型代回报告的数字:三处一致性自查
模型的价值在于能不能解释现实。这里用报告自己给的两三个数字反向检验它。
自查一:为什么报告报出的 loss 误差(低于 0.25%)比「最坏界 0.78%」还小? 两者并不矛盾,因为在 的配置下,随机游走估计是 0.069%、最坏界是 0.78%,而 0.25% 恰好在两者之间;再叠加两层体制性折减——累加误差在多层、多步训练里会被部分平均掉,且 loss 层面的相对误差不等于单个 GEMM 的相对误差。一个既做了分块、又做了提升的系统,落在 0.069%–0.78% 这个带里,是自洽的。
自查二:为什么「 越大越糟」? 本文模型里误差上界对连续累加步数 是线性的,而 在无截断时等于 ——所以「 大更糟」是模型的直接推论,不需要额外假设。
自查三:为什么分块能让 E4M3 全线可用? 把第五节的判据拿来量余量:分块之后,块内跨度比约为 3(128 个正态样本的期望最大值与标准差之比;这里用 作「需要保留的最小量级」的代理——它默认远低于 的量级不值得保留,真实数据里跨度比约 3 的块仍可能含少量下溢小值),换算成二进区间是 个;而 E4M3 一个共享缩放因子可用约 14.81 个二进区间(第四节)。1.6 / 14.81 约 11%,余量接近 9 倍。这个余量正是「敢把 E5M2 换成 E4M3」的定量依据:省下的动态范围换来了尾数位,而范围用不完。
三处自查都指向同一个结论:报告的数字与本文的推导彼此不打架;而这也正是判断一篇解读有没有跑偏的实用标准——如果推导不能复现报告里那些「为什么」,模型就该被换掉。
七、误差全景:一次 FP8 训练里有几处精度损失
把前面两节的结论并到一张表里,能看清一件事:「上 FP8」不是一个开关,而是一组互相配套的取舍。下表把报告里出现过的精度相关决策按「误差来源」归类,这也是后文所有判断的基础。
| 误差来源 | 出现在哪一步 | 治理方式 | 数量级参照 |
|---|---|---|---|
| 量化舍入(正规区内) | 每次把张量写成 FP8 | 无:格式固有,只由尾数位决定 | E4M3 上界 6.25%,E5M2 上界 12.5% |
| 量化下溢(次正规 / 归零) | 分组的缩放因子由该组 amax 决定 | 缩小分组:激活 1×128、权重 128×128 | 与组内跨度比挂钩(见第四节判据) |
| 累加截断 | Tensor Core 对齐后只保留高约 14 位 | 每 128 个元素提升到 CUDA Core 做 FP32 累加 | 见第六节数量级模型 |
| 存储量化 | 激活缓存、优化器状态 | 选格式:自定义 E5M6、BF16 存 AdamW 矩 | 0.78% / 0.39%(格式固有) |
| 通信量化 | MoE dispatch / combine | dispatch 前量化 FP8(缩放取 2 的整数幂)、combine 保 BF16 | 与 FP8 前向同量级 |
| 算子级保留 | attention、归一化、MoE gating、embedding、output head | 直接留在 BF16 / FP32 | 数值上为 0,代价是显存与带宽 |
这张表最有用的地方是把两类误差分开:第一类(舍入、下溢、存储与通信)由「分块 + 选格式」治理,第二类(累加截断)由「提升到高精度」治理,两者不能互相顶替。一个常见的工程误判,是看到 loss 抖动就先去调缩放因子,而真正的瓶颈其实在累加侧;反之亦然。要分清它们,最省事的办法是做一次纯 GEMM 的误差探针(见第十二节)。
八、三张图:数据流、误差局部化、累加截断
第一张图是报告第 3.3.1 节那个混合精度框架的骨架——注意它同时回答了两个问题:哪些算子走 FP8、以及误差在哪一步被两次截断。
flowchart TD
A["输入激活与主权重(BF16)"] --> B["按 1x128 激活 tile 与 128x128 权重块在线取 amax"]
B --> C["求缩放因子并量化为 FP8 E4M3"]
C --> D["FP8 GEMM 三件套:Fprop / Dgrad / Wgrad"]
D --> E["Tensor Core 分段累加(对齐后约 14 位有效位)"]
E --> F["每累计 128 个元素提升到 CUDA Core 做 FP32 累加"]
F --> G["输出 BF16 / FP32 激活"]
H["保留高精度:embedding / output head / MoE gating / 归一化 / attention"] -.-> D这张图说明了什么:FP8 只出现在「密度最高的那一段」——线性层的三种 GEMM;而量化与累加各自有一处被有意干预的关口(分块缩放、每 128 元素提升一次),其余算子与主权重整体留在 BF16/FP32。
第二张图把第四节与第五节的推导画成对照,解释「同样的离群值,为什么分块之后伤害变小」。
flowchart TD
T["整张量共享一个缩放因子"] --> T1["amax 由离群通道决定"]
T1 --> T2["其余通道被挤进次正规区,尾数位被侵蚀"]
B["每 128 个元素独立缩放"] --> B1["块内 amax 只由本块决定"]
B1 --> B2["小值留在正规区,保住 3 位尾数"]这张图说明了什么:分块量化并没有提高 FP8 本身的精度,它做的是把「离群值的影响半径」从一个张量缩小到 128 个元素。
第三张图是第六节的时间轴:误差上界与「连续累加的步数」挂钩,所以对策就是切断连续累加。
flowchart TD
A["K 维内积,K 很大"] --> B["Tensor Core 累加器:对齐后只保留约 14 位"]
B --> C{"已连续累计 128 个元素?"}
C -->|否| B
C -->|是| D["把部分和复制到 CUDA Core 的 FP32 寄存器"]
D --> E["做一次全精度累加,再开始下一段"]
E --> B这张图说明了什么:把误差从「随 线性增长」变成「随 128 线性增长、再被 FP32 段间接上」,这正是 想买到的东西。
九、DeepSeek-V3 的五条对策,逐条对应上面的机制
把报告第 3.3 节的设计摊开,会发现每一条都能对应到本文前面推出来的某一处误差来源。下面这张对照表是全文的收口。
| 报告中的设计 | 针对哪一处误差 | 报告给出的关键口径 |
|---|---|---|
| 细粒度量化:激活 1×128 tile、权重 128×128 块 | 共享缩放因子的下溢连坐(第四节) | 按更小的元素组自适应缩放,「更好地容纳离群值」 |
| 提升到 CUDA Core:每 个元素做一次 FP32 累加 | Tensor Core 约 14 位累加的截断误差(第六节) | 图 7 与正文:128 个元素相当于 4 次 WGMMA,是「能显著改善精度且无实质开销」的最小区间 |
| 尾数优先于指数:所有张量统一用 E4M3 | E5M2 的 2 位尾数精度不足 | 与既有「前向 E4M3、反向 E5M2」的混合方案相对;可行性归因于分块缩放「让分组元素共享指数位、缓解动态范围受限」 |
| 在线量化:每个 tile / 块在线取 amax 求缩放因子 | 延迟缩放的尺度滞后 | 相对「用历史 amax 推断当前缩放因子」的延迟方案,改为在线计算,以保证尺度准确并简化框架 |
| 低精度存储与通信 | 显存与 all-to-all 带宽,而非数值本身 | AdamW 一/二阶矩存 BF16;主权重与梯度保 FP32;attention 后的 Linear 输入用自定义 E5M6 且缩放因子取 2 的整数幂;MoE dispatch 前量化到 FP8、combine 保留 BF16 |
几条容易被忽略、但值得单独点出来的细节:
- 保留高精度的算子是有清单的,不是「看着办」:embedding、output head、MoE gating、归一化算子、以及 attention 算子全部维持在 BF16/FP32。报告用「对低精度计算敏感」与「代价低、反正不差这一点」两类理由解释这个保留。
- 主权重与梯度始终是 FP32,只有优化器的一阶、二阶矩被压到 BF16。这个取舍方向很清楚:状态量(矩)对噪声的容忍度高,而真正决定更新方向的量保持高精度。
- attention 之后的 Linear 输入用了一个自定义的 E5M6 格式,而不是 E4M3。报告给的理由是这些激活同时要被 attention 的反向用到、对精度敏感;它比 E4M3 多 3 位尾数(,相对误差上界 0.78%)。同一处还有一个细节:这些激活在反向会从 1×128 的量化排列转成 128×1,为了避免二次量化引入额外误差,缩放因子被取整为 2 的整数幂。
- 通信侧也做了量化:MoE up-projection 之前的激活量化到 FP8 再进 dispatch,与 FP8 Fprop 天然衔接;但 forward/backward 的 combine 组件被保留在 BF16。这一条的动机是带宽,而不是算力。
- 在线量化选得比延迟量化更贵,但更准。延迟缩放要靠前若干轮的 amax 历史去猜当前的缩放因子,省下了每步统计 amax 的开销,代价是尺度滞后;报告选择在线统计,理由写成「保证尺度准确并简化框架」——这是一次明确拿带宽/指令换数值稳定的取舍。
9.1 报告自己给出的验证与成本
上面这些都是机制,机制要能兑现才行。报告给出的验证是:在接近 DeepSeek-V2-Lite 与 DeepSeek-V2 的两个模型规模上、训练约 1T token,FP8 训练模型相对 BF16 基线的相对 loss 误差始终低于 0.25%,报告认为这一水平落在训练随机性可接受的范围内。
成本侧的数字同样值得记:预训练 14.8T token 花掉 2.664M H800 GPU 小时(即每 1T token 约 180K GPU 小时;换算到 2048 卡集群,是每 1T token 约 3.7 天),加上上下文扩展 119K 与后训练 5K,全程合计 2.788M H800 GPU 小时;报告按每 GPU 小时 2 美元的租用价折算为约 557.6 万美元。同时报告强调,训练全程未出现不可恢复的 loss spike、也没有回滚——这一条才是「FP8 训练能稳」的最终证据,前文的推导只是解释它为什么可能。
十、对照表:三代缩放范式的分野
把 NVIDIA 侧公开的口径与 DeepSeek-V3 的选择放在一张表里,能看清这不是一次孤立的技术选择,而是一条可外推的路线。
| 范式 | 缩放粒度 | 缩放因子存储 | 何时计算 | 典型代表 |
|---|---|---|---|---|
| 延迟缩放 | 每张量一个 | FP32 | 用前若干轮迭代的 amax 历史推断 | 早期 FP8 训练配方(本行口径出自 NVIDIA Transformer Engine 文档) |
| 在线逐张量缩放 | 每张量一个 | FP32 | 当前轮在线取 amax | 同上文档列出的 current scaling 配方 |
| 分块缩放 | 每 128 个元素(激活)/ 128×128(权重) | FP32 | 当前轮在线取 amax | DeepSeek-V3;NVIDIA Transformer Engine 已提供对应配方 |
| 微缩放(MXFP8) | 每 32 个连续元素 | 8 位幂次(E8M0) | 由硬件格式规定 | OCP 微缩放格式规范 v1.0 |
| 微缩放(NVFP4) | 每 16 个元素(权重用 16×16 二维块) | E4M3,另加一个每张量 FP32 因子 | 由硬件格式规定 | NVIDIA 后续一代硬件与其 NVFP4 预训练工作 |
这张表里有两点是本文想强调的:
- DeepSeek-V3 的 1×128 / 128×128 与后来的 MX 微缩放格式是同一个思想的两个实现。报告自己也写了这一点:其细粒度量化「与微缩放格式的思路高度一致」,而下一代 GPU 已宣布支持更小量化粒度的微缩放格式。NVIDIA 的 Transformer Engine 文档里那个明确注明「as described in DeepSeek-v3 paper」的分块缩放配方(
Float8BlockScaling),是这条判断最直接的落地证据。 - 粒度越细,缩放因子的存储与搬运开销越不可忽略。到 NVFP4 这一代,缩放因子本身要占 1 个 E8M0 或 E4M3 值 / 16 或 32 个元素;此外还引入了随机舍入、随机 Hadamard 变换、以及「最后几层用更高精度」的规则。这些新增的工程件说明:精度继续往下压,代价从「精度」转移到了「算法复杂度」。
十一、工程含义:什么时候值得上 FP8
把前面的机制翻译成几条可操作的判断。
第一,先看瓶颈在算力还是在别处。 FP8 的收益主要来自 GEMM 的算力(报告写的「理论上翻倍」)以及权重/激活/通信的字节数减半。如果你的训练瓶颈是 all-to-all 通信或数据加载,FP8 本身不会解决它——报告对 MoE 通信的处理是另一套(DualPipe 与通信核函数),量化只是顺带把带宽又压了一次。
第二,分块缩放不是「免费的开关」。 它依赖「高精度累加 + 沿 维的分组缩放」这套组合实现;报告明确说标准 FP8 GEMM 不直接支持沿内维的分组缩放因子,是配合 FP32 累加策略才高效落地的。在自己的训练栈里复现时,请把「分块」与「高精度累加」当成一个整体来验证,而不是只打开其中一个。
第三,模型规模与超参不变性是有证据的:FP8 格式论文(2209.05433)报告过在不改超参的情况下匹配 16 位训练质量,覆盖 CNN、RNN、Transformer 与最大 175B 参数的语言模型;DeepSeek-V3 报告则是把 FP8 与 BF16 放在同一批基线模型上做对照(附录 B.1),未声明超参细节。⚠️ 「不用改超参」这个结论的出处是格式论文,不是 V3 报告——引用时别混。这两条合起来说明 FP8 已经不是「冒险的前沿尝试」,而是可复现的工程选项。
第四,别把 当成普遍最优。 128 这个值是「最小且显著改善精度」的取值,而它背后的硬件事实是「对齐后保留约 14 位」。换到不同架构、不同累加器位宽,最优 会变;报告的 §3.5.2 也正是基于这一点向硬件厂商提了建议——希望未来 Tensor Core 的 FP8 GEMM 累加精度更高。
第五,收益要按「哪一类误差被消掉」来算,而不是按位数算。 从 bf16 换到 FP8,省下的是带宽与算力;没被省掉的是累加截断与算子保留带来的开销。如果一次改造只换了 GEMM 的数据类型、没动累加路径,你会拿到一半收益、同时拿到一整份累加误差。
11.1 算清收益上限:2× 的 GEMM 换不来 2× 的训练加速
一笔必须提前算清楚的账:FP8 把 GEMM 的理论算力翻倍,但这不等于训练步速翻倍。设一步训练的总时间为 ,其中 GEMM 占比例 ,其余(通信、优化器、归一化、attention 等)占 。换 FP8 后,GEMM 部分的时间理论上减半:
于是加速比有一个与 有关的闭式上界:
代两组数字: 时约 1.43 倍; 时约 1.67 倍。
这个式子的用处是在改造之前就判定值不值:它告诉你收益的天花板完全由「GEMM 占比」决定,而这个占比可以用一次 profile 直接量出来。它同时解释了为什么报告要把 DualPipe 与通信核函数和 FP8 放在同一段里讲——当 GEMM 变快,非 GEMM 部分占比上升、 变小,加速比的边际收益随之下降;不解决通信,FP8 省下的那一半时间会被剩下的部分吃掉。
还有一层隐含成本值得记:分块量化本身要额外的统计与反量化运算,提升操作也会占掉一部分 Tensor Core 利用率(见第六节末)。这些开销都被记在「其余」里,所以真实加速比通常略低于上面的上界——把它当成上界用,而不是当成预期值。
十二、怎么在自家训练栈里最小验证 FP8
这一节是给动手派的操作清单。它的目标是用尽量少的算力,把第七节那张表里的两类误差分开,而不是一上来就跑全量对照。
第零步:先量一次「离群有多离群」。 这一步只读数据、不改训练,却决定了后面所有选择。对每个分组算跨度比 (组内 amax 与组内标准差的比;用 当分母是代理,它默认「远低于 的量级不值得保留」;要更严格,应改用该分组内你真正在意的最小量级作分母),然后看分布:
- 若绝大多数分组 ,说明离群并不凶猛,逐张量缩放可能就够了,先别急着上分块;
- 若尾部有一批分组超过 (第四节的判据线),分块是必需的;此时再看这些「超标分组」的占比——如果它和 这种「少数通道」型分布吻合,1×128 分块正对症;如果每个分组都超标,那问题不是「少数离群通道连坐」,而是「分组内部本身就太宽」,此时该考虑的是更细的分组或分布整形(对应第十三节 4 位那一代的随机 Hadamard 变换),而不是简单把 128 调小。
这一步的产出应当是一张分布图,而不是一个结论句——它同时回答「要不要分块」与「分多细」两个问题。
第一步:确认三个前提是否成立。 这三条任一不成立,你的 FP8 收益都会打折,且症状会伪装成「精度问题」。
- 你的硬件/软件栈是否支持沿归约维的分组缩放,并且配了高精度累加?不支持时,1×128 与 128×128 这两档要么退化成逐张量,要么需要额外的反量化开销。
- 你的框架是否暴露了累加区间这个旋钮(对应 )?没有的话,累加侧只能被动接受硬件默认值。
- 你的卡上并发 MMA 是否足够,能把提升操作的指令开销藏掉?报告口径是 H800 上两个 warpgroup 并发。
第二步:做一次纯 GEMM 的误差探针,把累加误差单独量出来。 取两个随机矩阵、固定 (对齐报告用的 4096),在「有提升」与「无提升」两种配置下各算一次,与 fp64 参考解比最大相对误差。这个实验与模型结构、数据分布都无关,却能把第二类误差直接测出来;如果两种配置差异不明显,说明你的瓶颈在第一类误差上,先去调缩放粒度。
第三步:用「分组内的下溢比例」诊断第一类误差。 这是一个可以直接算的量:对每个分组统计
即落在正规区下限之下的元素占比。三个使用要点:(a)必须按分组统计,不要对整张量取平均——受损的是少数块,平均会把信号稀释掉;(b) 这个量随训练步数变化,值得按步记录而不是只看第一步;(c) 它一旦持续显著大于 0,先把分组切细,再谈别的。
第四步:对照实验要「同超参、同数据顺序、同 token 预算」,只切精度。 报告附录 B.1 是在同一批基线模型上做的 BF16/FP8 对照,但没有声明是否同数据顺序——把它当作方法建议看,不要当成报告背书。判据建议同时看两个:相对 loss 误差,以及少量下游任务分数;不要用单步 loss 曲线的形状下结论——训练本身的随机性足以制造出「看起来 FP8 更差」的曲线。
第五步:给自己定阈值时,以「同规模」为限。 报告那句「低于 0.25%」是在两个中等规模、约 1T token 的条件下测得的;把它当成一个「同量级参考」而不是你的验收线。规模、数据、超参一变,误差的可接受带也会变。真要立内部标准,就在自己的尺度上先跑一次 bf16 重跑的方差,把「随机性带宽」量出来,再判断 FP8 是否落在带内。
一句提醒:这五步里最容易跳过、也最容易出事的是第三步。第七节的表讲得很清楚——第一类误差是局部现象,用全局指标去监控它,等于没有监控。
十三、从 FP8 到 4 位:治理结构没变,件数变多了
如果 FP8 的结论成立,一个自然的问题是:再往下压到 4 位会怎样?NVIDIA 后续的 NVFP4 预训练工作给出了一个很清楚的回答:治理结构完全一样,只是每一件都要做得更狠。
它报告的要素可以逐条映射回本文的框架:
- 格式是 E2M1(2 位指数、1 位尾数),可表示的最大幅度只有约 6——相对精度降到极致,于是分块缩放的粒度进一步细到每 16 个元素,缩放因子用 E4M3 存储,再加一个每张量 FP32 因子防溢出。
- 引入了随机 Hadamard 变换(16×16)来「重塑张量分布、使其更接近高斯」,从而压制块级离群——这对应本文第五节的思路:块内跨度越小,越不容易越界。
- 用随机舍入替代确定性舍入。这一点值得单独算一下:确定性舍入的误差是系统性的(同一个数每次都被往同一个方向拉),而随机舍入让
即误差在期望意义上无偏,代价是方差变大。在 4 位这种极端精度下,「有偏」比「有噪」更致命,所以宁可换。
- 权重改用 16×16 的二维量化块,理由可以自己推出来:如果按一维(比如 1×16)切块,权重矩阵 与其转置 的分组成员就不一样,同一个元素在前向与反向会落在不同的量化块里、得到不同的量化值;而 16×16 的二维块在转置下成员集合不变,前后向自然一致。
- 最后几层保留更高精度——这与 FP8 时代保留 attention/归一化/gating 是同一个策略:把「对噪声最敏感的部分」从低精度里摘出去。
效果参照:这份工作用一个 12B 模型、在 10T token 上训练,报告的 MMLU-pro 得分为 62.58%,与 FP8 预训练基线的 62.62% 基本持平。
于是可以得到一个比「位数越低越难」更有用的判断:低精度训练的难点不在位宽,而在「有多少件事必须同时做对」。FP8 需要做对两件(分块缩放 + 高精度累加),4 位需要做对五件(更细分块 + 分布整形 + 随机舍入 + 二维块 + 选择性高精度层)。位宽下降带来的是链路变长,而不是某一环的难度突增。
十四、边界与未解
以下几条是本文认为必须说清的限制,而不是瑕疵:
- 报告的 2% 是随机矩阵的测试结果,不是「任何模型上都会差 2%」。本文用它来标定误差模型的数量级,不能反过来当作你自己任务的收益或损失预期。
- 0.25% 的相对 loss 误差是在两个较小规模(约 V2-Lite / V2 量级)、约 1T token 上测得的,不是 671B 全量预训练的逐点对比。把这条外围证据与「671B 全程无回滚」的工程结论分开看,才是对报告的正确读法。
- 本文第六节的误差模型是自建的数量级模型,它给出的 25% 与 0.39% 是上界与随机估计,不是报告的推导;报告只给了「接近 2%」这一个实测值。模型的价值在于解释「为什么 越大越糟、为什么截断有效」,不在于精确预测误差。
- 分块在激活侧不能照搬权重侧。 报告指出按权重方式对激活做块级缩放会引发训练不稳定(附录 B.2),这意味着「离群值只污染本块」这个结论在激活上需要按 1×128 的形态才能成立;这块的完整稳定性分析只能回到报告的附录。
- E5M6 不是标准格式。 它是这份工作为「attention 之后的 Linear 输入」单独定义的自定义精度档,跨框架复用时没有现成载体;同时它的缩放因子被取整为 2 的整数幂,这是一处刻意的工程取舍(牺牲一点表示效率,换取反向换排列时不引入二次量化误差)。
- 提升操作并非无代价。 报告明说它会降低单个 warpgroup 的 WGMMA 发射率,靠 H800 上两个 WGMMA 并发才能把开销隐藏掉。若硬件并发度不同,这笔开销就未必能白拿。
- 本文第五节那个 3.1% 的受影响元素占比是一个带假设的算例(、单离群通道、落在独立块内),真实激活的离群分布未必满足这些前提;它只用来做量级对照。
- 第十二节的方法清单是本文组织的,不是报告给出的流程。 其中「按分组统计下溢比例」与「纯 GEMM 误差探针」两步,报告中并没有以这个形式出现——报告给的是结论与硬件建议,落到工程诊断清单是本文的整理。
十五、五条常见误解
误解一:「FP8 精度只有 3 位尾数,所以训练注定比 BF16 差很多。」 不成立。相对误差是 的量级,但真正的差距由「有多少元素掉出正规区」决定;分块缩放正是把这个问题按分组规模缩小。
误解二:「分块量化提高了 FP8 的表示精度。」 没有。FP8 的位布局没变, 也没变。分块改变的是离群值的影响半径,以及分组内部的动态范围。
误解三:「用一个缩放因子就够了,反正误差是相对的。」 这句话在正规区内是对的,正是本文明确定下来的结论;但它恰好掩盖了真正的失败模式——下溢。共享范围越大,越有可能出现「同一组里既有 、又有 」的局面。
误解四:「装下 8 位、算得快就行,累加精度无关紧要。」 恰恰相反。报告给出的硬件事实是:对齐后只取高约 14 位, 的随机矩阵 GEMM 最大相对误差接近 2%——而这是在量化已经做对之后仍然存在的误差。必须靠提升到 FP32 累加来截断。
误解五:「E4M3 和 E5M2 随便选一个都行。」 两者的取舍是明确的:E4M3 换精度、E5M2 换范围。传统配方因此前向用 E4M3、反向用 E5M2;而 DeepSeek-V3 敢全线用 E4M3,前提是分块缩放已经把每组的动态范围需求压下来了——这是一个依赖前一项设计的结论,不能单独摘出来用。
十六、小结
把全文压缩成四句话:
- 浮点量化的相对误差与缩放因子无关,恒为 ;共享缩放因子的真实代价是下溢,而一个共享因子只覆盖约 的组内跨度。
- 分块量化不提升精度,只缩小离群值的影响半径:同样的离群值,整张量缩放伤 100% 的元素,1×128 分块最多伤到 的比例。
- 累加是第二重误差,与量化无关;它的上界随连续累加步数增长,所以对策是截断——每 个元素把部分和提升到 CUDA Core 做 FP32 累加,把最坏界按固定倍数折掉。
- DeepSeek-V3 的五条设计各自对应一重误差:分块缩放治下溢、提升累加治截断、E4M3 全集治精度、在线量化治尺度滞后、低精度存储与通信治带宽——而它们能被组合起来的前提,是「沿归约维分组缩放」与「高精度累加」在工程上被当成一件事实现。
真正值得带走的判断是最后这一条:低精度训练不是「选一个格式」,而是「为一组误差找到一个能被拆开、逐项治理的结构」。DeepSeek-V3 的贡献不在于发明了 FP8,而在于把这套结构做到了 671B 的规模上,并且用「全程无不可恢复回滚」给出了工程证据。而当下一个位宽(4 位)到来时,变的只是清单长度,不是这份结构。
最后补几条「怎么用这篇」的话,它们比结论本身更影响它的价值:
- 把它当检查表,而不是当结论。 第一节到第六节的推导给出的是一组判据:下溢门槛 、累加步数 的线性项、以及 的加速上界。它们的价值在于你能拿自己的数据代进去。
- 代进去之后结论与本文不同,是正常的——那才是判据被使用的证据。反过来,如果一篇文章的所有数字都只能由原文复述、不能被代换,它提供的是措辞,不是判断。
- 分清「来源说的」与「本文算的」。 文中每个数字都能在文末两条清单里找到归属:来源清单里的属于报告与论文,自行推导清单里的属于本文的模型。
- 引用数字时请连归属一起引用,否则一个带假设的算例会在传抄中变成一条「官方结论」——这是技术解读里最常见的信息失真方式。
- 格式选择应当先实测、再定论。 E4M3 与 E5M2 的取舍在本文是一张表,在你的栈里应该是一次实验:同一批数据、同一个 ,分别量化成两种格式,比较最大相对误差与误差分布,而不是照搬别处的结论。
- 关于复现。 本文所有自算数字都能用文中的算式手算复现,不需要任何未公开数据;这正是把「解读」与「转述」区分开的方式。
- 若只想快速取用:看第七节的误差清单(判断瓶颈在哪一类)与第九节的对策对照表(DeepSeek-V3 各选了什么);若要做改造,从第十二节的第零步开始。
这几条合起来,就是这个栏目做深度解读的底线:宁可把边界写清楚,也不制造确定性。
📋 来源与核验记录
下列一手来源均为本轮实地打开核验(2026-10-03):
- DeepSeek-AI. DeepSeek-V3 Technical Report. arXiv:2412.19437(v1 2024-12-27 提交,v2 2025-02-18 修订)。用于:模型规模与训练成本(671B 总参数 / 37B 激活、14.8T token、2.664M 预训练 GPU 小时、合计 2.788M H800 GPU 小时、按每 GPU 小时 2 美元折算约 557.6 万美元)、FP8 训练在约 1T token 上相对 loss 误差低于 0.25%、第 3.3 节混合精度框架与五项策略、第 3.5.2 节「对齐 32 个尾数积、右移对齐后只取高 14 位」与第 3.3.2 节「K=4096 随机矩阵 GEMM 最大相对误差接近 2%」。https://arxiv.org/abs/2412.19437
- 上述报告的 arXiv HTML 全文版(第 3.3.1–3.3.3 节的完整正文;量化粒度 1×128 激活 tile 与 128×128 权重块、在线量化、AdamW 矩存 BF16 而主权重/梯度保 FP32、attention 后 Linear 输入用自定义 E5M6 且缩放因子取 2 的整数幂、MoE dispatch 前量化 FP8 而 combine 保 BF16、提升到 CUDA Core 的累加区间为 128 个元素相当于 4 次 WGMMA,均出自这里)。https://arxiv.org/html/2412.19437v2
- Micikevicius, P. et al. FP8 Formats for Deep Learning. arXiv:2209.05433(v1 2022-09-12,v2 2022-09-29)。用于:E4M3/E5M2 的位布局定义、E4M3 通过不表示无穷且只保留一个 NaN 位型来换取动态范围、以及该格式在含最大 175B 参数语言模型在内的任务上匹配 16 位训练质量。https://arxiv.org/abs/2209.05433
- NVIDIA. Using FP8 and FP4 with Transformer Engine(Transformer Engine 官方文档的 fp8_primer 示例章节)。用于:E4M3 上限 448 / E5M2 上限 57344、前向 E4M3 与反向 E5M2 的通行理由、即时刻度与延迟刻度两种缩放策略的权衡、微缩放 MXFP8 的 32 元素粒度与 E8M0 缩放因子、NVFP4 的 16 元素粒度与 E4M3 缩放因子、以及「明确注明 as described in DeepSeek-v3 paper 的分块缩放配方(Float8BlockScaling)」这一落地证据。https://nvidia.github.io/TransformerEngine/examples/fp8_primer.html
- NVIDIA. Pretraining Large Language Models with NVFP4. arXiv:2509.25149。用于:FP8 训练已被广泛采用、继续下压到 4 位时的稳定性挑战(随机 Hadamard 变换压制块级离群、二维量化、随机舍入、选择性高精度层),以及 12B 模型 / 10T token 上 MMLU-pro 62.58% 与 FP8 基线 62.62% 的对照。https://arxiv.org/abs/2509.25149
- Open Compute Project. OCP Microscaling Formats (MX) Specification, Version 1.0。用于:微缩放格式的规范化定义(含 E8M0 缩放数据类型)与其参与厂商范围。https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
- deepseek-ai/DeepSeek-V3(官方仓库 README)。用于:模型摘要(61 层、MoE、MLA)以及其列出的 FP8/BF16 推理支持生态(vLLM、SGLang、LMDeploy、TensorRT-LLM、MindIE)。https://github.com/deepseek-ai/DeepSeek-V3
本文自行推导与自算数字(非上述来源,属本文计算,假设值已随算式列出):
- 第三节的格式对照表:半 ulp 相对误差上界 的取值(E4M3 的 6.25%、E5M2 的 12.5%、E5M6 的 0.78%、bf16 的 0.39%、fp32 约 ),以及两种 FP8 格式正规区比值范围的折算(E4M3 约 / 28672,E5M2 约 / 9.40×10⁸)。
- 第四节的相对误差推导 ,以及由它导出的两道下溢门槛:保持全精度需 (约 )、完全归零阈值(按四舍五入、半个次正规刻度)为 (约 )、分组内部跨度判据 。
- 第五节的算例模型与结果:隐藏维度 、单离群通道 时,整张量缩放受影响元素占比 100%、1×128 分块受影响元素占比 3.1%;正态情形下 128 个样本最大值的期望约为 3.1 倍标准差();以及「归零需要跨度比超过约 」的折算。
- 第六节的累加误差数量级模型:以「每次加法丢弃不超过最大量级 × 、」为假设, 时最坏界 25%()、随机游走估计 0.39%(); 时最坏界 0.78%()、随机游走估计 0.069%();以及「截断到 128 使最坏界缩小 32 倍」的比值。
- 第六节末「缩放因子可随 FP32 反量化一起在 CUDA Core 上乘」与第八节「 相当于 4 次 WGMMA、即每段 128 元素」的对应关系,为本文依据报告第 3.3.2 节正文所做的归纳。该数值在报告中直接给出,原文为「setting elements, equivalent to 4 WGMMAs, represents the minimal accumulation interval…」;本文发布前又复核了一次 arXiv HTML 的内联公式(
alttext="N_{C}=128")确认无误——注意纯文本抽取该页会丢掉内联数学,只看抽取结果会误以为符号缺失。 - 第 5.1 节的算例:缩放因子 0.0279 与 2.232、全精度门槛 4.36×10⁻⁴ 与 3.49×10⁻²、0.03 量级元素的两条误差算法(相对误差给出 1.88×10⁻³、ulp 半刻度给出 1.74×10⁻³)、次正规区下 0.02 量级元素的相对误差约 10.9%(半刻度上界;该点按最近舍入实际约 9%;对比正规区的 6.25%)、“是门槛的约 46 倍”这一比值,以及 E4M3 次正规档位共 7 个的计数,均为本文自算。
- 第 9.1 节的成本折算:由报告给出的 2.664M H800 GPU 小时 / 14.8T token 推出的「每 1T token 约 180K GPU 小时」,以及换算到 2048 卡集群的「每 1T token 约 3.7 天」,均为本文自算(报告只给总量)。
- 第 6.4 节的三处一致性自查:随机游走估计 0.069% 与最坏界 0.78% 构成的区间、块内跨度比约 3 对应的约 1.6 个二进区间、以及「1.6 / 14.81 约 11%、余量接近 9 倍」的折算,均为本文自算。
- 第十二节第零步给出的判据线( 与 )为本文据第四、五节判据自行整理的诊断口径。
- 第 11.1 节的收益上限推导:、,以及 时约 1.43 倍、 时约 1.67 倍的代入值,均为本文自算。
- 第十三节的映射与公式:随机舍入的无偏性 、以及「一维块在转置下分组成员改变、16×16 二维块在转置下成员集合不变」的推导,均为本文自行整理(NVFP4 相关事实来自来源 5 与来源 4,推导与映射关系为本文所加)。
未能核实的点(如实记录):
- 报告附录 B.1(FP8 验证实验的模型规模细节)与附录 B.2(激活按块缩放导致训练不稳定的分析)本轮只读到正文对其的引用,未逐页核对其内部数据。
- 第五节 3.1% 的算例假设「离群通道落在互不相同的块内」,真实激活的离群结构可能集中在同一块的相邻通道上,此时受影响比例会低于该算例。