DistributedDataParallel (DDP)
Grupy procesów, dist.init_process_group, DistributedSampler, synchronizacja gradientów.
DistributedDataParallel (DDP) to bezpłatna lekcja Learn AI with Python na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Learn AI with Python, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn AI with Python zawiera 4 lekcji w sumie.
Czym jest DDP
DistributedDataParallel (DDP) to wysokowydajne podejście PyTorch do trenowania z równoległością danych. Uruchamia jeden proces na każdy GPU, przy czym każdy proces przechowuje pełną replikę modelu i efektywnie synchronizuje gradienty. DDP skaluje się niemal liniowo między GPU i maszynami.
Grupa procesów
DDP koordynuje procesy za pośrednictwem grupy procesów. Każdy proces otrzymuje unikalny rank i zna całkowity rozmiar świata. Procesy komunikują się za pośrednictwem backendu; w przypadku GPU NVIDIA tym backendem jest nccl.
init_process_group
Każdy proces rozpoczyna od dołączenia do grupy. dist.init_process_group z backend="nccl" konfiguruje komunikację między GPU.
import torch.distributed as dist
import os
dist.init_process_group(backend="nccl")
rank = dist.get_rank()
world_size = dist.get_world_size()Przypisanie urządzenia
Każdy proces powinien zarządzać jednym GPU. Należy użyć lokalnego ranku do ustawienia urządzenia, tak aby proces 0 korzystał z cuda:0, proces 1 z cuda:1 i tak dalej.
local_rank = int(os.environ["LOCAL_RANK"])
torch.cuda.set_device(local_rank)
device = torch.device("cuda", local_rank)Opakowanie modelu
Model należy przenieść na jego GPU, a następnie opakować go w DDP za pomocą device_ids=[local_rank]. DDP rejestruje hooki, które będą synchronizować gradienty podczas propagacji wstecznej.
from torch.nn.parallel import DistributedDataParallel as DDP
model = MyModel().to(device)
model = DDP(model, device_ids=[local_rank])DistributedSampler
Każdy proces musi otrzymać inny fragment danych, bez nakładania się fragmentów. DistributedSampler dzieli zbiór danych między ranki, dzięki czemu ich suma obejmuje cały zbiór dokładnie raz w każdej epoce.
from torch.utils.data import DataLoader
from torch.utils.data.distributed import DistributedSampler
sampler = DistributedSampler(dataset)
loader = DataLoader(dataset, batch_size=32, sampler=sampler)Tasowanie w każdej epoce
Na początku każdej epoki należy wywołać sampler.set_epoch(epoch). Powoduje to spójne ponowne zainicjalizowanie tasowania we wszystkich procesach, dzięki czemu każdy rank tasuje dane w ten sam sposób, a partycje pozostają rozłączne.
for epoch in range(epochs):
sampler.set_epoch(epoch)
for x, y in loader:
...Gradientowe all-reduce
Podczas loss.backward() DDP wykonuje operację all-reduce: każdy proces wysyła swoje gradienty i otrzymuje ich uśredniony wynik, dzięki czemu wszystkie repliki stosują identyczne aktualizacje. Operacja all-reduce nakłada się na propagację wsteczną, ukrywając koszt komunikacji.
Brak wąskiego gardła GPU 0
W przeciwieństwie do DataParallel, DDP nie ma centralnego GPU zbierającego wyniki. Każdy proces oblicza własną funkcję straty i gradienty; wymieniane są wyłącznie gradienty za pomocą all-reduce. Ta symetria wyjaśnia, dlaczego DDP skaluje się znacznie lepiej.
Uruchamianie za pomocą torchrun
torchrun uruchamia procesy dla poszczególnych GPU i ustawia zmienne środowiskowe określające ranki. --nproc_per_node=4 uruchamia 4 procesy (po jednym na GPU) na tym węźle.
torchrun --nproc_per_node=4 train.pyZapisywanie tylko na ranku 0
Wszystkie ranki przechowują identyczne wagi, dlatego tylko jeden z nich powinien zapisywać checkpoint, aby uniknąć wzajemnego nadpisywania. Zapis należy zabezpieczyć sprawdzeniem ranku.
if rank == 0:
torch.save(model.module.state_dict(), "model.pt")
dist.barrier()Szybkie sprawdzenie
Proszę sprawdzić swoją wiedzę o DDP.
Podsumowanie
Poznali Państwo DistributedDataParallel:
dist.init_process_group(backend="nccl")dołącza proces do grupy procesów- DistributedSampler przydziela każdemu rankowi rozłączny fragment danych
DDP(model, device_ids=[rank])synchronizuje gradienty za pomocą all-reduce- Uruchamianie odbywa się za pomocą
torchrun --nproc_per_node=4 - Zapis należy wykonywać tylko na ranku 0
Często zadawane pytania
Czy lekcja „DistributedDataParallel (DDP)” jest bezpłatna?
Tak — pełny tekst „DistributedDataParallel (DDP)” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Learn AI with Python, przejdź na CoddyKit PRO. Kurs Learn AI with Python zawiera 4 lekcji w sumie.
Co nauczysz się w „DistributedDataParallel (DDP)”?
Grupy procesów, dist.init_process_group, DistributedSampler, synchronizacja gradientów. Ćwiczysz Learn AI with Python z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Learn AI with Python?
Nie wymagamy żadnego doświadczenia. Learn AI with Python w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „DistributedDataParallel (DDP)”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Learn AI with Python?
Tak. Każda lekcja Learn AI with Python zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Trenowanie na wielu GPU za pomocą DataParallel
- DistributedDataParallel (DDP)
- Trenowanie z mieszaną precyzją za pomocą AMP
- Wydajne trenowanie za pomocą Hugging Face Accelerate