课程导入:显存溢出问题的背景、影响与课程目标

在大模型训练与微调实践中,显存溢出(Out of Memory,OOM)几乎是最常见、也最令人头疼的故障之一。它往往不是模型结构本身的问题,而是参数、梯度、优化器状态、激活值、临时缓冲区等多类显存占用叠加后,超出了单卡或单节点的物理容量。理解 OOM 的成因、定位路径与优化手段,是从“能跑通小模型”走向“稳定训练大模型”的关键一步。

本课程围绕“显存溢出定位与 ZeRO 优化调优”展开,目标不是简单罗列参数,而是建立一套可复用的排查与调优方法:先看清显存被谁占用,再判断是峰值问题还是常驻问题,最后用 ZeRO 等分片策略把显存压力从单卡转移到多卡与 CPU 侧。

一、为什么显存溢出如此普遍

以混合精度训练为例,一个参数量为 P 的模型,其显存占用大致可拆为:

  • 模型参数:FP16/BF16 约 2P 字节,若保留 FP32 主权重则再加 4P 字节;
  • 梯度:通常与参数同精度,约 2P 字节;
  • 优化器状态:Adam 需要一阶矩、二阶矩及 FP32 主权重,约 12P 字节;
  • 激活值:与 batch size、序列长度、层数强相关,常成为峰值显存的主要来源;
  • 临时缓冲区与通信缓冲:all-reduce、all-gather、reduce-scatter 等集合通信会额外占用显存。

当 batch size 增大、序列变长或模型层数加深时,激活值与通信缓冲会迅速膨胀,导致原本“刚好能跑”的配置在某个 step 突然 OOM。更隐蔽的是,OOM 可能发生在反向传播或优化器更新阶段,而不是前向计算时,这让很多初学者误以为是模型太大。

训练显存占用构成与 OOM 触发路径 模型参数 FP16 2P + FP32 4P 梯度 约 2P 字节 优化器状态 Adam 约 12P 字节 激活值 随 batch/seq 增长 临时缓冲区 + 通信缓冲 all-reduce / all-gather / reduce-scatter 单卡显存峰值超过物理容量 触发 CUDA out of memory 优化方向:降低单卡常驻占用 + 削峰 + 分片 梯度累积 · 激活重计算 · 混合精度 · ZeRO-1/2/3 · CPU Offload · 通信重叠

二、OOM 的典型影响与业务代价

显存溢出带来的不只是“程序报错”,它会直接拖慢研发节奏并增加成本:

  • 训练中断:长任务在若干 step 后崩溃,checkpoint 丢失,需要回滚重跑;
  • 规模受限:无法使用更大 batch size 或更长序列,影响收敛速度与效果;
  • 资源浪费:GPU 利用率忽高忽低,集群排队时间变长;
  • 调参困难:工程师被迫反复试错,缺少系统化定位手段。
常见误区:一遇到 OOM 就盲目减小 batch size。实际上,若瓶颈在优化器状态或激活值,减小 batch 可能只缓解一部分;若瓶颈在通信缓冲,甚至可能无效。正确做法是先定位显存构成,再选择对应策略。

三、课程知识框架与学习路径

本课程将按“定位—分析—优化—验证”的闭环展开,整体知识框架如下表所示:

模块 核心问题 关键工具/方法 产出
显存定位 显存被谁占用?峰值出现在哪一步? torch.cuda.memory_summary、NVIDIA Nsight、PyTorch Profiler 显存构成清单与峰值时刻
OOM 归因 是常驻占用过高,还是瞬时峰值过高? 分阶段显存快照、激活值估算、通信缓冲分析 根因判断与优先级
ZeRO 优化 如何把参数、梯度、优化器状态分片? ZeRO-1/2/3、DeepSpeed 配置、FSDP 可运行的分布式配置
调优与验证 分片后吞吐是否下降?通信是否成为瓶颈? Offload、通信重叠、梯度累积、激活重计算 稳定训练与性能平衡

四、一个典型场景:从 OOM 到可训练

假设你在单卡 24GB 上微调一个 7B 模型,使用 Adam 和 FP16,batch size 设为 8,序列长度 1024。训练在第 3 个 step 报错:

RuntimeError: CUDA out of memory. Tried to allocate 2.00 GiB
(GPU 0; 23.65 GiB total capacity; 21.80 GiB already allocated;
1.20 GiB free; 22.10 GiB reserved in total by PyTorch)

此时不要急着改 batch size。可以先打印显存摘要:

print(torch.cuda.memory_summary(device=None, abbreviated=False))

若发现优化器状态和激活值占了大头,可依次尝试:开启梯度检查点、使用 ZeRO-2 分片优化器状态与梯度、必要时启用 CPU Offload。很多情况下,原本 OOM 的配置可以在多卡上稳定跑通,且吞吐损失可控。

学习建议:每学完一个模块,回到自己的训练脚本做一次显存快照,记录“优化前 vs 优化后”的峰值变化。只有把抽象参数与真实日志对应起来,ZeRO 调优才不会变成“背配置”。

本课程后续将围绕显存定位工具、OOM 根因分析、ZeRO 三阶段原理、DeepSpeed/FSDP 实战配置、通信与计算重叠、以及典型故障复盘逐步展开。掌握这套方法后,你将能够面对不同模型规模与硬件条件,快速判断显存瓶颈并给出可落地的优化方案。