pytorch报错:RuntimeError: CUDA out of memory.(CUDA内存不足)

本文详细介绍如何使用nvidia-smi命令实时监控GPU占用情况,解决GPU显存不足及内存泄漏问题,包括调整模型参数、清理缓存、手动释放进程等方法,并提供僵尸进程处理流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查看GPU的运行状况
  • 程序运行中可以通过watch -n 0.1 -d nvidia-smi命令来实时查看GPU占用情况,按Ctrl+c退出
  • 通过nvidia-smi命令来查看某一时刻的GPU的占用情况
    在这里插入图片描述
1、训练阶段

如果是训练时遇到该问题,说明模型的参数太多了,将模型的参数减少该问题就解决了,改小batch_size是不能解决的(我将batch_size设为1都没解决,而且报错时的内存数据都没变),因此,出现这个问题,应该有三个原因:

  • GPU还有其他进程占用显存,导致本进程无法分配到足够的显存
  • 缓存过多,使用torch.cuda.empty_cache()清理缓存(没试过)
  • 卡不行,换块显存更大的卡吧(因为服务器上有4个显卡,所以,选择了序号为3的显卡进行实验)
2、测试阶段

如果是测试时遇到该问题,在测试代码前面加上:with torch.no_grad():

with torch.no_grad():
  # test process
3、GPU显存未释放问题

若使用了上述两种方法还不成功,那么我们就需要手动释放那些已经不需要的进程(这些进程占据着GPU的资源)
我们在使用tensorflow+pycharm 或者PyTorch写程序的时候, 有时候会在控制台终止掉正在运行的程序,但是有时候程序已经结束了,nvidia-smi也看到没有程序了,但是GPU的内存并没有释放,这是怎么回事呢?
使用PyTorch设置多线程(threads)进行数据读取(DataLoader),其实是假的多线程,他是开了N个子进程(PID都连着)进行模拟多线程工作,所以你的程序跑完或者中途kill掉主进程的话,子进程的GPU显存并不会被释放,需要手动一个一个kill才行,具体方法描述如下:

  • 1.先关闭ssh(或者shell)窗口,退出重新登录
  • 2.查看运行在gpu上的所有程序:
fuser -v /dev/nvidia*
  • 3.kill掉所有(连号的)僵尸进程

具体操作步骤如下:

  • 我们可以用如下命令查看 nvidia-smi看不到的GPU进程。
nvidia-smi   

发现内存泄露问题,即没有进程时,内存被占用
在这里插入图片描述

  • 发现僵尸进程(连号的)
fuser -v /dev/nvidia*   

在这里插入图片描述

  • 查看具体这个进程调用GPU的情况
pmap -d PID
  • 强行关掉所有当前并未执行的僵尸进程
kill -9 PID

参考1:https://blog.csdn.net/weixin_38314865/article/details/105998844
参考2:https://www.jianshu.com/p/0d8ea6ca332a

### 解决 CUDA Out of Memory 的方法 当遇到 `RuntimeError: CUDA out of memory` 错误时,通常是因为 GPU 显存不足以支持当前模型或数据的计算需求。以下是几种常见的解决方案: #### 1. 减少批量大小(Batch Size) 较大的批量大小会占用更多的显存资源。可以通过降低批量大小来减少显存消耗[^1]。 ```python batch_size = 32 # 原始值可能为64或其他较大数值 dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True) ``` #### 2. 使用梯度累积(Gradient Accumulation) 如果减小批量大小会影响训练效果,可以采用梯度累积技术,在多个较小批次上累计梯度后再更新参数。 ```python accumulation_steps = 4 # 梯度累积步数 optimizer.zero_grad() for i, data in enumerate(dataloader): inputs, labels = data outputs = model(inputs) loss = criterion(outputs, labels) loss = loss / accumulation_steps loss.backward() if (i + 1) % accumulation_steps == 0: optimizer.step() optimizer.zero_grad() ``` #### 3. 清理未使用的张量变量 在某些情况下,PyTorch 中可能存在悬空的张量对象占据显存空间。通过手动清理这些对象并调用垃圾回收机制可以帮助释放部分显存。 ```python import torch import gc del variable_name # 删除不再需要的张量变量 torch.cuda.empty_cache() # 手动清空缓存 gc.collect() # 调用Python的垃圾收集器 ``` #### 4. 设置环境变量优化显存分配策略 调整 PyTorch显存管理配置能够有效缓解碎片化问题。例如设置 `PYTORCH_CUDA_ALLOC_CONF` 来控制最大分割尺寸。 ```bash export PYTORCH_CUDA_ALLOC_CONF="max_split_size_mb:128" ``` 或者直接在 Python 程序中实现: ```python import os os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'max_split_size_mb:128' ``` #### 5. 启用混合精度训练(Mixed Precision Training) 利用 NVIDIA 提供的 Apex 或者原生 PyTorch 功能启用 FP16 训练模式,从而显著降低显存使用率。 ```python from torch.cuda.amp import GradScaler, autocast scaler = GradScaler() for data, target in dataloader: with autocast(): output = model(data) loss = criterion(output, target) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update() ``` 以上方法单独或组合应用均能有效地应对因显存不足引发的各种错误情况。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还能坚持

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值