从0训练LLM · 现代大模型体系 导读 5 课 + 1 条岔路 + 1 节实验课 ≈ 3.5 小时
C9 精度与显存:一个参数要几字节 章导读

精度与显存:一个参数要几字节

推理时一个参数 2 字节,训练时 16 字节。这一章从这本账出发,每砍一次位宽就在一个真数字上失败一次:FP16 让 10⁻⁸ 变成 0,BF16 让 257 变成 256,FP8 让离群值拖垮整张量,FP4 只剩 16 个码点;再看另一半账——激活,它由序列长度决定,还带 s²。

主线定位

从已有出发 · 训练一步在显存里留下什么(BF16 混合精度) 本课点任一环节看它在 Qwen/Qwen3.8-27B 上占多少

这一章回扣了前面好几处伏笔:C4 岔路课「训练约 278 亿参数的模型要多少显存」、C5 第 2、3 课「m、v 各 4 字节,完整的显存账在 C9」在第 1 课兑现;C4 第 3 课「ε 在低精度下」、C8 第 4、5 课「logit 漂到上千时 BF16 还分得清吗」在第 3 课兑现;C0 第 4 课「不把整张分数表写出来」、C6 第 1 课「开了重计算实际约 8ND」在第 5 课兑现;C3 第 8、10 课「把缓存量化到更低精度」在岔路课有一个真例子。

本章问题链

每一课只回答一个问题;上一课的失败,逼出下一课的问题。

课这一课的问题朴素方案在哪个真数字上失败一句话
第 1 课训练一个参数,要几字节?只算权重:55.6 GB「装得下」;训练一步实际要 444.5 GB训练时一个参数 16 字节:16 位权重、梯度各 2,FP32 主权重与 m、v 各 4
第 2 课全换成 FP16,为什么会丢梯度?fp16(10⁻⁸) = 0;fp16(1 + 10⁻⁴) = 1;fp16(70,000) = inf指数只有 5 位:小梯度下溢、小更新被吞;修法是 FP32 主权重 + loss scaling
第 3 课能不要 loss scaling 吗?FP16 的窗口只有 40 个 2 的幂,缩放只能平移;换 BF16 后 bf16(257) = 256BF16 用尾数换指数,范围同 FP32、不用缩放;精度粗到 1/128,主权重仍要 FP32
第 4 课8 位还能训吗?整张量缩放:[1000, 0.01, 0.02, 0.5] 里 0.01 的误差 12.8%一小块一个缩放(1 × 128 / 128 × 128),块形状跟着离群值走,累加回到 FP32
岔路4 位只剩 16 个数,怎么训?块 [0.3, −1.2, 2.7, 0.05] 用 MX 缩放后 0.05 → 0更小的块 + 各自的缩放;2026 年主要是 MoE 专家权重的 QAT
第 5 课激活为什么比参数还占显存?全存:锚点一条 4,096 token 的序列约 162.5 GiB,注意力分数占 73.8%激活由 s、b、h、L 决定,分数项带 s²;FlashAttention 不写出它,重计算用算力换显存
实验课四种精度在我们的模型上比一比,再把显存账对一遍—只改精度,先预测再看曲线、下溢比例和显存截面

演进地图

