Antrenare Distribuită Multi-GPU: DistributedDataParallel (DDP) în PyTorch & Deep Learning Practic

Scalarea antrenării pe mai multe plăci grafice: inițializarea proceselor cu torchrun, backend-ul NCCL, sincronizarea gradienților cu AllReduce și DistributedSampler.

Sintaxă & invocare Python
# Lansare din terminal cu utilitarul oficial torchrun (ex: 4 GPU-uri pe un server):
torchrun --nproc_per_node=4 antrenare.py

# În scriptul Python:
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP

dist.init_process_group(backend="nccl")
model = DDP(model.to(local_rank), device_ids=[local_rank])

Descriere & Utilizare

Când un model de inteligență artificială devine prea mare sau setul de date are milioane de exemple, o singură placă grafică nu mai este suficientă. DistributedDataParallel (DDP) este standardul industrial de aur în PyTorch pentru scalarea antrenării pe oricâte GPU-uri (pe același server sau într-un cluster întreg).

Spre deosebire de vechiul DataParallel (care folosea un singur proces Python și suferea de blocaje GIL), DDP lansează un proces Python complet independent per placă grafică. Fiecare proces deține o copie identică a modelului și procesează o bucată unică din setul de date.

La finalul fiecărui pas, GPU-urile comunică între ele la viteze de sute de gigabytes pe secundă prin backend-ul NVIDIA NCCL folosind algoritmul inelar AllReduce, mediind gradienții înainte ca fiecare model să își actualizeze parametrii în sincronizare perfectă.

Cum să o reții ușor

💡 Patru bucătari identici care gătesc aceeași rețetă în paralel: fiecare are bancul său de lucru și tigaia sa (GPU-ul său), dar la finalul fiecărui pas își compară măsurătorile pe walkie-talkie (NCCL AllReduce) pentru a se asigura că mâncarea iese identic gustoasă.

Opțiuni și parametri tehnici

  • torchrun: utilitarul de terminal recomandat de lansare care configurează automat variabilele de mediu RANK, WORLD_SIZE și LOCAL_RANK.
  • backend="nccl": biblioteca de comunicare inter-GPU optimizată de NVIDIA (pe CPU se folosește backend="gloo").
  • DistributedSampler(dataset): se asigură că fiecare GPU primește o felie non-suprapusă din setul de date la fiecare epocă.
  • device_ids=[local_rank]: asociază fiecare proces cu GPU-ul său fizic corespunzător.

Exemple practice și cazuri de utilizare

  • Aflarea rangului local din mediu: local_rank = int(os.environ["LOCAL_RANK"]).
  • Setarea epocii pe DistributedSampler pentru amestecare corectă: sampler.set_epoch(epoca) la începutul fiecărei epoci.
  • Salvarea checkpoint-ului doar de pe primul GPU (Rank 0): if dist.get_rank() == 0: torch.save(model.module.state_dict(), "model.pt").

Sfaturi de configurare & capcane

Salvează întotdeauna greutățile folosind model.module.state_dict() în loc de model.state_dict() dintr-un model împachetat în DDP — altfel toate cheile vor avea prefixul nedorit "module."!

Comenzi și ghiduri înrudite