显存不足几乎都会炸出以“CUDA out of memory”为首的一连串报错,本质是显存分配失败或内存交换异常,但报错文案五花八门,迷惑性极强。很多新手盯着错误日志第一行看了半天,其实真正的问题早就写在日志中间甚至末尾,这篇内容把训练时最常撞见的几种报错形态、它们背后的行为模式、以及排查修复的实操顺序一次讲清。
先记住这几类典型报错,别再被换壳文案骗了
显卡显存被打满的那一刻,PyTorch、TensorFlow、深度学习框架通常会抛出以下几种极具代表性的报错,按出现频率排序。
RuntimeError: CUDA out of memory(最经典,占比最高)
这是显存不足的老祖宗报错,几乎是所有炼丹师的入门必修课,完整文案通常长这样:
RuntimeError: CUDA out of memory. Tried to allocate 512.00 MiB (GPU 0; 8.00 GiB total capacity; 7.89 GiB already allocated; 0 bytes free; 7.90 GiB reserved in total by PyTorch)
注意看这行字里的两个数字:“already allocated” 和 “reserved in total by PyTorch”,PyTorch 有自己的显存缓存分配器,tensor 释放后显存不会立刻还给驱动,而是留在缓存池里,already allocated”看着不高,但“reserved in total”通常接近显卡总显存。
行业共识认为:这类报错的直接原因是单次显存分配失败,但根因绝大多数时候不是那 512MiB 的问题,而是之前的显存占用已经把池子填满了。
CUDA error: out of memory(更底层的报错)
去掉 RuntimeError 前缀,直接来自 CUDA 驱动层的报错同样常见,多发生在框架自带缓存策略没接管到的场景,比如调用自定义 CUDA kernel、使用 TensorRT、或者直接操作 cudaMalloc,它的文案比 PyTorch 的更短更直接:
CUDA error: out of memory
如果你看到这一行,紧接着往往还会跟一句 CUDA kernel errors might be asynchronously reported,这句话很坑,它意味着真正的错误可能发生在前几步的某个 kernel 里,只是异步执行到这里才被框架捕捉到,误导性极强。
显存溢出导致进程被直接杀死(没有报错文本)
这种情况最让人血压飙升,训练跑着跑着进度条停住,终端里没出现任何 Python 报错,只有一行冰冷的系统提示:Killed,在 Linux 服务器上跑大规模训练时尤常见,这是操作系统的 OOM Killer 在动手显存不够时,PyTorch 进程会尝试申请内存,OS 一看物理内存和交换分区也快没了,直接杀掉进程了事。
HIP out of memory(AMD 显卡特供版)
用 AMD 显卡跑 ROCm 的用户会比较熟悉,报错格式近乎照搬 CUDA 版,只是把 CUDA 换成了 HIP:
HIP_ERROR_OUT_OF_MEMORY
如果你买不到 N 卡,只能拿 RX 7900 系列顶一顶,这种报错你迟早会认识,好消息是处理思路完全一样。
各种看似毫无关联的派生报错
显存不足还会伪装成其它面相,让新手误以为是模型代码写错了:
std::bad_alloc:C++ 层内存分配失败,通常伴随显存和内存双爆。Segmentation fault (core dumped):段错误,显存爆掉后访问非法地址导致。- NCCL 通信超时或初始化失败:多卡训练时某张卡显存先满,NCCL 的 allreduce 卡死,最后报超时。
显存不够时训练过程有哪些行为特征
报错只是结果,训练卡死之前的过程行为同样值得警惕,能提前发现异常,往往可以省下几小时的排队时间。
GPU 利用率先冲高再骤降为 0
正常训练时 GPU-Util 应该稳定在 80%-100% 区间波动,显存即将打满时,多卡并行训练会频繁等待同步,利用率变成锯齿状,用 nvidia-smi 持续盯控,能看到利用率从 90% 掉到 0%、又瞬间拉回 90%,反复横跳。
训练日志里的 loss 长时间不更新
显存不足不会直接停掉进程,而是触发频繁的显存碎片整理,PyTorch 会试图通过释放缓存块来满足下一次分配需求,这个过程非常耗时,表现为训练步骤卡在某个 step 上,loss 数值几十分钟不刷新,CPU 占用率却拉满。
牺牲精度换显存的隐性报错
有些框架为了缓解显存压力,会自动把精度从 FP32 降到 BF16,甚至在部分算子中启用重计算,但重计算本身要牺牲约 30% 的训练速度,如果代码里没有显式开启却自动触发了,通常是显存逼近极限的信号。
如何定位到底是谁偷走了你的显存
排查显存占用遵循一套固定的实操路径,养成肌肉记忆后,看到报错就能条件反射地找到元凶。
看 GPU 实时状态,别用眼睛估
打开终端,敲下命令:
nvidia-smi
重点关注每个进程的“Used GPU Memory”列,如果已经发现某个 Python 进程占满了全部显存,先把进程 PID 记下来。
更细颗粒度的监测用这个:
watch -n 1 nvidia-smi
每秒刷新一次,能看到显存是逐步爬升还是瞬间打满。
区分“模型本身大”和“数据缓存撑爆”
模型参数量大导致的显存占用和 batch size 过大导致的显存爆掉,处理方式完全不同。
- 模型权重占用:加载预训练模型时就把显存吃了一半,这种情况得换小模型或做模型并行。
- 激活值占用:训练过程中逐步攀升,到某个 step 后才炸,多数是 batch size 或序列长度太长。
- 优化器状态占用:Adam 优化器给每个参数要存两份额外状态,模型 10G,优化器就占 20G。
用 PyTorch 自带的命令行工具能看详细的逐层占用:
python -m torch.utils.bottleneck
用 torch.cuda.memory_summary() 看统计
在训练代码里加一行,就能在报错前打印当前显存快照:
print(torch.cuda.memory_summary(device=None, abbreviated=False))
会列出每个 tensor 占用的显存、缓存分配器的内部状态、以及碎片化程度,重点看“Large Pool”和“Small Pool”两个分类,small pool 里碎块极多,说明显存碎片化严重。
从小到大、从软到硬的应对方案
按成本递增的顺序排列,先动代码再动环境,最后才考虑换硬件。
先把 batch size 调小试水(代价最小)
多数情况下,把 batch size 直接砍半就能解决,比如原来设 32 显存爆炸,改成 16 大概率能跑通,代价是训练步数翻倍,但总时长未必增加太多,因为大 batch 本身不一定线性加速。
调 batch size 的同时,同步调低学习率,参考线性缩放规则。
开启梯度累积:保住大 batch 的等效效果
不想牺牲全局 batch size 时,可以保持微 batch 为 4,梯度累积步数设为 8,等效于原来 32 的 batch size:
accumulation_steps = 8
optimizer.zero_grad()
for i, (inputs, labels) in enumerate(dataloader):
outputs = model(inputs)
loss = criterion(outputs, labels)
loss = loss / accumulation_steps
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
开启混合精度训练:显存直接减半
PyTorch 自带 AMP(自动混合精度)模块,FP16 存储 + FP32 计算,多数显卡的显存占用能下降 40%-50%,用法几行就搞定:
scaler = torch.cuda.amp.GradScaler()
with torch.cuda.amp.autocast():
outputs = model(inputs)
loss = criterion(outputs, labels)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
老显卡需要确认算力在 7.0 以上,否则 FP16 加速效果有限。
开启梯度检查点(重计算技术)
训练阶段不保存全部中间激活值,反向传播时重新计算前向过程,用 torch.utils.checkpoint 包装关键模块:
from torch.utils.checkpoint import checkpoint
def forward(self, x):
return checkpoint(self.transformer_block, x)
内存换取显存,实测能减少 60% 左右的激活值占用,代价是前向计算量增加一次,训练时间延长约 20%-30%。
清空不再需要的变量和缓存
每轮迭代结束后主动释放不再使用的 tensor,并清空 PyTorch 缓存:
del loss, outputs torch.cuda.empty_cache()
这只是解决显存碎片的手段,释放的空间本来就是空闲的,不要指望这一招能逆天改命。
不同场景下的差异化应对
AI绘画显存不足怎么办(Stable Diffusion 用户向)
生成 512×512 图片爆显存和训练模型爆显存是两码事,SD WebUI 用户最常遇到的报错是:
RuntimeError: CUDA out of memory during sampling
通常因为采样器需要维护多份潜空间特征图,优先把分辨率降回 512×512,再把 --medvram 或 --lowvram 启动参数加上,如果你的显卡只有 6GB,建议直接考虑用 --medvram 而不是跟显存硬刚。
大语言模型微调爆显存(LoRA 优先)
本地部署大模型需要多大显存,这个问题没有标准答案,要看量化级别和上下文长度,7B 模型 FP16 加载要 14GB 显存,4-bit 量化后只需约 6GB,微调时如果还用了 LoRA,trainable 参数只占原模型 1% 以下,显存占用大头仍在基础模型的权重上。
实测经验:8GB 显存可以微调 7B 模型的 LoRA,但上下文长度得压到 2048 token 以内;13B 模型建议至少 16GB 才跑得动 LoRA。
多卡训练时单卡显存不够怎么办
多卡情况下,单卡爆显存(其他卡还有余量)通常是数据并行切分不均或负载不均衡,改用 张量并行(Tensor Parallelism) 或 流水线并行(Pipeline Parallelism) 能更均匀地分摊显存压力,如果用的是 HuggingFace 的 Trainer,可以在启动参数里加:
--fsdp --fsdp_auto_wrap_policy TRANSFORMER_BASED_WRAP
PyTorch FSDP 会把模型参数、梯度和优化器状态全部切分到多张卡上。
Windows 用户特有的显存陷阱
Windows 上跑深度学习,有一个坑是 WDDM 显卡驱动模型会预留一部分显存给桌面显示和视频解码,8GB 显卡实际可用可能只有 6.5GB 左右,nvidia-smi 显示的 free 显存永远比物理显存少一截,这是正常的,别跟驱动较劲。
治标不治本的应急手段
这几招只能保证训练勉强能跑,但不推荐长期依赖。
- 调低图像尺寸或序列长度:粗暴但有效,代价是模型效果可能下降。
- 关闭可视化工具:TensorBoard 在浏览器端渲染大量曲线图时,也会占用一两个 GB 的显存。
- 换更小的模型:比如从 ViT-L 换成 ViT-B,这是最彻底的解决方式。
- 升级推理框架:在推理时用 vLLM 替代原生 PyTorch,显存占用能再降几层,但训练场景不适用。
常见问题
显存不足报错和内存不足有什么区别
显存不足报错指向的是 GPU 显卡上的独立存储,内存不足报错指向的是 CPU 侧的系统主内存,两者常常一起爆,因为数据从显存拷贝到内存时,内存也可能被打满,但报错关键词有显著区别:显存不足是 CUDA out of memory,内存不足是 MemoryError 或 std::bad_alloc。
batch size 调到多小才能解决显存不足问题
没有固定数值,取决于模型参数量、输入分辨率、优化器类型等因素,实操中先尝试直接减半,32 变 16,再看 nvidia-smi 中剩余显存的变化,如果减半后剩余显存仍然很少,就需要叠加使用混合精度或梯度累积,单靠调小 batch size 通常无法根治。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/788488.html


![[ComfyUI]跑视频显存不足?8G到底怎么设置才能运行视频生成?保姆级教程](https://i2.hdslb.com/bfs/archive/73b3c3555499a9eac937e0cbd2b1fff1d6d8d2cc.jpg)