pytorch锁死在dataloader(训练时卡死)


Posted in Python onMay 28, 2021

1.问题描述

pytorch锁死在dataloader(训练时卡死)

2.解决方案

(1)Dataloader里面不用cv2.imread进行读取图片,用cv2.imread还会带来一系列的不方便,比如不能结合torchvision进行数据增强,所以最好用PIL 里面的Image.open来读图片。(并不适用本例)

(2)将DataLoader 里面的参变量num_workers设置为0,但会导致数据的读取很慢,拖慢整个模型的训练。(并不适用本例)

(3)如果用了cv2.imread,不想改代码的,那就加两条语句,来关闭Opencv的多线程:cv2.setNumThreads(0)和cv2.ocl.setUseOpenCL(False)。加了这两条语句之后,并不影响模型的训练。(并不适用本例)

(4)这种情况应该是属于pytorch多线程锁死,在github上看到有该问题,但是没有解决的。

参考建议

首先确保num_works数量低于CPU数量(如果使用Kubernetes,则设置为pod),但是设置得足够高,使数据随时可以用于下一次迭代。

如果GPU在t秒内运行每个迭代,而每个dataloader worker加载/处理单个批处理需要N*t秒,那么您应该将num_workers设置为至少N,以避免GPU停滞。当然,系统中至少要有N个cpu。

不幸的是,如果Dataloader使用任何使用K个线程的库,那么生成的进程数量就会变成num_workersK = NK。这可能比计算机中的cpu数量大得多。这会使pod节流,而Dataloader会变得非常慢。这可能导致Dataloader不返回批处理每t秒,导致GPU暂停。

避免K个线程的一种方法是通过OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 python train.py调用主脚本。这就限制了每个Dataloader工作程序只能使用一个线程,从而避免了使机器不堪重负。你仍然需要有足够的num_workers来满足GPU的需要。

您还应该在_get_item__中优化您的代码,以便每个worker在较短的时间内完成其批处理。请确保worker完成批处理的时间不受从磁盘读取训练数据的时间(特别是当您从网络存储中读取数据时)或网络带宽(当您从网络磁盘读取数据时)的影响。如果您的数据集很小,并且您有足够的RAM,那么可以考虑将数据集移动到RAM(或/tmpfs)中,并从那里读取数据以进行快速访问。对于Kubernetes,您可以创建一个RAM磁盘(在Kubernetes中搜索emptyDir)。

如果你已经优化了你的_get_item__代码,并确保磁盘访问/网络访问不是罪魁祸首,但仍然会出现问题,你将需要请求更多的cpu(为了一个Kubernetes pod),或者将你的GPU移动到拥有更多cpu的机器上。

另一个选项是减少batch_size,这样每个worker要做的工作就会减少,并且可以更快地完成预处理。后一种选择在某些情况下是不可取的,因为会有空闲的GPU内存不被利用。

你也可以考虑离线做一些预处理,减轻每个worker的负担。例如,如果每个worker正在读取一个wav文件并计算音频文件的谱图,那么可以考虑离线预先计算谱图,只从工作者的磁盘中读取计算的谱图。这将减少每个worker的工作量。

你也可以考虑将dataloader里的设置pin_memory=False。

补充:pytorch加载训练数据集dataloader操作耗费时间太久,该如何解决?

笔者在使用pytorch加载训练数据进行模型训练的时候,发现数据加载需要耗费太多时间,该如何缩短数据加载的时间消耗呢?经过查询相关文档,

总结实际操作过程如下:

1、尽量将jpg等格式的文件保存为bmp文件,可以降低解码时间;

2、dataloader函数中增加num_workers参数,该参数表示加载数据的线程数,建议设置为该系统中的CPU核心数,若CPU很强劲,而且内存很大,也可以考虑将该数值设置的更大一些。

train_loader=torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)

修改为:

train_loader=torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True,num_workers=multiprocessing.cpu_count())

虽然使用dataloader达到了iter(Dataset)的读取并行,但是没有实现在GPU运算时异步读取数据,可以考虑使用non_blocking实现。

dataloader = data.Dataloader(dataset, batch_size = batch_size, num_workers = workers)
for epoch in range(epochs):
    for batch_idx, (images, labels) in enumerate(dataloader):
        images = images.to(device)
        labels = labels.to(device)

改为:

