在使用 pytorch dataloader 时,出现了当把num_workers 设置不为0即报错的问题,本文记录两种此类错误的解决方案。
Dataloader
有个参数num_workers
,该参数表示使用dataloader
时加载数据的进程数量,可以理解为为网络搬运数据的工人数量;dataloader
比较复杂,工人多的时候自然可以节省大量数据加载时间,他们可以在网络训练时同时进行数据加载工作,等网络训练结束直接从内存中取走加载完成的数据,因此当num_worker
大于1时可以对数据加载进行加速,当数量多到网络不需要加载数据的时间时就是工人们为加速训练做工作的极限收益了;根据
num_worker
的工作思路,可能会在工作中出现两种错误(我遇到的两种):
RuntimeError: DataLoader worker (pid XXX) is killed by signal: Bus error
ERROR: Unexpected segmentation fault encountered in worker.
或
RuntimeError: DataLoader worker (pid 4499) is killed by signal: Segmentation fault.
或
RuntimeError: DataLoader worker (pid(s) ****) exited unexpectedly
下面给出两种问题的解决方案。
num_workers
设置为0--shm-size="15g"
,设置15g(根据实际情况酌量设置)的共享内存:nvidia-docker run -it --name [container_name] --shm-size="15g" ...
df -h
查看# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 3.6T 3.1T 317G 91% /
tmpfs 64M 0 64M 0% /dev
tmpfs 63G 0 63G 0% /sys/fs/cgroup
/dev/sdb1 3.6T 3.1T 317G 91% /workspace/tmp
shm 15G 8.1G 7.0G 54% /dev/shm
tmpfs 63G 12K 63G 1% /proc/driver/nvidia
/dev/sda1 219G 170G 39G 82% /usr/bin/nvidia-smi
udev 63G 0 63G 0% /dev/nvidia3
tmpfs 63G 0 63G 0% /proc/acpi
tmpfs 63G 0 63G 0% /proc/scsi
tmpfs 63G 0 63G 0% /sys/firmware
dataloader
使用了多线程操作,如果程序中存在其他有些问题的多线程操作时就有可能导致线程套线程,容易出现死锁的情况dataloader
的杂糅出现了问题;num_workers
设置为0__getitem__
方法中禁用opencv的多线程:def __getitem__(self, idx):
import cv2
cv2.setNumThreads(0)
...