1. 显存溢出(OOM)全景认知

什么是显存溢出?

显存溢出,英文叫 Out of Memory,简称 OOM。

说白了,就是你的 GPU 显存放不下了。

你想想看,一张 A100 有 80GB 显存,听起来挺大对吧?但我在实际项目中见过,一个 13B 参数的模型,光参数就要占 26GB,加上梯度、优化器状态、中间激活值,80GB 瞬间就爆了。

显存溢出不是突然发生的。它有个过程:

  • 模型加载阶段:参数塞不进显存
  • 前向传播阶段:中间激活值撑爆显存
  • 反向传播阶段:梯度累积导致溢出
  • 推理阶段:KV Cache 把显存吃光

核心认知:显存溢出不是 bug,是资源管理问题。就像你搬家,东西太多箱子太小,得想办法重新打包。

OOM 的典型表现

我遇到过很多次 OOM,每次的表现都不太一样。这里总结几个最常见的:

表现类型 具体现象 我踩过的坑
直接报错 CUDA out of memory. Tried to allocate ... 有一次训练跑了 3 小时,突然报错,白跑了
训练中断 loss 突然变成 NaN,然后进程被 kill 其实是显存不够,系统自动杀了进程
推理变慢 生成速度越来越慢,最后卡死 KV Cache 慢慢撑爆,不是瞬间爆的
多卡训练异常 某张卡显存占用特别高,其他卡正常 数据并行时,有一张卡负责的 batch 特别大

注意:OOM 不总是报 "out of memory"。有时候它表现为进程被 kill,或者训练 loss 突然发散。我见过有人排查了三天,最后发现是显存不够导致的。

OOM 对训练推理的影响

影响有多大?我直接说几个真实案例:

  • 训练方面:一次 OOM 可能导致几小时甚至几天的训练白费。我有个同事,训练一个 70B 模型,跑了 5 天,第 6 天 OOM 了,所有 checkpoint 都没保存。
  • 推理方面:线上服务 OOM 会导致服务不可用。我经历过一次,用户量突然上涨,显存不够,整个推理集群挂了 20 分钟。
  • 成本方面:GPU 很贵。A100 一小时几十块,OOM 一次浪费的钱够吃顿好的了。

我的经验:OOM 不只是技术问题,更是成本问题。你想想看,一个 8 卡 A100 的集群,每小时成本几百块。OOM 一次,几千块就没了。

为什么需要系统学习 OOM 分析?

这个问题我问过很多人。大部分人的回答是:报错了就调小 batch size 呗。

嗯,这确实能解决问题。但治标不治本。

我总结了几点必须系统学习的原因:

  1. OOM 的原因很多:不只是 batch size 的问题。模型结构、优化器选择、数据加载方式,都可能引发 OOM。
  2. 盲目调参效率低:我曾经为了调一个 OOM,试了十几种 batch size,最后发现是梯度检查点没开。
  3. 影响模型质量:为了省显存,有些人把精度从 fp16 降到 int8,结果模型效果掉了 5 个点。
  4. 分布式训练更复杂:单卡 OOM 好解决,多卡 OOM 就麻烦了。哪张卡爆了?为什么爆?这些都需要系统分析。

一句话总结:系统学习 OOM 分析,不是为了解决一次报错,而是为了让你在 GPU 资源有限的情况下,把每一 MB 显存都用在刀刃上。

本章知识体系

下面这张图,是我自己整理的 OOM 分析知识体系。你可以把它当成一张地图,后续章节都会围绕这些展开。

显存溢出(OOM)全景 OOM 原因分析 OOM 诊断方法 OOM 解决方案 模型参数占用 梯度 & 优化器状态 中间激活值 KV Cache 数据加载 & 预处理 nvidia-smi 监控 PyTorch Profiler 显存快照分析 梯度累积检测 内存碎片分析 梯度检查点 混合精度训练 模型并行 ZeRO 优化 显存碎片整理 目标:每 MB 显存都用在刀刃上

这张图展示了 OOM 分析的三个核心方向:原因分析、诊断方法、解决方案。后续章节会逐一深入。

我的建议:学 OOM 分析,不要只盯着报错信息。要理解显存是怎么分配的,哪些环节最吃显存,这样才能从根本上解决问题。

好了,第一章就到这里。记住一句话:OOM 不可怕,可怕的是不知道怎么分析它。

可可精品资料库