精度与显存的演进:每砍一次位宽,都在一个真数字上失败一次
  1. 起点 FP32 全精度 + AdamW 深度学习早期的默认做法
    解决了范围到 ±3.4 × 10³⁸,1 附近的间距 2⁻²³ ≈ 1.2 × 10⁻⁷,数值上几乎不用操心。
    卡在每个参数 4 + 4 + 4 + 4 = 16 字节(权重、梯度、Adam 的 m、v):锚点 27,781,427,952 个参数就是 444.5 GB,是 80 GB 单卡的 5.6 倍,还没算激活。
  2. 第一代 FP16 混合精度:FP32 主权重 + loss scaling Micikevicius et al. 2017
    解决了矩阵乘和激活用 16 位,带宽与激活显存减半;FP32 主权重接住小更新,loss 乘 S 把小梯度推出下溢区,更新前再除回来。
    卡在指数只有 5 位:fp16(10⁻⁸) = 0,fp16(1 + 10⁻⁴) = 1,fp16(70,000) = inf;缩放倍数要一直调,溢出就得跳过这一步。
  3. 第二代 BF16:用尾数换指数 Google Brain 2019 · Kalamkar et al. 2019
    解决了8 位指数,范围与 FP32 相同:不再下溢,不需要 loss scaling。2026 年的默认训练精度。
    卡在1 附近间距粗到 1/128:bf16(257) = 256,bf16(1 + 10⁻³) = 1——主权重和优化器状态仍要 FP32,账本还是 16 字节/参数。
  4. 第三代 FP8 + 细粒度块缩放 Micikevicius et al. 2022(格式)· DeepSeek-V3 2024(超大规模训练)
    解决了激活每 1 × 128、权重每 128 × 128 一个缩放:张量 [1000, 0.01, 0.02, 0.5] 里,0.01 的误差从整张量缩放的 12.8% 降到 0.45%;DeepSeek-V3 相对 BF16 的 loss 相对误差 < 0.25%(官方自报)。
    卡在只有 256 个位型,E4M3 最大 448;块的形状要跟着离群值走——激活梯度改按 128 × 128 块量化,16B MoE 训到约 300B token 发散(附录 B.2);主权重和梯度仍是 FP32。
  5. 岔路 · 2025–2026 4 位:MX / NVFP4 块缩放 + QAT OCP MX 2023 · NVFP4 2025 · Kimi K3 / DeepSeek-V4 2026
    解决了MXFP4 每 32 个数共用一个 2 的幂(4.25 位/参数),NVFP4 每 16 个数一个 E4M3 缩放;K3、DeepSeek-V4 在后训练阶段对 MoE 专家权重做 QAT。
    卡在E2M1 只有 16 个码点:块 [0.3, −1.2, 2.7, 0.05] 用 MX 缩放后,0.05 → 0;全 FP4 预训练仍是前沿。
  6. 另一半账 激活:重计算与 FlashAttention Chen et al. 2016 · Korthikanti et al. 2022 · Dao et al. 2022
    解决了不把 s × s 的注意力分数存下来:锚点一条 4,096 token 的序列,激活从 162.5 GiB 降到 42.5 GiB(选择性重计算 / FlashAttention);全量重计算每层只存输入,只剩 2.5 GiB(标准块公式近似)。
    卡在重计算用多算一遍前向换显存;可 444.5 GB 的模型状态一张 80 GB 卡仍然放不下 → C10 并行。
数字口径:舍入结果在构建时按 IEEE 754 / OCP 规则现算(先存 FP32,再就近舍入、平局取偶);显存由 anchor-model.json 的 param_total 现算,1 GB = 10⁹ 字节;激活按 Korthikanti et al. 2022 式 1(标准块近似,s = 4,096、b = 1);DeepSeek-V3 的数字出自其技术报告 §3.3 与附录 B(本地 PDF,官方自报)。

贯穿任务与例句

贯穿任务:在一张 80 GB 的卡上训练锚点 Qwen3.8-27B 的一步。每一课在同一本账上多记一笔:第 1 课记模型状态,第 2–4 课决定每个数用几位,第 5 课补上激活。

贯穿例句「小明把苹果给了小王」(Qwen3.8 真 tokenizer 切成 5 个 token)是这一步的那一批数据:它的激活只有几十 MB,模型状态已经 444.5 GB;把序列拉到 4,096,激活就反超了参数本身。第 2–4 课讲浮点格式时换成追踪「一个参数 w 和它的一次更新 Δw」,每课开头写明了原因。

全章的账本:先看模型状态(第 5 课再加激活)

三层交互

