Ошибка загрузчика данных Pytorch «Рабочий DataLoader (pid xxx) убит сигналом» решение

PyTorch

Это 13-й день моего участия в ноябрьском испытании обновлений.Подробности о событии:Вызов последнего обновления 2021 г.

При использовании загрузчика данных pytorch возникает проблема, связанная с сообщением об ошибке, когда для num_workers не установлено значение 0. В этой статье описаны два решения таких ошибок.

Dataloader - num_workers

  • Модули для загрузки данных в PytorchDataloaderимеет параметрnum_workers, этот параметр указывает на использованиеdataloaderКоличество процессов, которые загружают данные одновременно, можно понимать как количество рабочих, которые несут данные для сети;

  • так что еслиdataloaderЭто сложнее.Когда есть много работников, это, естественно, может сэкономить много времени на загрузку данных.Они могут загружать данные одновременно во время обучения сети и напрямую брать загруженные данные из памяти, когда обучение сети закончено.num_workerКогда оно больше 1, загрузку данных можно ускорить.Когда число настолько велико, что сети не нужно загружать данные, это является предельным преимуществом работников, работающих над ускоренным обучением;

  • Использование рабочих процессов больше 1 потребует больше памяти и процессора, а также займет больше общей памяти (share memory);

  • Использование рабочих процессов больше 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

Решения обеих проблем приведены ниже.

Вопрос 1 RuntimeError: рабочий DataLoader (pid XXX) убит сигналом: ошибка шины

проблема вызывает

  • Как правило, такого рода проблемы возникают в докере, поскольку по умолчанию общая память докера составляет 64 МБ, места не хватает при большом количестве воркеров, и возникает ошибка.

решение

1 Самостоятельно заброшенные боевые искусства
  • будетnum_workersустановить на 0
2 решить проблему
  • существуетсоздать докерПри настройке большей общей памяти добавьте параметры--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
  • где shm - это общая память

Проблема 2 RuntimeError: рабочий процесс DataLoader (pid(s) ****) неожиданно завершился

проблема вызывает

  • так какdataloaderПри использовании многопоточной операции, если в программе есть другие многопоточные операции с некоторыми проблемами, это может привести к тому, что потоки будут переносить потоки, что может привести к взаимоблокировке.
  • Конкретная ситуация может отличаться в зависимости от конкретной среды, моя связана с многопоточностью в opencv иdataloaderЕсть проблема с сочетанием ;
  • На данный момент cv версии 3.4.2, тот же код работает без проблем в cv 4.2.0.34.

решение

1 Самостоятельно заброшенные боевые искусства
  • будетnum_workersустановить на 0
2 решить проблему
  • в загрузчике данных__getitem__Отключить многопоточность opencv в методе:
def __getitem__(self, idx):
	import cv2
	cv2.setNumThreads(0)
	...

использованная литература