Это 13-й день моего участия в ноябрьском испытании обновлений.Подробности о событии:Вызов последнего обновления 2021 г.
При использовании загрузчика данных pytorch возникает проблема, связанная с сообщением об ошибке, когда для num_workers не установлено значение 0. В этой статье описаны два решения таких ошибок.
Dataloader - num_workers
-
Модули для загрузки данных в Pytorch
Dataloader
имеет параметр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)
...