层本章里的组件在哪一课
概念动画一次迭代的显存时间线(可播放:前向攒激活、反向放激活长梯度、step 分配 m、v);loss scale 把整批梯度沿数轴平移;浮点位条逐位翻转第 5 课、第 2 课、第 2–3 课
算法模拟器(真算法、小数据)FP32 / FP16 / BF16 / FP8 / FP4 手写编解码(与 torch 逐值对照);同一个 w 连加 1,000 次的累加被吞;E4M3 与 E5M2 全部 256 个位型;整张量 vs 1 × 128 vs MX / NVFP4 块缩放的误差热力图;显存账本与 Korthikanti 激活公式(s、b 滑杆)第 1–5 课、岔路
真模型 / 真数据锚点与前沿模型的官方 config(param_total、DeepSeek-V3 与 V4.1 的 quantization_config);我们自己从 0 训练的小模型:四种精度的训练日志、下溢探针的真实梯度直方图、4 个实测显存截面(项目数据生成后显示)第 1、3、4、5 课、岔路与实验课

项目推进:给我们的模型定训练精度,并对上显存账

对应 04-实践项目/MILESTONES.md 的「C9 精度与显存」。分工照旧:代码 AI 来写,决策你来做。项目里 train.precision(fp32 / bf16 / fp16,autocast)、手写的动态 loss scaler(日志含 loss_scale、skipped_steps)、每步恰为 0 的梯度比例、显存分项都已实现,实验脚本 experiments/exp_c9_precision.py 导出本章组件读取的 c09-precision.json。

🧭

你要拍板的三件事

  1. 用 fp32、bf16,还是 fp16 + 动态缩放?理由要同时引用 loss 曲线、跳过步数与下溢比例(第 2、3 课与实验课)。
  2. fp16 为什么需要 loss scaling,bf16 为什么不需要?用下溢探针的直方图回答:落在 2⁻²⁴ 以下的比例、乘 65,536 之后的比例(第 2、3 课)。
  3. 显存账:手算模型状态与激活,与实测分项对账(第 1、5 课)。

验收标准(全部可测):

项目实测 · 验收用的对照表(四种精度)

坑与带走

坑症状后果怎么办
按「参数量 × 2 字节」估训练显存一开训就 OOM低估 8 倍(还没算激活)模型状态 16 字节/参数(第 1 课)
以为混合精度把显存减半换了 BF16 还是放不下模型状态一个字节没省混合精度省的是算力、带宽与激活;要省状态,看 m、v 的格式、优化器与 ZeRO(第 1 课、C10)
用 FP16 训练却不做 loss scalingloss 降得比 FP32 慢;一部分参数几乎不动小梯度下溢成 0用 BF16;或 FP16 + 动态 loss scaling(第 2、3 课)
在 16 位的权重上直接做更新长时间训练后 loss 停滞小更新被舍入吞掉更新落在 FP32 主权重上(第 2、3 课)
FP8 用整张量缩放部分层的量化误差大,甚至发散小值掉进次正规区或变 0细粒度块缩放,块的形状跟着离群值走(第 4 课)
按参数量估激活(旧版组件的错误)拉长序列就 OOM漏掉了与参数量无关、还带 s² 的那部分按 sbh(34 + 5as/h) 估;FlashAttention、重计算(第 5 课)
以为 autocast 把参数也变成了 16 位显存账对不上误判省了多少autocast 只让算子在低精度里算,参数、梯度、优化器状态仍是 FP32(实验课)
拿推理显存估算器估训练预算差好几倍买错卡、配错并行训练 = 模型状态 + 激活 + 临时缓冲,分项算(第 1、5 课)

这一章你应该带走的(各课「一句话」):

深入这一章

每条都实际打开核对过(2026-09-26):写清它讲清了什么、对应哪一课、为什么推荐。外部链接都需要联网;本地 PDF 可离线打开。

🎮 想更直观 10–30 分钟

