本页章节
EXACT MECHANICS / FLOATING POINT
数值计算:同一公式为什么算出不同结果
有限位数只能表示部分数值。存储、运算、累加和格式转换都可能舍入;从单个数字和短求和开始,理解混合精度、稳定 softmax 与训练误差。
指数决定范围,尾数决定相邻值间距
| 格式 | 指数位 | 尾数小数位 | 1 附近上方间距 |
|---|---|---|---|
| FP16 | 5 | 10 | 2⁻¹⁰ |
| BF16 | 8 | 7 | 2⁻⁷ |
| FP32 | 8 | 23 | 2⁻²³ |
舍入与累加顺序
每个操作数和加法都舍入到所选格式所选格式求和:;实数算术结果:
| 步骤 | 输入 | 操作数舍入 | 累加前 | 累加后 |
|---|
采用 round-to-nearest ties-to-even,保留渐进下溢。硬件若使用 flush-to-zero 或更高精度累加会得到不同结果;这不是某块 GPU 的仿真。
大数附近的间隔较大,小更新可能在舍入后消失。两个接近的大数相减,还会暴露此前舍入造成的相对误差。改变 batch 分组或并行规约顺序,可能改变浮点求和路径;需要按任务和精度设置容差,不能默认逐位相等。
先减最大值,为什么结果不变?
同一分布,不同整体偏移
此处使用 JavaScript 双精度 explogits=[偏移, 偏移−1, 偏移−2]。格式选择仅影响上面的舍入实验。
直接 exp 后归一化:
减最大值后归一化:
稳定 logsumexp:
稳定改写处理指数溢出和比例尺度问题,仍受浮点舍入、输入非有限值和 mask 约定限制。全为 −∞ 的 logits 没有可归一化的有效候选;不能用一个看似正常的分布掩盖输入错误。
一次训练中,哪些地方用了什么精度?
参数与状态存储
模型权重、master copy、梯度、动量和平方矩分别记录 dtype。
乘法与累加
输入格式、Tensor Core 乘法、累加器与最终输出格式可能不同。
归约与同步
loss、Norm、softmax 和多卡梯度分别核对累加与通信精度。
优化与写回
FP16 loss scaling、unscale、有限值检查、裁剪和参数写回按顺序处理。
更高精度 master 权重能保留低精度副本无法表达的小更新,再转换供前向使用;具体训练器是否维护它取决于实现。loss scaling 放大反传数值,并在更新前还原梯度,主要处理低精度下溢;它无法修复错误标签或无定义的目标。
数值诊断可以固定小输入,用高精度参考逐层比较前向、梯度和更新误差。记录绝对与相对误差、非有限值位置和求和顺序;接近零时相对误差的分母需要额外约定。
从缩放梯度,到一次实际参数更新
每个窗口包含两个等权 microbatch。先把各自梯度除以 2,再用同一个 scale 放大;完成累积后统一还原尺度、检查有限值和裁剪。窗口结束时才决定是否更新参数及 scale。
四个更新窗口的状态账本
预设梯度 · 显式舍入 · 不运行 GPUSGD,无动量和衰减;初始参数 [0.8,−0.5] 以 FP32 保存。学习率 η=0.05/(1+0.2u),u 为已经成功的更新数。连续两次有限更新后 scale×2,溢出时 scale÷2。
| 窗口 | 末次 scale → 下一窗口 | 是否更新 | 本窗口 LR | 更新后参数 |
|---|
所选窗口:两份梯度怎样合并?
| Microbatch | 原梯度 | scale | 除以 2 后缩放并舍入 | FP32 累积值 |
|---|
还原后梯度:;裁剪时范数:;裁剪系数:。
实际应用梯度:;理想算术参考:。
这套 scale 增长规则用于教学,不代表任何框架的默认配置。预设梯度不依赖当前参数。FP16 只作用于缩放后的各梯度贡献;实际反传中的逐算子精度需按实现核对。
裁剪阈值必须对应还原后的梯度
原梯度 [3,4] 的范数是 5,阈值 1 给出 [0.6,0.8]。若 scale=8 时先裁剪 [24,32],再除以 8,只得到 [0.075,0.1]。相同阈值被应用到了不同尺度。
一个累积窗口使用同一 scale
若两份贡献分别乘 S₁、S₂,最后统一除以 S₂,第一份贡献会额外乘 S₁/S₂。只有完成当前窗口,才能为后续窗口更改 scale。
跳步与调度器计数一起记录
溢出窗口仍消耗数据和计算,但本例不会更新参数或推进学习率计数。实际训练器可能按尝试次数、成功更新或 token 数调度,恢复时应保存相同口径。
还原梯度后仍可能丢失小更新
scale 能帮助微小梯度在低精度中存活,参数写回仍受参数格式的间距限制。autocast 管理算子精度,scaler 管理梯度尺度;是否另存 master 权重由训练器决定。
FP4 原生训练,要逐项指定哪些计算?
Nemotron 3 Super 的公开配方把大部分线性层放入 NVFP4 训练路径,同时让不同部件保留其他精度。读“FP4 训练”时,需要分别查前向乘法、输入梯度、权重梯度、累加、归约、参数写回与优化器状态;模型名称中的位宽不能替代这份账本。
| 固定版本中的层类型 | 报告格式 | 需要理解的选择 |
|---|---|---|
| 未另行列出的线性层 | NVFP4 | 前向、输入梯度与权重梯度 GEMM 采用低位路径。 |
| 末段 15%、latent / MTP、QKV / attention 投影与 embedding | BF16 | 按部件保留数值精度,具体名单以配方为准。 |
| Mamba 输出投影 | MXFP8 | 报告将这一选择与较小规模实验中观察到的下溢联系起来。 |
Transformer Engine 2.16 的 NVFP4 说明使用 E2M1 元素和两层缩放:一维块含 16 个元素,块 scale 为 E4M3,整个张量另有 FP32 scale。其默认权重配方使用 16×16 的二维缩放;激活与梯度的缩放方向需对应 GEMM 的归约轴。
前向与反向需要兼容的表示
线性层前向、dX 和 dW 使用不同转置与归约方向。报告为权重采用二维缩放来保持相关量化表示的一致性;不能把对一个方向量化后转置,与按另一个方向重新量化视为同一数值操作。
稳定训练还依赖其他配方
公开说明还包含随机 Hadamard 变换与梯度随机舍入。应核对它们作用在哪类张量、随机状态怎样保存、缩放状态怎样恢复,再测误差、下溢和独立任务结果。不能从单个张量的 MSE 推出完整模型的训练收益。
固定 32 个数,只看缩放范围的影响
构造激活 x=[6,15 个 1,16 个 0.1],固定线性层的 32 个权重全为 1,y=Σwᵢx̂ᵢ。简化计算只做 E2M1 最近值舍入,分别让 32 个数共用 scale,或每 16 个数共用 scale。
| 计算方案 | 本例 scale | 输出 y | dW 最大绝对误差 |
|---|---|---|---|
| 高精度输入参考 | 无量化 | 22.600000 | 0.000000 |
| 32 个数共用 scale | 1 | 21.000000 | 0.100000 |
| 每 16 个数共用 scale | 1 / 0.016667 | 22.600000 | 0.000000 |
外部上游梯度固定为 1;量化后的激活作为常量,因此 dWᵢ=x̂ᵢ,可对每个权重做有限差分。这里没有对舍入函数使用直通估计器。分块在这组输入中保留了后 16 个小值,不证明其他数据或模型质量必然改善,也没有测量低位硬件速度。
一手依据:Nemotron 3 Super 固定配方 99a7e45、技术报告第 2.2 节与表 3,格式和缩放机制绑定 Transformer Engine 2.16。公开配方同时说明部分预训练数据未发布;本站未重建其训练数据链或执行 GPU 训练。
适用范围与一手资料
原有二进制舍入采用最近偶数;更新账本使用预设梯度与教学 scale 规则。新增 FP4 教具使用高精度块 scale、等距取较小幅度,只重算线性输出与 dW,不实现完整 NVFP4、随机舍入或 GPU kernel。厂商逐层精度绑定固定配方。
公式与机制的原始依据 · 6 项
- PyTorch · Numerical accuracy浮点精度、非结合性、矩阵运算累加与非有限值
- PyTorch · Automatic Mixed Precision examples梯度累积、unscale、裁剪与 scaler 更新顺序
- PyTorch · CrossEntropyLoss完整类别分母、ignore_index 与 reduction
- NVIDIA Transformer Engine · FP8/FP4, release 2.16NVFP4 的 E2M1、E4M3 块 scale、FP32 全局 scale、二维权重缩放和稳定训练配方;本站简例不实现完整格式或硬件 kernel
- NVIDIA · Nemotron 3 Super pretraining / 99a7e45固定官方配方中的逐层精度名单与未发布数据范围;NVFP4、BF16、MXFP8 分工不等于全部状态都以 4 bit 保存
- NVIDIA · Nemotron 3 Super report (PDF 2026-04-03)第 2.2 节的精度,以及 2.4–2.5 节的 WSD/平均读出;报告保存间隔 1000 步,与固定配方 2000 步并列,不推测原因或重跑厂商训练