本文最后更新于:2024年5月7日 下午
在使用 pytorch dataloader 时,出现了当把num_workers 设置不为0即报错的问题,本文记录两种此类错误的解决方案。
Dataloader - num_workers
-
Pytorch 中加载数据的模块
Dataloader
有个参数num_workers
,该参数表示使用dataloader
时加载数据的进程数量,可以理解为为网络搬运数据的工人数量; -
所以如果
dataloader
比较复杂,工人多的时候自然可以节省大量数据加载时间,他们可以在网络训练时同时进行数据加载工作,等网络训练结束直接从内存中取走加载完成的数据,因此当num_worker
大于1时可以对数据加载进行加速,当数量多到网络不需要加载数据的时间时就是工人们为加速训练做工作的极限收益了; -
使用大于1的工人会占用更多的内存和cpu,同时也会占用更多的共享内存(share memory);
-
使用大于1的工人会调用多线程。
问题说明
根据
num_worker
的工作思路,可能会在工作中出现两种错误(我遇到的两种):
- 共享内存不足:
1 |
|
- 多线程出现段错误导致死锁,进而导致程序卡住,线程阻塞:
1 |
|
或
1 |
|
或
1 |
|
下面给出两种问题的解决方案。
问题1 RuntimeError: DataLoader worker (pid XXX) is killed by signal: Bus error
问题原因
- 一般这种问题发生在docker中,由于docker默认的共享内存为64M,导致工人数量多时空间不够用,发生错误。
解决方案
1 自废武功
- 将
num_workers
设置为0
2 解决问题
- 在创建docker时配置较大的共享内存,加入参数
--shm-size="15g"
,设置15g(根据实际情况酌量设置)的共享内存:
1 |
|
- 通过
df -h
查看
1 |
|
- 其中shm即为共享内存空间
问题2 RuntimeError: DataLoader worker (pid(s) ****) exited unexpectedly
问题原因
- 由于
dataloader
使用了多线程操作,如果程序中存在其他有些问题的多线程操作时就有可能导致线程套线程,容易出现死锁的情况 - 具体的情况可能会根据具体环境不同,我的是由于opencv中的多线程与
dataloader
的杂糅出现了问题; - 此时cv版本 3.4.2,相同的代码在 4.2.0.34 的cv中没有出现问题。
解决方案
1 自废武功
- 将
num_workers
设置为0
2 解决问题
- 在dataloader 的
__getitem__
方法中禁用opencv的多线程:
1 |
|
参考资料
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”
微信支付
支付宝支付
Pytorch dataloader 错误 “DataLoader worker (pid xxx) is killed by signal” 解决方法
https://www.zywvvd.com/notes/study/deep-learning/pytorch/dataloader-segmentation-fault/dataloader-segmentation-fault/