先玩本章的组件;下面四个是外部最好的动手工具
需联网10 min英文 交互工具
逐位翻转 half、bfloat16、float、double,实时显示数值、相邻可表示值与间距。
对应第 2、3 课:本章 FloatLab 的外部对照,适合拿来核对你自己构造的边界值。它没有 FP8。
需联网10 min英文 Spencer Williams · 2025-10-25
FP8、FP6、FP4、E8M0、MXINT8 等格式互转,可选舍入方式与是否饱和,报告绝对与相对误差。
对应第 4 课与岔路课:8 位、4 位格式的外部核对工具。
需联网10 min英文 v1.1 · 2024-09-28
E4M3FN、E4M3FNUZ、E5M2、E5M2FNUZ 四种 FP8 变体,各自 256 个值排成 16 × 16 表,按零、次正规、NaN、inf 着色。
对应第 4 课:和本章 ValueAxis 的全位型表对照;注意它比本课多列了 FNUZ 两种变体。
需联网20 min英文 Aaron Shi、Zachary DeVito · 2023-12-14
用 PyTorch 的显存快照工具看一个真实训练循环:参数、梯度、优化器状态、激活各自什么时候出现、什么时候释放。
对应第 1、5 课:本章 MemTimeline 是推演,它是真实工具;「第 2 次迭代比第 1 次高」在两边都能看到。

🔬 想吃透原理 1–3 小时

唯一必看:Ultra-Scale Playbook 的显存与混合精度两节。其余按课挑
需联网1–1.5 h英文(有中文译本) 读「Memory usage in transformers」与「Mixed precision training / FP8」两节
从单卡的显存账讲起:16 与 20 字节两种口径、激活公式与选择性重计算、FP16 训练的三个补丁、各格式的位分配表、FP8 的几种方案(含 DeepSeek-V3 的 1 × 128 / 128 × 128 分块)。
一处覆盖第 1–5 课(只缺岔路课的 4 位),而且它接着讲的就是 C10 的并行,可以一路读下去。中文译本 github.com/pprp/ultrascale-playbook-zh 两节都有,有少量机翻错误(如把 E5M2 写成「e5e2」)。原文也有一处笔误:一句「12 bytes in total」与它自己的公式矛盾。
需联网40 min英文 2023-04-18
训练算力 C ≈ 6PD、每参数字节数(2 + 12 + 2 = 16)、激活公式(张量并行版本)、ZeRO 各阶段显存。
对应第 1、5 课,也是 C6、C10 的公式速查。读的时候注意两处表述不准:说 fp16「稳定但难收敛」,又说 Adam 存「三份梯度」——本章第 1 课的账本才是准确的拆法。
需联网30 min英文 2025-07-01
为什么需要缩放因子;delayed scaling 与 current scaling;MXFP8 的 32 元素块;1 × 128 分块;转置时为什么要从高精度重新量化。
对应第 4 课:厂商一手的块缩放说明。有中文机翻版,但把 current scaling 译成了「电流缩放」,建议读英文。
需联网55 min中文 王秀轩 · 2025-03-29 · 官方 YouTube
从「8B 模型训练约要 128 GB」这本账讲起;约 13:30 起讲梯度检查点,约 36:10 起讲 FlashAttention,之后是 ZeRO。
对应第 1、5 课与 C10,中文里把显存优化串成一条线的一堂课。它不讲 loss scaling、BF16、FP8。
需联网约 45 min(只看四段)中英字幕 全长 4:01:27 · 2024-06-10
按原版 YouTube 章节:1:22:18 混合精度、1:28:14 TF32、1:39:38 float16 / grad scaler / bfloat16、2:00:18 FlashAttention——每一步都先跑慢的版本、再看吞吐怎么变。
对应第 2、3、5 课:在真代码里看这些开关的效果。时间点取自 YouTube 原版章节,B 站版时长只差 1 秒,按此推断对齐,未逐帧核对。
需联网13 min中文 2023-06
两种 16 位格式的位布局与计算细节,配 notebook。
对应第 2、3 课。配套 notebook 的数值已核对正确;视频本身没有公开字幕,内容按标题与 notebook 核对。

📄 想读原文 按需

