Перейти к содержанию

Обучение с использованием нескольких GPU с YOLOv5

В этом руководстве объясняется, как правильно использовать несколько графических процессоров для обучения набора данных с помощью YOLOv5 🚀 на одной или нескольких машинах.

Прежде чем начать

Клонируйте репозиторий и установите requirements.txt в окружении Python>=3.8.0, включая PyTorch>=1.8. Модели и наборы данных загружаются автоматически из последнего релиза YOLOv5.

git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install

ProTip!

Docker-образ Рекомендуется для всех Multi-GPU тренировок. Смотрите Краткое руководство по Docker Загрузки Docker

ProTip!

torch.distributed.run заменяет torch.distributed.launch в PyTorch>=1.9. Смотрите Распределенная документация PyTorch для получения подробной информации.

Обучение

Выберите предварительно обученную модель для начала обучения. Здесь мы выбираем YOLOv5s, самую маленькую и быструю доступную модель. См. нашу таблицу в README для полного сравнения всех моделей. Мы будем обучать эту модель с использованием Multi-GPU на наборе данных COCO.

Модели YOLOv5

Один GPU

python train.py --batch 64 --data coco.yaml --weights yolov5s.pt --device 0

Вы можете увеличить device чтобы использовать несколько GPU в режиме DataParallel.

python train.py --batch 64 --data coco.yaml --weights yolov5s.pt --device 0,1

Этот метод медленный и едва ускоряет обучение по сравнению с использованием только 1 GPU.

Вам нужно будет передать python -m torch.distributed.run --nproc_per_node, за которым следуют обычные аргументы.

python -m torch.distributed.run --nproc_per_node 2 train.py --batch 64 --data coco.yaml --weights yolov5s.pt --device 0,1
  • --nproc_per_node указывает, сколько GPU вы хотите использовать. В примере выше это 2.
  • --batch это общий размер пакета. Он будет равномерно разделен между всеми GPU. В примере выше это 64/2=32 на GPU.

Приведенный выше код будет использовать GPU. 0... (N-1).

