一篇读懂训练显存账单:参数、梯度、优化器状态与激活

训练显存账单:四项构成(手绘信息图)

四项构成:训练显存的金字塔

训练时显存里躺着四类东西,从「必然」到「可控」排列。第一项:参数(权重)。FP16/BF16 下每参数 2 字节——7B 模型 14GB。这是地基,任何训练都躲不掉。第二项:梯度。反向传播为每个参数算一个梯度,FP16 下与参数同大小——再来 14GB。第三项:优化器状态。这是最容易被新手漏算的大头:Adam 优化器为每个参数维护两份状态(一阶动量 + 二阶动量),且混合精度训练里这两份与主权重通常保持 FP32(精度要求)——FP32 动量两份 + FP32 主权重一份 = 每参数 12 字节,7B 模型这一项就是 84GB。第四项:激活值。前向计算中每一层的中间结果都要保留(反向传播要重用),大小 = batch size × 序列长度 × 隐藏维度 × 层数 × 常数——它不随参数量增长,随「batch × 序列长度」增长,是微调场景的显存弹性项。

全量训练显存 ≈ 参数(2B/参数) + 梯度(2B/参数) + 优化器(12B/参数) + 激活(随 batch×seq)
            = 16 B/参数 + 激活
7B 模型:约 112GB + 激活 —— 单卡 80GB 都装不下

这笔账解释了入门者的经典困惑:「7B 模型才 14GB,为什么我的卡装不下训练?」——因为训练显存不是模型文件的大小,是它的四倍以上(全量训练含优化器状态)。

混合精度:账单的第一笔折扣

混合精度训练(本库已有专篇)把这笔账改写:前向与反向用 FP16/BF16(快、省显存),权重更新用 FP32 主副本保精度——优化器状态 12B/参数 里的「FP32 主权重」是混合精度的代价(它就是「主副本」)。省下来的大头在激活(FP16 的激活减半)与计算速度(Tensor Core 对 FP16/BF16 的算力翻倍)。BF16 与 FP16 的选择:BF16 的动态范围大(不用损失缩放,训练更稳),现代 GPU 上是默认。

省显存的四板斧:每一项都有对应招

省激活:梯度检查点(gradient checkpointing)。激活值是微调场景的弹性大头——梯度检查点的思路是「前向时不存全部激活,只存关键节点,反向时重新计算丢失的部分」——用约 30% 的额外计算换掉大部分激活显存(激活显存降数倍)。开启它几乎是无脑推荐(计算换显存的汇率划算),代价是训练时间拉长 20–40%。省优化器状态:LoRA(本库专篇)。冻结基座、只训低秩增量——可训练参数从 100% 降到 0.1% 量级,优化器状态与梯度按可训练参数计——7B 模型 LoRA 微调的账单:基座权重 14GB(只读)+ 0.1% 参数的梯度与优化器(几十 MB)+ 激活——总账从 112GB+ 降到 20GB 级,消费级单卡可跑。省权重与优化器:分片与 offload。ZeRO-3/FSDP 把三项按卡分片(本库分布式篇);CPU offload 把优化器状态挪到内存——「显存不够内存凑」,代价是 PCIe 传输的时间。省 KV 与批:梯度累积(本库专篇)——有效 batch 靠多次累积凑,单次 micro-batch 压小以控激活。

微调与全量训练的两张实账

LoRA 微调 7B(常见入门场景):基座 BF16 14GB(冻结)+ LoRA 参数与优化器 <1GB + 激活(batch 1、seq 2048、开梯度检查点)约 2–4GB ≈ 20GB 上下——24GB 消费卡(4090)可跑,这就是「人人都能微调」的账本依据。全量 SFT 7B:16B/参数 × 7B = 112GB + 激活 ≈ 130GB+——需要多卡(FSDP 分片到 4×80GB 或 2×80GB 紧张配置)。全量预训练 70B:16B/参数 × 70B = 1.12TB + 激活(大 batch 长序列下以 TB 计)≈ 数 TB——必须 TP+PP+DP 的 3D 并行摊到几十上百张卡(本库分布式篇的决策表)。

三笔账的斜率差异就是整个微调产业的存在理由:LoRA 把「参与训练」的门槛从集群级拉到消费卡级——显存账单上每一项的省法,对应一个真实的产业分层(消费卡微调 / 多卡 SFT / 集群预训练)。

诊断思路:OOM 时的排查顺序

显存不足(CUDA OOM)的排查按「哪一项爆了」定位。启动即 OOM(模型还没开始训练)——权重 + 优化器装不下:换 LoRA、上 ZeRO-3/FSDP、或 offload。训练几步后 OOM(越跑越满)——激活爆了(序列特别长的样本触发峰值):减 batch、开梯度检查点、截断长样本。某个长样本突然 OOM——激活的峰值与最长样本相关:设样本长度上限或动态 batch。碎片化 OOM(显存够却分配失败)——长期训练的内存碎片:开 PyTorch 的碎片整理或减小分配粒度。OOM 的排查顺序就是「先看账单哪一项爆了」——显存问题的本质永远是算术问题,把四项账算清,OOM 就从玄学变成算术。

显存账单的实测方法:从理论到 torch 的真实数字

