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 呗。
嗯,这确实能解决问题。但治标不治本。
我总结了几点必须系统学习的原因:
- OOM 的原因很多:不只是 batch size 的问题。模型结构、优化器选择、数据加载方式,都可能引发 OOM。
- 盲目调参效率低:我曾经为了调一个 OOM,试了十几种 batch size,最后发现是梯度检查点没开。
- 影响模型质量:为了省显存,有些人把精度从 fp16 降到 int8,结果模型效果掉了 5 个点。
- 分布式训练更复杂:单卡 OOM 好解决,多卡 OOM 就麻烦了。哪张卡爆了?为什么爆?这些都需要系统分析。
一句话总结:系统学习 OOM 分析,不是为了解决一次报错,而是为了让你在 GPU 资源有限的情况下,把每一 MB 显存都用在刀刃上。
本章知识体系
下面这张图,是我自己整理的 OOM 分析知识体系。你可以把它当成一张地图,后续章节都会围绕这些展开。
这张图展示了 OOM 分析的三个核心方向:原因分析、诊断方法、解决方案。后续章节会逐一深入。
我的建议:学 OOM 分析,不要只盯着报错信息。要理解显存是怎么分配的,哪些环节最吃显存,这样才能从根本上解决问题。
好了,第一章就到这里。记住一句话:OOM 不可怕,可怕的是不知道怎么分析它。