pytorch 运行一段时间后出现GPU OOM的问题


Posted in Python onJune 02, 2021

pytorch的dataloader会将数据传到GPU上,这个过程GPU的mem占用会逐渐增加,为了避免GPUmen被无用的数据占用,可以在每个step后用del删除一些变量,也可以使用torch.cuda.empty_cache()释放显存:

del targets, input_k, input_mask
torch.cuda.empty_cache()

这时能观察到GPU的显存一直在动态变化。

但是上述方式不是一个根本的解决方案,因为他受到峰值的影响很大。比如某个batch的数据量明显大于其他batch,可能模型处理该batch时显存会不够用,这也会导致OOM,虽然其他的batch都能顺利执行。

显存的占用跟这几个因素相关:

模型参数量

batch size

一个batch的数据 size

通常我们不希望改变模型参数量,所以只能通过动态调整batch-size,使得一个batch的数据 size不会导致显存OOM:

ilen = int(sorted_data[start][1]['input'][0]['shape'][0])
olen = int(sorted_data[start][1]['output'][0]['shape'][0])
# if ilen = 1000 and max_length_in = 800
# then b = batchsize / 2
# and max(1, .) avoids batchsize = 0
# 太长的句子会被动态改变bsz,单独成一个batch,否则padding的部分就太多了,数据量太大,OOM
factor = max(int(ilen / max_length_in), int(olen / max_length_out))
b = max(1, int(batch_size / (1 + factor)))
#b = batch_size
end = min(len(sorted_data), start + b)
minibatch.append(sorted_data[start:end])
if end == len(sorted_data):
    break
start = end

此外,如何选择一个合适的batchsize也是个很重要的问题,我们可以先对所有数据按照大小(长短)排好序(降序),不进行shuffle,按照64,32,16依次尝试bsz,如果模型在执行第一个batch的时候没出现OOM,那么以后一定也不会出现OOM(因为降序排列了数据,所以前面的batch的数据size最大)。

还有以下问题

pytorch increasing cuda memory OOM 问题

改了点model 的计算方式,然后就 OOM 了,调小了 batch_size,然后发现发现是模型每次迭代都会动态增长 CUDA MEMORY, 在排除了 python code 中的潜在内存溢出问题之后,基本可以把问题定在 pytorch 的图计算问题上了,说明每次迭代都重新生成了一张计算图,然后都保存着在,就 OOM 了。

参考

CUDA memory continuously increases when net(images) called in every iteration

Understanding graphs and state

说是会生成多个计算图:

loss = SomeLossFunction(out) + SomeLossFunction(out)

准备用 sum来避免多次生成计算图的问题:

loss = Variable(torch.sum(torch.cat([loss1, loss2], 0)))

然而,调着调着就好了,和报错前的 code 没太大差别。估计的原因是在pycharm 远程连接服务器的时候 code 的保存版本差异问题,这个也需要解决一下。

还有个多次迭代再计算梯度的问题,类似于 caffe中的iter_size,这个再仔细看看。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
如何准确判断请求是搜索引擎爬虫(蜘蛛)发出的请求
Oct 13 Python
使用python中的in ,not in来检查元素是不是在列表中的方法
Jul 06 Python
Python拼接微信好友头像大图的实现方法
Aug 01 Python
Python list列表中删除多个重复元素操作示例
Feb 27 Python
python爬虫 execjs安装配置及使用
Jul 30 Python
Django中间件拦截未登录url实例详解
Sep 03 Python
tensorflow:指定gpu 限制使用量百分比,设置最小使用量的实现
Feb 06 Python
记录模型训练时loss值的变化情况
Jun 16 Python
Python调用飞书发送消息的示例
Nov 10 Python
基于python的matplotlib制作双Y轴图
Apr 20 Python
Python游戏开发实例之graphics实现AI五子棋
Nov 01 Python
Django基础CBV装饰器和中间件
Mar 22 Python
python flask开发的简单基金查询工具
python爬取网页版QQ空间,生成各类图表
Python爬虫实战之爬取携程评论
Pytorch DataLoader shuffle验证方式
python 爬取吉首大学网站成绩单
python 批量压缩图片的脚本
Jun 02 #Python
python操作xlsx格式文件并读取
You might like
谈一谈收音机的高放电路
2021/03/02 无线电
php批量删除数据
2007/01/18 PHP
如何用PHP实现插入排序?
2013/04/10 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
php二维数组按某个键值排序的实例讲解
2019/02/15 PHP
Alliance vs AM BO3 第二场2.13
2021/03/10 DOTA
WordPress JQuery处理沙发头像
2009/06/22 Javascript
javascript与asp.net(c#)互相调用方法
2009/12/13 Javascript
javascript 处理null及null值示例
2014/06/09 Javascript
checkbox勾选判断代码分析
2014/06/11 Javascript
JavaScript实现模仿桌面窗口的方法
2015/07/18 Javascript
jquery实现左右滑动菜单效果代码
2015/08/27 Javascript
浅谈jQuery为哪般去掉了浏览器检测
2016/08/29 Javascript
浅谈js函数的多种定义方法与区别
2016/11/29 Javascript
AngularJS指令与控制器之间的交互功能示例
2016/12/14 Javascript
js数组去重的hash方法
2016/12/22 Javascript
JS实现根据密码长度显示安全条功能
2017/03/08 Javascript
webpack构建换肤功能的思路详解
2017/11/27 Javascript
Angular2 自定义表单验证器的实现方法
2018/12/14 Javascript
微信小程序登录数据解密及状态维持实例详解
2019/05/06 Javascript
angular异步验证防抖踩坑实录
2019/12/01 Javascript
python批量替换页眉页脚实例代码
2018/01/22 Python
Python-OpenCV基本操作方法详解
2018/04/02 Python
Python使用装饰器模拟用户登陆验证功能示例
2018/08/24 Python
对Python subprocess.Popen子进程管道阻塞详解
2018/10/29 Python
利用python在excel里面直接使用sql函数的方法
2019/02/08 Python
pyqt5 获取显示器的分辨率的方法
2019/06/18 Python
美国椅子和沙发制造商:La-Z-Boy
2020/10/25 全球购物
暑期社会实践感言
2014/02/25 职场文书
公务员培的训心得体会
2014/09/01 职场文书
意外伤害赔偿协议书范文
2014/09/23 职场文书
优秀教师个人材料
2014/12/15 职场文书
学术会议通知范文
2015/04/15 职场文书
python实战之一步一步教你绘制小猪佩奇
2021/04/22 Python
go设置多个GOPATH的方式
2021/05/05 Golang
MYSQL 表的全面总结
2021/11/11 MySQL