dataloader = data.Dataloader(dataset, batch_size = batch_size, num_workers = workers, pin_memory = True)
for epoch in range(epochs):
    for batch_idx, (images, labels) in enumerate(dataloader):
        images = images.to(device, non_blocking=True)
        labels = labels.to(device, non_blocking=True)

需要注意的是:只有pin_memory=True并且num_workers>0时non_blocking才会有效。

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

Python 相关文章推荐
Python中的ConfigParser模块使用详解
May 04 Python
Python环境下安装使用异步任务队列包Celery的基础教程
May 07 Python
python如何查看系统网络流量的信息
Sep 12 Python
Python中的pygal安装和绘制直方图代码分享
Dec 08 Python
python中(str,list,tuple)基础知识汇总
Feb 20 Python
python中不能连接超时的问题及解决方法
Jun 10 Python
Python基于最小二乘法实现曲线拟合示例
Jun 14 Python
tensorflow 获取变量&打印权值的实例讲解
Jun 14 Python
Python2.7环境Flask框架安装简明教程【已测试】
Jul 13 Python
如何利用python制作时间戳转换工具详解
Sep 12 Python
Python自动化测试中yaml文件读取操作
Aug 20 Python
python regex库实例用法总结
Jan 03 Python
Python趣味爬虫之用Python实现智慧校园一键评教
Pytorch 如何加速Dataloader提升数据读取速度
在前女友婚礼上,用Python破解了现场的WIFI还把名称改成了
pytorch DataLoader的num_workers参数与设置大小详解
May 28 #Python
Flask搭建一个API服务器的步骤
May 28 #Python
Python趣味挑战之给幼儿园弟弟生成1000道算术题
May 28 #Python
解决Python中的modf()函数取小数部分不准确问题
May 28 #Python
You might like
php对象在内存中的存在形式分析
2015/02/03 PHP
php如何获取文件的扩展名
2015/10/28 PHP
PHP合并数组的2种方法小结
2016/11/24 PHP
PHP实现的获取文件mimes类型工具类示例
2018/04/08 PHP
Laravel 中创建 Zip 压缩文件并提供下载的实现方法
2019/04/02 PHP
使用javascript实现有效时间的控制,并显示将要过期的时间
2014/01/02 Javascript
js+html5实现可在手机上玩的拼图游戏
2015/07/17 Javascript
简单的jQuery入门指引
2015/07/28 Javascript
浅析jquery数组删除指定元素的方法:grep()
2016/05/19 Javascript
js学习之----深入理解闭包
2016/11/21 Javascript
jQuery插件zTree实现获取当前选中节点在同级节点中序号的方法
2017/03/08 Javascript
JS去掉字符串前后空格、阻止表单提交的实现代码
2017/06/08 Javascript
微信小程序 rich-text的使用方法
2017/08/04 Javascript
angular基于ng-alain定义自己的select组件示例
2018/02/23 Javascript
详解Vue中使用Echarts的两种方式
2018/07/03 Javascript
vue 录制视频并压缩视频文件的方法
2018/07/27 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
Python multiprocessing.Manager介绍和实例(进程间共享数据)
2014/11/21 Python
Django框架中数据的连锁查询和限制返回数据的方法
2015/07/17 Python
python dict 字典 以及 赋值 引用的一些实例(详解)
2017/01/20 Python
利用python将pdf输出为txt的实例讲解
2018/04/23 Python
PyTorch读取Cifar数据集并显示图片的实例讲解
2018/07/27 Python
python读取目录下所有的jpg文件,并显示第一张图片的示例
2019/06/13 Python
Python实现基于SVM的分类器的方法
2019/07/19 Python
python socket通信编程实现文件上传代码实例
2019/12/14 Python
日本一家专门经营各种箱包的大型网站:Traveler Store
2016/08/03 全球购物
波兰数码相机及配件网上商店: Cyfrowe.pl
2017/06/19 全球购物
最好的商品表达自己:Cafepress
2019/09/04 全球购物
乌克兰最大的家用电器和电子产品连锁店:Eldorado
2019/10/02 全球购物
党员培训思想汇报
2014/01/07 职场文书
体育教师自我鉴定
2014/02/12 职场文书
数控技术学生的自我评价
2014/02/15 职场文书
2014年客房部工作总结
2014/11/22 职场文书
环保建议书范文
2015/09/14 职场文书
污染环境建议书
2015/09/14 职场文书
《刺客之王:C罗全景传记》:时代从来不会亏待手艺人
2019/11/28 职场文书