显存账单(正文的四项构成)要落到实测,方法与工具链值得展开。理论估算的校准:公式的估算与实测有差距(框架的显存开销、内核的临时缓冲、碎片化),实测才是真相——实测的工具链三层。第一层:nvidia-smi 的粗粒度监控(每秒看一次显存占用,观察「训练时的稳态水位与峰值」——水位接近 100% 就有 OOM 风险)。第二层:PyTorch 的显存统计(torch.cuda.max_memory_allocated 拿峰值精确值;memory_summary 给出分配/保留/碎片的明细——「保留远大于分配」就是碎片化问题)。第三层:profiler 的逐项分解(torch profiler 或 memory snapshot——把显存占用按张量来源分解,直接看到「哪一步分配了最大的张量」)。实测驱动的优化流程:跑一步前向 + 反向 → 读峰值 → 对照四项账单找「超预期的一项」→ 对症下药(激活大就开检查点、优化器大就上 LoRA/ZeRO、碎片就整理)。两个常见的实测发现:其一,「峰值出现在反向传播的中段」(激活的反向重算与梯度的叠加时刻——检查点能削的就是这个峰);其二,「碎片化让 80GB 的卡只能用 70GB」(长期训练的分配-释放循环造成——环境变量设置分配器策略或定期 torch.cuda.empty_cache 缓解)。显存优化的工作流由此闭环:理论账单定方向 → 实测峰值找矛盾 → 逐项优化 → 回归实测验证——把显存管理变成测量驱动的工程,而不是玄学调参。

显存账单与推理的结合:服务端的显存规划

显存账单(正文)不仅管训练,也管推理服务的规划——服务端的账本结构与训练不同,值得单独列。推理服务端的显存构成:权重(量化后大减,本库量化篇)+ KV Cache(与并发数 × 上下文长度线性相关——服务端的显存大头,本库 KV Cache 篇)+ 引擎开销(框架的调度缓冲)。规划的算式:可支撑并发 ≈ (总显存 − 权重 − 引擎开销) ÷ 单请求 KV(按目标上下文长度算)——例如 80G 卡跑 7B Q4(权重 4G):剩余 70G ÷ 单请求 2G(16K 上下文)≈ 35 并发(理论值,实际打七折)。动态的显存管理:请求的上下文长度不一(有的 1K 有的 100K)——引擎的动态分配(PagedAttention,本库 vLLM 篇)按需给块,但「一个超长请求」仍可能占掉巨量显存(100K 请求的 KV 是 16K 请求的 6 倍)——长度限制与分级服务(长短请求分流)是规划的必要补充。规划的流程:确定目标(并发 × 上下文 × TTFT)→ 按算式初配 → 压测校准(真实流量分布与理论分布的差异)→ 留余量上线(峰值余量 30%)。推理端的显存规划与训练端共享同一套「账单思维」——显存优化的通用方法论:列出构成、算出公式、按目标反推、压测校准——这套方法在训练与推理两侧通用。

显存账单的推理版:单请求与服务端的账本差异

显存账单(正文训练版)的推理版有独立的账本结构,两本账的差异值得对照。训练账:参数 + 梯度 + 优化器 + 激活——优化器是大头(本库正文)。推理账:权重 + KV Cache + 引擎开销——KV Cache 是大头(高并发 × 长上下文时轻松超过权重,本库 KV Cache 篇)。两本账的关键差异:训练的显存是「确定的」(batch 定了就定了),推理的显存是「动态的」(请求的长度与并发实时变化)——推理的显存规划因此更像「容量规划」(按峰值设计、按 P99 校准),训练更像「预算管理」(按配置核算)。两本账的互通:省显存的手段部分互通(量化对两侧都有效——权重量化训练与推理共用、KV 量化推理专用)、部分专属(梯度检查点训练专属、PagedAttention 推理专属)。统一的心法:无论训练还是推理,显存管理的第一步都是「列出构成、按量核算」——账单思维是两个世界的通用语言,把「显存不够」从模糊的恐慌变成清晰的算术。

显存账单的速算卡片:随身携带的算式

显存账单的速算卡片,三行公式随身携带。训练全量:显存 ≈ 16B/参数(FP16 混合精度)+ 激活——7B ≈ 112G+、70B ≈ 1.1T+。LoRA 微调:显存 ≈ 基座量化后大小 + LoRA 参数开销(<1G)+ 激活(检查点后大幅缩水)——7B QLoRA ≈ 10–14G、14B QLoRA ≈ 14–20G。推理:显存 ≈ 权重(参数 × 位宽字节)+ KV(2 × 层数 × 上下文 × KV 头数 × 头维 × 字节 × 并发)——7B Q4 单请求 16K 上下文 ≈ 4G + 1–2G。卡片的使用心法:先估算再实测(理论定方向、实测定真值,本库实测篇);三行公式覆盖九成的「要多少显存」之问——剩下的 10%(MoE、多模态、超长上下文)回到账单四项逐项细算。把这三行公式存进手机备忘录,显存问题从「查半天」变成「心算十秒」。

小结

训练显存四项构成:参数(2B/参数)+ 梯度(2B/参数)+ 优化器状态(12B/参数,最易漏算的大头)+ 激活(随 batch×seq 弹性)——全量训练约 16B/参数加激活。省法对应四板斧:混合精度省激活与提速、梯度检查点用 30% 计算换数倍激活显存、LoRA 把可训练参数降到 0.1%(7B 微调从 130GB 到 20GB)、分片与 offload 摊薄权重与优化器。三笔实账:LoRA 微调 20GB 级(消费卡可跑)、全量 SFT 130GB 级(多卡)、预训练 70B 数 TB(3D 并行)。OOM 排查按「哪项爆了」定位——显存问题永远是算术问题。

← 返回资讯列表

读者留言

COMMENTS 暂无
仅本站原创文章开放留言 · 请勿留下手机号、邮箱等个人信息

还没有留言,来说第一句?