有本地 PDF 的直接打开;其余链 arXiv 或官方页面(需联网)
需联网Micikevicius et al. 2017
FP32 主权重(§3.1)、loss scaling(§3.2)、FP32 累加(§3.3)三个补丁,每一条配「不这样做会怎样」。
第 2 课的出处。注意:它没有实现动态 loss scaling,只建议溢出时跳过更新。
需联网Kalamkar et al. 2019
首个全面的 BF16 实证研究:范围与 FP32 相同,不改超参就达到 FP32 的效果(BF16 为模拟)。
第 3 课的出处;BF16 格式本身出自 Google Cloud 博客(2019-08-23)。
需联网Micikevicius et al. 2022
E4M3 与 E5M2 的定义:E4M3 不表示 inf、只留一个 NaN 位型,最大 448;推荐权重与激活用 E4M3、梯度用 E5M2。
第 4 课的格式出处。它的大模型实验是模拟 FP8(只把矩阵乘输入裁到 FP8 可表示值)。
DeepSeek-AI 2024
§3.3:细粒度量化(1 × 128 / 128 × 128)、N_C = 128 的 FP32 累加提升、全 E4M3、BF16 的 m 与 v;附录 B.1 的 < 0.25% 与 B.2 的发散。
第 4 课的主出处,先读 §3.3 再读附录 B。
需联网OCP 2023-09
32 元素块、E8M0 共享缩放、MXFP8 / MXFP6 / MXFP4 的元素编码。配套论文:Rouhani et al. 2023(arXiv 2310.10537)。
岔路课的出处。官网对脚本访问有防护,浏览器打开正常。
需联网NVIDIA 2025
12B 混合模型、10T token 的 NVFP4 预训练,以及随机 Hadamard、二维块、随机舍入、保留部分 BF16 层这一整套手段。
岔路课「4 位能训,但要一整套补丁」的出处。
Moonshot 2026 · DeepSeek-AI 2026
K3 §4.1.4:MoE 专家权重 MXFP4 + 激活 MXFP8 的后训练 QAT;DeepSeek-V4(/papers/S7-02-DeepSeek-V4.pdf)§5.2.1:FP4 QAT、无损反量化到 FP8、STE。
岔路课 2026 年做法的出处,均为官方自报。
需联网Rajbhandari et al. 2019
§3.1 的 2Ψ + 2Ψ + KΨ(K = 12)与 7.5B → 120 GB;§3.2 GPT-2 1.5B 的激活约 60 GB,大于其 24 GB 的模型状态。
第 1、5 课的出处,也是 C10 第 2 课的主角。
需联网Korthikanti et al. 2022
§4 逐张量推出每层激活 sbh(34 + 5as/h);§5 选择性重计算与序列并行;530B 的 MFU 数字。
第 5 课公式的出处。
需联网Chen et al. 2016
梯度检查点:O(√n) 显存,多一次前向;1,000 层 ResNet 48G → 7G,多约 30% 时间。
第 5 课「改进一」的出处。
Dao et al. 2022
分块、在线 softmax、反向重算;精确注意力,显存随序列长度线性;GPT-2 端到端快 3 倍。
第 5 课「改进三」的出处。
Fedus et al. 2021
§2.4「Selective precision」:纯 bfloat16 训练发散,路由器输入转 FP32 后稳定、速度不变。
第 3 课 Dig「BF16 也不是处处都行」的出处。
🚫

排除了什么(也是筛选标准):① ZOMI 酱 AI System 系列——它的仓库里混合精度、重计算两章写着「这个内容还没有」,搜到的一条低比特量化视频讲的是推理;② 1–3 分钟的速通或面试向短视频(如 BV1NbNi6ZEfK、BV1ZhsJzcEqr、BV1hQh76JEdr)——只给结论,讲不清下溢与缩放;③ 偏推理显存或格式科普的视频(BV1aq7P6LEp6、BV1zPQGBfEHu、BV1SZ42187du)——和训练的精度问题不对口;④ 阿里云开发者社区《大模型训练显存优化实战指南》(旧版课程的侧栏资料)——「80% 的显存来自优化器状态」没有出处,显存饼图是示意比例,与「激活随 s、b 变化」相矛盾;⑤ HF 的模型显存估算器(旧版收录)——旧版页面自己注明它算的是推理加载显存、不含激活,拿来估训练会严重偏低;⑥ NVIDIA FP8 博客的中文机翻版——把 current scaling 译成「电流缩放」。另注:B 站上还有两条播放量低、内容未能核实的精度视频(BV1L8hF6rE61、BV1qhMtz5E21),暂不收。