Entraînement multi-GPU avec YOLOv5

Ce guide explique comment entraîner YOLOv5 avec plusieurs GPU sur une seule machine ou sur plusieurs machines.

Avant de commencer

Clone le dépôt et installe requirements.txt dans un environnement Python>=3.8.0, en incluant PyTorch>=1.8. Les modèles et les datasets se téléchargent automatiquement depuis la dernière release de YOLOv5.

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

L'image Docker Ultralytics est recommandée pour tous les entraînements multi-GPU. Consulte le Guide de démarrage rapide Docker. Docker Pulls

PyTorch >= 1.9

torch.distributed.run remplace torch.distributed.launch dans PyTorch >= 1.9. Consulte la documentation distribuée de PyTorch pour plus de détails.

Entraînement

Choisis un modèle pré-entraîné pour commencer l'entraînement. Ici, nous sélectionnons YOLOv5s, le modèle le plus petit et le plus rapide disponible. Consulte notre tableau dans le README pour une comparaison complète de tous les modèles. Nous entraînerons ce modèle avec plusieurs GPU sur le dataset COCO.

YOLOv5 Models

GPU unique

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

Mode Multi-GPU DataParallel (⚠️ non recommandé)

Passe plusieurs identifiants GPU à --device pour activer le mode DataParallel :

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

DataParallel est lent et accélère à peine l'entraînement par rapport à l'utilisation d'un seul GPU.

Mode Multi-GPU DistributedDataParallel (✅ recommandé)

Fais précéder la commande d'entraînement de python -m torch.distributed.run --nproc_per_node, puis passe les arguments habituels :

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 est le nombre de GPU à utiliser. Dans l'exemple ci-dessus, il s'agit de 2.
  • --batch est la taille totale du lot, divisée également entre chaque GPU. Dans l'exemple ci-dessus, cela représente 64 / 2 = 32 par GPU.

La commande ci-dessus utilise les GPU 0...(N-1). Pour contrôler la visibilité des appareils via des variables d'environnement, définis CUDA_VISIBLE_DEVICES=2,3 (ou toute autre liste) avant de lancer.

Use specific GPUs (click to expand)

Passe --device suivi des identifiants spécifiques des GPU. L'exemple ci-dessous utilise les 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
Use SyncBatchNorm (click to expand)

SyncBatchNorm peut augmenter la précision pour l'entraînement multi-GPU, mais il ralentit considérablement l'entraînement. Il est uniquement disponible pour l'entraînement multi-GPU DistributedDataParallel.

À utiliser de préférence lorsque la taille du lot sur chaque GPU est petite (<= 8).

Pour activer SyncBatchNorm, passe --sync-bn :

python -m torch.distributed.run --nproc_per_node 2 train.py --batch 64 --data coco.yaml --cfg yolov5s.yaml --weights '' --sync-bn
Use Multiple machines (click to expand)

Ceci est uniquement disponible pour l'entraînement multi-GPU DistributedDataParallel.

Avant de continuer, assure-toi que le dataset, le code et toutes les autres dépendances correspondent sur toutes les machines, puis vérifie que les machines peuvent se connecter entre elles sur le réseau.

Choisis une machine maître (celle à laquelle les autres se connecteront), note son adresse (master_addr) et choisis un port (master_port). L'exemple ci-dessous utilise master_addr = 192.168.1.1 et master_port = 1234.

Ensuite, lance :

# 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 est le nombre de GPU par machine, N est le nombre de machines, et R est le rang de la machine dans 0...(N-1). Par exemple, avec deux machines et deux GPU chacune, définis G = 2, N = 2, et R = 1 sur la deuxième machine.

L'entraînement ne démarre pas tant que toutes les N machines ne sont pas connectées. La sortie n'est affichée que sur la machine maître.

Notes

  • La prise en charge de Windows n'est pas testée ; Linux est recommandé.

  • --batch doit être un multiple du nombre de GPU.

  • Le GPU 0 utilise légèrement plus de mémoire que les autres car il maintient l'EMA et gère la sauvegarde des checkpoints.

  • Si tu reçois l'erreur RuntimeError: Address already in use, cela signifie généralement que plusieurs exécutions d'entraînement utilisent le même port. Spécifie un port différent avec --master_port :

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

Results

Résultats de profilage DDP sur une instance AWS EC2 P4d avec 8x A100 SXM4-40GB pour YOLOv5l pendant 1 époque COCO.

Profiling code
# prepare
t=ultralytics/yolov5:latest && sudo docker pull $t && sudo docker run -it --runtime=nvidia --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
taille-lotMémoire CUDA
appareil0 (G)
COCO
train
COCO
val
1x1626GB20:390:55
2x3226GB11:430:57
4x6426GB5:570:55
8x12826GB3:090:57

Comme le montrent les résultats, l'utilisation de DistributedDataParallel avec plusieurs GPU offre une mise à l'échelle presque linéaire de la vitesse d'entraînement. Avec 8 GPU, l'entraînement se termine environ 6,5 fois plus vite qu'avec un seul GPU, tout en conservant la même utilisation de mémoire par appareil.

FAQ

Consulte la liste de vérification ci-dessous avant d'ouvrir un ticket — cela permet souvent de gagner du temps.

Checklist (click to expand)
  • As-tu lu ce guide entièrement ?
  • As-tu re-cloné la base de code ? Le code change quotidiennement.
  • As-tu cherché le message d'erreur ? Quelqu'un a peut-être déjà rencontré le même problème et partagé une solution.
  • As-tu installé toutes les dépendances (y compris les versions correctes de Python et PyTorch) ?
  • As-tu essayé l'un des environnements pris en charge listés ci-dessous ?
  • As-tu essayé avec un dataset plus petit tel que coco128 ou coco2017 pour isoler la cause première ?

Si tout ce qui précède est en ordre, ouvre un ticket avec autant de détails que possible, en suivant le modèle.

Environnements pris en charge

Ultralytics propose une gamme d'environnements prêts à l'emploi, chacun pré-installé avec des dépendances essentielles telles que CUDA, CUDNN, Python et PyTorch, pour démarrer rapidement tes projets.

État du projet

YOLOv5 CI

Ce badge indique que tous les tests d'intégration continue (CI) des GitHub Actions de YOLOv5 réussissent. Ces tests CI vérifient rigoureusement la fonctionnalité et les performances de YOLOv5 sous divers aspects clés : entraînement, validation, inférence, export et benchmarks. Ils garantissent un fonctionnement cohérent et fiable sur macOS, Windows et Ubuntu, avec des tests effectués toutes les 24 heures et à chaque nouveau commit.

Crédits

Nous tenons à remercier @MagicFrogSJTU, qui a fait tout le travail difficile, et @glenn-jocher pour nous avoir guidés tout au long du chemin.

Voir aussi

Commentaires