OOM 报错是什么
PyTorch 的显存不足报错(torch.cuda 的 OutOfMemoryError)本身就是一份账单:这次申请多大、卡总容量多少、当前空闲多少、已分配与已保留各多少。分清 allocated(当前活跃张量占用)与 reserved(分配器向驱动保留的总量,含空闲缓存块),才能判断是容量真不够,还是碎片导致申请失败。
基本信息
| 报错来源 | PyTorch CUDA 分配器在申请失败时抛出 |
|---|---|
| 关键字段 | 申请大小、卡容量、空闲、已分配、已保留、已保留但未分配 |
| 两种成因 | 容量不足(真的装不下)与碎片(有空闲块但不连续) |
| 常见场合 | 推理服务并发升高、训练批过大、同卡多进程 |
| 缓解方向 | 降并发或窗口、减小批、关闭多余进程、碎片缓解参数 |
典型使用场景
- 推理服务偶发崩溃:结合报错与并发曲线,判断是流量峰值还是容量长期偏紧
- 训练或微调调批:先看账单再决定减批还是减序列长度
- 评估是否加卡:先确认是容量因素而非碎片,否则加卡后仍会复发
- 上线前显存估算:用报错里的字段反推实际占用与预留是否合理
- 多进程排障:卡上还有别的任务时,OOM 未必是当前服务造成的
报错文本结构(示意)
报错文本结构(示意)
CUDA out of memory. Tried to allocate 2.34 GiB.
GPU 0 has a total capacity of 79.65 GiB of which 1.98 GiB is free.
77.50 GiB is allocated ... 77.56 GiB is reserved ...
64.00 MiB is reserved by PyTorch but unallocated
读法:申请 2.34 GiB 但只剩 1.98 GiB 可用 → 容量不够
若「已保留但未分配」很大而仍申请失败 → 碎片信号碎片缓解(先在预发验证)
碎片缓解(先在预发验证)
# 尝试让分配器使用可扩展段,降低碎片导致的大块申请失败
# 兼容性随 CUDA 与框架版本而异,确认本环境支持后再用于生产
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
# 先看卡上还有谁在占显存,再判断要不要动参数
nvidia-smi --query-compute-apps=pid,used_memory --format=csv报错字段读法
| 字段 | 含义 | 怎么用 |
|---|---|---|
| allocated | 当前活跃张量占用 | 与模型规模对比,判断是否异常 |
| reserved | 分配器向驱动保留的总量(含缓存块) | 与卡容量对比看真实占用 |
| free | 驱动层面仍可分配的量 | 申请失败时通常已接近 0 |
| reserved 但未分配 | 空闲缓存块 | 数值大仍申请失败即碎片信号 |
碎片缓解参数不是万能开关:其兼容性随 CUDA 与框架版本变化,先在预发环境验证,确认稳定后再用于生产服务。
推理服务的 OOM 多来自并发与上下文长度的组合,而不是模型本身:先调小并发或窗口验证一轮,再考虑加卡或改并行度。