pytorch锁死在dataloader(训练时卡死)
作者:Totoro-wen 时间:2023-06-28 02:36:34
1.问题描述
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才会有效。
来源:https://blog.csdn.net/qq_32526087/article/details/106350530
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
详解Python中while无限迭代循环方法
![](https://img.aspxhome.com/file/2023/4/83694_0s.png)
HTML 5 正在改变 Web
![](https://img.aspxhome.com/file/UploadPic/20089/15/20089158232273s.jpg)
PostgreSQL COALESCE使用方法代码解析
关于Dreamweaver乱码问题的解决方案
使用Python自动化破解自定义字体混淆信息的方法实例
Python OpenCV中的resize()函数的使用
![](https://img.aspxhome.com/file/2023/4/93814_0s.png)
Python学习小技巧之列表项的排序
Oracle 管道 解决Exp/Imp大量数据处理问题
sql server中Select count(*)和Count(1)的区别和执行方式
![](https://img.aspxhome.com/file/2023/8/110938_0s.png)
Jebrains付费插件Activation code[持续更新]
Python实现随机生成迷宫并自动寻路
![](https://img.aspxhome.com/file/2023/1/128181_0s.jpg)
javascript自定义函数参数传递为字符串格式
python绘制带有色块的折线图
![](https://img.aspxhome.com/file/2023/8/85228_0s.jpg)
python编程实现希尔排序
![](https://img.aspxhome.com/file/2023/3/102763_0s.jpg)
Python必知必会之os模块实例详解
![](https://img.aspxhome.com/file/2023/6/99046_0s.jpg)
Sublime Text 配置 Python 环境的问题及解决方案
CentOS7下mysql 8.0.16 安装配置方法图文教程
![](https://img.aspxhome.com/file/2023/3/66143_0s.png)
python3中dict(字典)的使用方法示例
Python实战之设计一个多功能办公小工具
![](https://img.aspxhome.com/file/2023/2/109652_0s.png)