Используйте определенные GPU (нажмите, чтобы развернуть) Вы можете сделать это, просто передав `--device`, за которым следуют ваши конкретные GPU. Например, в коде ниже мы будем использовать GPU `2,3`.
python -m torch.distributed.run --nproc_per_node 2 train.py --batch 64 --data coco.yaml --cfg yolov5s.yaml --weights '' --device 2,3
Используйте SyncBatchNorm (нажмите, чтобы развернуть) [SyncBatchNorm](https://docs.pytorch.org/docs/master/generated/torch.nn.SyncBatchNorm.html) could increase [accuracy](https://www.ultralytics.com/glossary/accuracy) for multiple GPU training, however, it will slow down training by a significant factor. It is **only** available for Multiple GPU DistributedDataParallel training. It is best used when the batch-size on **each** GPU is small (<= 8). To use SyncBatchNorm, simply pass `--sync-bn` to the command like below:
python -m torch.distributed.run --nproc_per_node 2 train.py --batch 64 --data coco.yaml --cfg yolov5s.yaml --weights '' --sync-bn
Используйте несколько машин (нажмите, чтобы развернуть) Это **доступно только** для обучения с использованием Multiple GPU DistributedDataParallel. Прежде чем мы продолжим, убедитесь, что файлы на всех машинах одинаковы: набор данных, кодовая база и т. д. После этого убедитесь, что машины могут связываться друг с другом. Вам нужно будет выбрать главную машину (машину, с которой будут связываться остальные). Запишите ее адрес (`master_addr`) и выберите порт (`master_port`). Я буду использовать `master_addr = 192.168.1.1` и `master_port = 1234` для примера ниже. Чтобы использовать это, вы можете сделать следующее:
# On master machine 0
python -m torch.distributed.run --nproc_per_node G --nnodes N --node_rank 0 --master_addr "192.168.1.1" --master_port 1234 train.py --batch 64 --data coco.yaml --cfg yolov5s.yaml --weights ''
# On machine R
python -m torch.distributed.run --nproc_per_node G --nnodes N --node_rank R --master_addr "192.168.1.1" --master_port 1234 train.py --batch 64 --data coco.yaml --cfg yolov5s.yaml --weights ''
где `G` — количество GPU на машину, `N` — количество машин, а `R` — номер машины от `0...(N-1)`. Допустим, у меня есть две машины с двумя GPU на каждой, тогда будет `G = 2`, `N = 2` и `R = 1` для вышеуказанного. Обучение не начнется до тех пор, пока **все** `N` машин не будут подключены. Вывод будет отображаться только на главной машине!

Примечания

  • Поддержка Windows не тестировалась, рекомендуется Linux.
  • --batch должно быть кратно количеству GPU.
  • GPU 0 будет использовать немного больше памяти, чем другие GPU, поскольку он поддерживает EMA и отвечает за создание контрольных точек и т. д.
  • Если вы получите RuntimeError: Address already in use, это может быть связано с тем, что вы запускаете несколько процессов обучения одновременно. Чтобы это исправить, просто используйте другой номер порта, добавив --master_port как показано ниже:

    python -m torch.distributed.run --master_port 1234 --nproc_per_node 2 ...
    

Results

Результаты профилирования DDP на экземпляре AWS EC2 P4d с 8x A100 SXM4-40GB для YOLOv5l для 1 эпохи COCO.

Профилирование кода
# prepare
t=ultralytics/yolov5:latest && sudo docker pull $t && sudo docker run -it --ipc=host --gpus all -v "$(pwd)"/coco:/usr/src/coco $t
pip3 install torch==1.9.0+cu111 torchvision==0.10.0+cu111 -f https://download.pytorch.org/whl/torch_stable.html
cd .. && rm -rf app && git clone https://github.com/ultralytics/yolov5 -b master app && cd app
cp data/coco.yaml data/coco_profile.yaml

# profile
python train.py --batch-size 16 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0
python -m torch.distributed.run --nproc_per_node 2 train.py --batch-size 32 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0,1
python -m torch.distributed.run --nproc_per_node 4 train.py --batch-size 64 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0,1,2,3
python -m torch.distributed.run --nproc_per_node 8 train.py --batch-size 128 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0,1,2,3,4,5,6,7
GPU
A100
Размер пакета (batch-size) CUDA_mem
device0 (G)
COCO
train
COCO
val
1x 16 26 ГБ 20:39 0:55
2x 32 26 ГБ 11:43 0:57
4x 64 26 ГБ 5:57 0:55
8x 128 26 ГБ 3:09 0:57

Как показывают результаты, использование DistributedDataParallel с несколькими GPU обеспечивает почти линейное масштабирование скорости обучения. С 8 GPU обучение завершается примерно в 6,5 раз быстрее, чем с одним GPU, при этом сохраняется одинаковое использование памяти на устройство.

Часто задаваемые вопросы

В случае возникновения ошибки, пожалуйста, сначала ознакомьтесь с приведенным ниже списком! (Это может сэкономить ваше время)

Контрольный список (нажмите, чтобы развернуть) - Вы внимательно прочитали этот пост? - Вы пробовали повторно клонировать кодовую базу? Код меняется **ежедневно**. - Вы пробовали искать свою ошибку? Возможно, кто-то уже сталкивался с ней в этом или другом репозитории и имеет решение. - Вы установили все требования, перечисленные выше (включая правильные версии Python и PyTorch)? - Вы пробовали в других средах, перечисленных в разделе «Среды» ниже? - Вы пробовали с другим набором данных, таким как coco128 или coco2017? Это облегчит поиск основной причины. Если вы выполнили все вышеперечисленное, не стесняйтесь поднять проблему, предоставив как можно больше подробностей, следуя шаблону.

Поддерживаемые среды

Ultralytics предоставляет ряд готовых к использованию сред, каждая из которых предварительно установлена с необходимыми зависимостями, такими как CUDA, CUDNN, Python и PyTorch, чтобы дать старт вашим проектам.

Статус проекта

YOLOv5 CI

Этот значок указывает на то, что все тесты непрерывной интеграции (CI) YOLOv5 GitHub Actions успешно пройдены. Эти тесты CI тщательно проверяют функциональность и производительность YOLOv5 по различным ключевым аспектам: обучение, валидация, вывод, экспорт и бенчмарки. Они обеспечивают стабильную и надежную работу в macOS, Windows и Ubuntu, при этом тесты проводятся каждые 24 часа и при каждом новом коммите.

Авторы

Мы хотели бы поблагодарить @MagicFrogSJTU, который проделал всю тяжелую работу, и @glenn-jocher за руководство на этом пути.

См. также



📅 Создано 1 год назад ✏️ Обновлено 22 дня назад

Комментарии