Vai al contenuto

Addestramento Multi-GPU con YOLOv5

Questa guida spiega come utilizzare correttamente più GPU per addestrare un set di dati con YOLOv5 🚀 su una o più macchine.

Prima di iniziare

Clona il repository e installa i requirements.txt in un ambiente Python>=3.8.0, incluso PyTorch>=1.8. I modelli e i dataset vengono scaricati automaticamente dall'ultima release di YOLOv5.

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

Suggerimento!

Immagine Docker è raccomandato per tutti gli addestramenti Multi-GPU. Vedi Guida rapida a DockerPull di Docker

Suggerimento!

torch.distributed.run sostituisce torch.distributed.launch in PyTorch>=1.9. Vedere Documentazione distribuita di PyTorch per i dettagli.

Training

Seleziona un modello pre-addestrato da cui iniziare l'addestramento. Qui selezioniamo YOLOv5s, il modello più piccolo e veloce disponibile. Consulta la nostra tabella nel file README per un confronto completo di tutti i modelli. Addestreremo questo modello con Multi-GPU sul dataset COCO.

Modelli YOLOv5

Singola GPU

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

Puoi aumentare il device per utilizzare più GPU in modalità DataParallel.

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

Questo metodo è lento e accelera a malapena l'addestramento rispetto all'utilizzo di una sola GPU.

Dovrai superare python -m torch.distributed.run --nproc_per_node, seguito dai soliti argomenti.

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 specifica il numero di GPU che si desidera utilizzare. Nell'esempio sopra, è 2.
  • --batch è la dimensione totale del batch. Sarà diviso equamente per ogni GPU. Nell'esempio sopra, è 64/2=32 per GPU.

Il codice sopra utilizzerà le GPU 0... (N-1). È inoltre possibile impostare CUDA_VISIBLE_DEVICES=2,3 (o qualsiasi altro elenco) prima di lanciare il comando, se si preferisce controllare la visibilità del dispositivo tramite variabili d'ambiente.

Utilizza GPU specifiche (clicca per espandere) Puoi farlo semplicemente passando `--device` seguito dalle tue GPU specifiche. Ad esempio, nel codice seguente, useremo le 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
Utilizza SyncBatchNorm (clicca per espandere) [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
Utilizza più macchine (clicca per espandere) Questo è **solo** disponibile per la formazione DistributedDataParallel su più GPU . Prima di continuare, assicurarsi che i file su tutte le macchine siano gli stessi, dataset, codebase, ecc. Successivamente, assicurarsi che le macchine possano comunicare tra loro. Si dovrà scegliere una macchina master (la macchina con cui le altre parleranno). Annotate il suo indirizzo (`master_addr`) e scegliete una porta (`master_port`). Nell'esempio che segue utilizzerò `master_addr = 192.168.1.1` e `master_port = 1234`. Per usarlo, si può fare come segue:
# 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 ''
dove `G` è il numero di GPU per macchina, `N` è il numero di macchine e `R` è il numero di macchina da `0...(N-1)`. Supponiamo di avere due macchine con due GPU ciascuna, sarebbe `G = 2`, `N = 2` e `R = 1` per quanto detto sopra. L'addestramento non inizierà finché **tutte** le `N` macchine non saranno connesse. L'output sarà mostrato solo sulla macchina master!

Note

  • Il supporto per Windows non è testato, si consiglia Linux.
  • --batch deve essere un multiplo del numero di GPU.
  • La GPU 0 utilizzerà leggermente più memoria rispetto alle altre GPU poiché gestisce l'EMA ed è responsabile del checkpointing, ecc.
  • Se ottieni RuntimeError: Address already in use, potrebbe essere perché stai eseguendo più addestramenti contemporaneamente. Per risolvere questo problema, è sufficiente utilizzare un numero di porta diverso aggiungendo --master_port come sotto:

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

Risultati

Risultati della profilazione DDP su un'istanza AWS EC2 P4d con 8x A100 SXM4-40GB per YOLOv5l per 1 epoca COCO.

Codice di profilazione
# 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
dimensione-batchCUDA_mem
device0 (G)
COCO
train
COCO
val
1x1626GB20:390:55
2x3226GB11:430:57
4x6426GB5:570:55
8x12826GB3:090:57

Come mostrato nei risultati, l'utilizzo di DistributedDataParallel con più GPU fornisce un ridimensionamento quasi lineare nella velocità di training. Con 8 GPU, il training viene completato circa 6,5 volte più velocemente rispetto a una singola GPU, mantenendo lo stesso utilizzo di memoria per dispositivo.

FAQ

In caso di errore, leggere prima la checklist qui sotto! (Potrebbe farvi risparmiare tempo)

Checklist (clicca per espandere) - Hai letto bene questo post? - Hai provato a riclonare la base di codice? Il codice cambia **quotidianamente**. - Hai provato a cercare il tuo errore? Qualcuno potrebbe averlo già riscontrato in questo repo o in un altro e avere la soluzione. - Sono stati installati tutti i requisiti elencati sopra (comprese le versioni corrette di Python e PyTorch )? - Avete provato in altri ambienti elencati nella sezione "Ambienti" qui sotto? - Avete provato con un altro set di dati come coco128 o coco2017? In questo modo sarà più facile trovare la causa principale. Se avete seguito tutte le procedure di cui sopra, non esitate a sollevare un problema fornendo il maggior numero di dettagli possibile seguendo il modello.

Ambienti supportati

Ultralytics fornisce una gamma di ambienti pronti all'uso, ciascuno preinstallato con dipendenze essenziali come CUDA, CUDNN, Python e PyTorch, per avviare i tuoi progetti.

Stato del progetto

YOLOv5 CI

Questo badge indica che tutti i test di Integrazione Continua (CI) di YOLOv5 GitHub Actions vengono superati con successo. Questi test CI verificano rigorosamente la funzionalità e le prestazioni di YOLOv5 attraverso vari aspetti chiave: training, validation, inference, export e benchmarks. Garantiscono un funzionamento coerente e affidabile su macOS, Windows e Ubuntu, con test eseguiti ogni 24 ore e ad ogni nuovo commit.

Riconoscimenti

Vorremmo ringraziare @MagicFrogSJTU, che ha fatto tutto il lavoro pesante, e @glenn-jocher per averci guidato lungo il percorso.

Vedi anche



📅C reato 2 anni fa ✏️ Aggiornato 5 giorni fa
glenn-jocherUltralyticsAssistantonuralpszrLaughing-qRizwanMunawarBurhan-Q

Commenti