一、显存溢出概述

什么是显存溢出(OOM)

显存溢出,英文叫 Out of Memory,简称 OOM。说白了,就是你的 GPU 显存放不下你喂给它的数据了。

我经常跟团队里的新人说,你可以把显存想象成一个仓库。模型参数是货架,中间结果是临时堆放的货物,优化器状态是打包材料。当仓库堆满了,再往里塞东西,自然就爆了。

显存溢出不是突然发生的,它有一个过程。GPU 会尝试分配新的显存块,发现不够用,然后尝试回收一些缓存,实在不行了,就抛出 OOM 错误。嗯,这个过程其实很快,快到你可能还没反应过来,训练就崩了。

核心要点:显存溢出 = 请求分配的显存量 > 当前可用显存量

OOM 的常见表现与报错信息

不同框架报错的方式不太一样,但本质都是一回事。我整理了几种最常见的报错形式:

框架/场景 典型报错信息 说明
PyTorch CUDA out of memory. Tried to allocate ... 最常见,会告诉你尝试分配了多少显存
TensorFlow ResourceExhaustedError: OOM when allocating tensor 会显示当前显存使用情况
深度学习框架通用 RuntimeError: CUDA error: out of memory 底层 CUDA 驱动报错
系统级别 Process killed (OOM) 进程直接被系统杀掉,没有详细日志

我遇到过最坑的一次,是系统级别的 OOM。训练跑了大半天,突然进程没了,连个错误日志都没留下。后来排查才发现,是显存慢慢泄漏,最后系统直接 kill 了进程。这种问题最难定位。

避坑指南:我曾经在调试一个 70B 模型时,发现 OOM 报错里显示的「已分配显存」只有 20GB,但我的卡有 80GB。别被这个数字骗了!它只代表当前这次分配失败时的信息,不代表你的显存真的只用了 20GB。实际上,碎片化和缓存占用可能已经吃掉了大部分显存。

OOM 对训练/推理的影响

显存溢出带来的影响,比你想象的要严重得多。我把它分成三个层面:

训练场景

  • 训练中断:最直接的影响。跑了几天的训练,啪一下没了。我之前有个项目,训练到第 3 天 OOM 了,检查点还没保存,心态直接崩了。
  • batch size 被迫缩小:为了不 OOM,只能把 batch size 调小。但 batch size 太小,梯度噪声大,模型收敛变慢,训练质量下降。
  • 模型规模受限:你想试试更大的模型?显存不够,想都别想。我见过不少团队,明明算法设计好了,就因为显存放不下,只能砍模型层数。

推理场景

  • 服务不可用:线上推理服务 OOM 了,用户直接报错。这可不是闹着玩的。
  • 并发量受限:显存决定了你能同时处理多少个请求。显存不够,并发上不去,QPS 就低。
  • 长序列处理失败:处理长文本时,显存占用会暴增。我遇到过推理一个 8K 长度的对话,直接 OOM 了,最后只能截断输入。

我的经验:判断一个模型能不能跑,我习惯先算一笔账。模型参数占多少、优化器状态占多少、激活值占多少、batch size 乘上序列长度再乘上每样本的显存开销。加总后留出 20% 的余量,这才是安全的显存预算。

知识体系总览

下面这张图,是我梳理的显存溢出排查与优化的整体框架。你可以把它当作一张地图,后续的章节都会围绕这些方向展开。

显存溢出(OOM)排查与优化 诊断:如何定位 OOM 显存监控工具 报错信息分析 碎片化检测 优化:如何减少显存 梯度检查点 混合精度训练 显存复用 策略:分布式与调度 模型并行 流水线并行 显存调度 目标:在不影响训练效果的前提下,最大化显存利用率

这张图里,我把 OOM 的排查与优化分成了三大块:诊断、优化、策略。诊断是第一步,你得先搞清楚显存到底用在哪了;优化是具体手段,怎么省着用;策略是更高维度的思考,怎么通过分布式和调度来突破单卡限制。

后面的章节,我会逐一展开这些内容。你想想看,如果能把这套体系吃透,以后遇到 OOM 就不会慌了。

一句话总结:显存溢出不是 bug,是资源管理问题。理解了它,你就能更好地驾驭大模型训练和推理。

可可精品资料库