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 相关文章推荐
详解Python的Django框架中的中间件
Jul 24 Python
实例讲解Python中global语句下全局变量的值的修改
Jun 16 Python
Python正则简单实例分析
Mar 21 Python
Python获取当前公网ip并自动断开宽带连接实例代码
Jan 12 Python
python实现趣味图片字符化
Apr 30 Python
Python实现的文轩网爬虫完整示例
May 16 Python
django 捕获异常和日志系统过程详解
Jul 18 Python
解决python flask中config配置管理的问题
Jul 26 Python
python利用openpyxl拆分多个工作表的工作簿的方法
Sep 27 Python
sklearn-SVC实现与类参数详解
Dec 10 Python
Python3 元组tuple入门基础
Feb 09 Python
Python是什么 Python的用处
May 26 Python
python flask开发的简单基金查询工具
python爬取网页版QQ空间,生成各类图表
Python爬虫实战之爬取携程评论
Pytorch DataLoader shuffle验证方式
python 爬取吉首大学网站成绩单
python 批量压缩图片的脚本
Jun 02 #Python
python操作xlsx格式文件并读取
You might like
学习使用PHP数组
2006/10/09 PHP
利用phpExcel实现Excel数据的导入导出(全步骤详细解析)
2013/11/26 PHP
CodeIgniter实现更改view文件夹路径的方法
2014/07/04 PHP
ThinkPHP模版中导入CSS和JS文件的方法
2014/11/29 PHP
Codeigniter框架实现获取分页数据和总条数的方法
2014/12/05 PHP
WordPress网站性能优化指南
2015/11/18 PHP
科讯商业版中用到的ajax空间与分页函数
2007/09/02 Javascript
jquery 打开窗口返回值实现代码
2010/03/04 Javascript
js实现网站首页图片滚动显示
2013/02/04 Javascript
防止浏览器记住用户名及密码的简单实用方法
2013/04/22 Javascript
jQuery实现仿腾讯视频列表分页效果的方法
2015/08/07 Javascript
Node.js中使用socket创建私聊和公聊聊天室
2015/11/19 Javascript
javascript实现tab响应式切换特效
2016/01/29 Javascript
JavaScript知识点总结(四)之逻辑OR运算符详解
2016/05/31 Javascript
Three.js学习之正交投影照相机
2016/08/01 Javascript
如何正确理解javascript的模块化
2017/03/02 Javascript
angular4中关于表单的校验示例
2017/10/16 Javascript
利用npm 安装删除模块的方法
2018/05/15 Javascript
Vue axios设置访问基础路径方法
2018/09/19 Javascript
从源码里了解vue中的nextTick的使用
2018/11/22 Javascript
vue柱状进度条图像的完美实现方案
2019/08/26 Javascript
Vue的click事件防抖和节流处理详解
2019/11/13 Javascript
JS变量提升原理与用法实例浅析
2020/05/22 Javascript
JS实现购物车基本功能
2020/11/08 Javascript
python中黄金分割法实现方法
2015/05/06 Python
python实现将html表格转换成CSV文件的方法
2015/06/28 Python
python中的set实现不重复的排序原理
2018/01/24 Python
使用wxpy实现自动发送微信消息功能
2020/02/28 Python
python实现logistic分类算法代码
2020/02/28 Python
keras的load_model实现加载含有参数的自定义模型
2020/06/22 Python
PyCharm+PyQt5+QtDesigner配置详解
2020/08/12 Python
Skyscanner香港:机票比价, 平机票和廉价航空机票预订
2020/02/07 全球购物
我们没有写servlet的构造方法,那么容器是怎么创建servlet的实例呢
2013/04/24 面试题
反邪教宣传工作方案
2014/05/07 职场文书
导游词之黄果树瀑布
2019/09/20 职场文书
python爬虫selenium模块详解
2021/03/30 Python