跑大模型 OOM 排查全记录:从报错到解决

王老师728 阅读

跑大模型最烦的就是 OOM。报错信息看起来一样,实际原因可能完全不同。这篇按我遇到的类型,逐个记录排查过程。

类型一:CUDA out of memory(显存爆)

报错:RuntimeError: CUDA out of memory. Tried to allocate ... MiB

排查步骤:

Bash
nvidia-smi # 看谁占着显存
  • 如果是别的进程占着:kill 或者换卡
  • 如果是自己的模型加载就爆:模型太大,量化或换小模型
  • 如果是跑了一会儿才爆:上下文在增长,KV cache 占显存随对话轮数线性增长,长对话迟早爆。解法:限制上下文长度、定期清空历史。

类型二:CPU 内存爆

报错一般是 MemoryError 或者直接被杀(OOM Killer,看 dmesg)。

原因通常是:一次加载太多内容进内存、或者 embed 整个文档集(向量化时把全部文本堆内存)。解法:分批处理、控制 batch size、用 mmap 或流式读取。

类型三:显存泄漏(跑了几天才爆)

这个最阴。报错:CUDA out of memory,但刚启动时好好的。

排查:torch 缓存。PyTorch 默认会缓存显存不释放,长时间运行后碎片化严重。在关键循环里加:

Python
torch.cuda.empty_cache()

但这不是根治,真正要查的是:有没有累积未释放的中间变量、DataLoader 有没有泄漏、循环里有没有不断创建新张量。

类型四:多进程显存翻倍

用了多进程(比如 DataLoader num_workers>0),每个 worker 都可能复制 CUDA context,显存直接翻 N 倍。解法:worker 里不加载模型,或设置 CUDA_VISIBLE_DEVICES 隔离。

类型五:batch 太大

推理时 batch_size 设太大,峰值显存超限。解法:调小 batch、用梯度累计(训练时)。

通用排查思路

  1. 先看 nvidia-smi 和 free -h,确定是显存还是内存
  2. 用代码逐段注释,二分定位是哪段代码导致
  3. 看监控:如果 OOM 有规律(比如每天固定时间),看是不是定时任务或上下文增长

预防:上线前压测,摸清显存/内存峰值,留 20% 余量。

评论0

还没有评论,来抢沙发~