Rozdzielić microbatch, przebieg wstecz i aktualizację
Microbatch to grupa przykładów przetwarzana przez przebieg w przód na jednej replice. Przebieg wstecz oblicza jego wkład do gradientów. Aktualizacja optymizatora wykorzystuje dostępne gradienty do zmiany parametrów. Przy akumulacji kilka przebiegów w przód/wstecz poprzedza tę aktualizację; parametry pozostają niezmienione w trakcie grupy.
W PyTorch gradienty akumulują się w przeznaczonych do tego tensorach. Wyzerowanie gradientów po każdym microbatchu anulowałoby więc zamierzoną akumulację. Z kolei zapomnienie o wyzerowaniu ich między dwiema grupami sprawiłoby, że przykłady z poprzedniej aktualizacji wniosłyby swój wkład.
Zdefiniuj swoją jednostkę logowania: numer microbatcha, aktualizację optymizatora, widziane przykłady lub tokeny. Samo słowo „step” jest niejednoznaczne. Krzywej straty nie da się poprawnie porównać, jeśli na osi jednego z eksperymentów jest osiem razy więcej przykładów.
Źródła techniczne: PyTorch — akumulacja i zerowanie gradientów
Obliczyć efektywny batch bez podwójnego liczenia GPU
Oznaczmy m jako liczbę przykładów na microbatch i na replikę, A jako liczbę zakumulowanych microbatchy, D jako liczbę replik równoległości danych. Jeśli te rozmiary są stałe, a przykłady poprawnie rozdzielone, liczba przykładów wnoszących wkład do jednej globalnej aktualizacji wynosi m × A × D.
Czynnik D nie musi oznaczać wszystkich kart w maszynie. GPU, które dzielą jeden model przez równoległość tensorową lub potokową, nie stają się przez to tyloma replikami danych. Zapisz faktycznie skonfigurowane grupy, a nie samą handlową wielkość partii.
Przykład arytmetyczny: dwa przykłady na mikrobatch, osiem akumulacji i dwie repliki dają 32 przykłady na globalną aktualizację. Każda replika przetwarza szesnaście przykładów w tej grupie. Tabela porównuje liczby; nie szereguje ich pod względem pamięci ani szybkości.
| m | A | D | Przykłady na globalną aktualizację |
|---|---|---|---|
| 2 | 8 | 2 | 32 |
| 1 | 16 | 2 | 32 |
| 4 | 4 | 2 | 32 |
| 2 | 8 | 1 | 16 |
Źródła techniczne: PyTorch — efektywny batch i akumulacja w mieszanej precyzji · PyTorch — zachowanie replik DistributedDataParallel
Normalizacja straty według faktycznie ocenianych elementów
W przypadku średniej straty na mikrobatchach zawierających tę samą liczbę istotnych elementów podzielenie każdego wkładu przez A daje średnią grupy. Ta reguła zakłada, że framework nie wykonuje już tej normalizacji. Jeśli używasz narzędzia, które obsługuje akumulację, przeczytaj jego kontrakt, zanim dodasz ręczne dzielenie.
W przypadku średniej straty na token różne długości zmieniają mianownik. Należy odnieść sumę strat do faktycznie nadzorowanych tokenów w grupie, z wyłączeniem paddingu i pozycji ignorowanych. Średnia ze średnich mikrobatchów na ogół nie daje tego samego celu.
Przykład teoretyczny: jeden mikrobatch ma 512 nadzorowanych tokenów ze średnią stratą 2; inny ma 1 536 ze średnią 4. Średnia ważona wynosi (512 × 2 + 1 536 × 4) ÷ 2 048 = 3,5. Średnia nieważona wynosi 3 i nadmiernie uwzględnia małą grupę. Te wartości ilustrują wyłącznie obliczenie.
Źródła techniczne: Hugging Face Accelerate — akumulacja z przykładami o zmiennych rozmiarach
Organizacja pełnej grupy akumulacji
Najpierw przygotuj granice grupy i jej mianownik. Dla każdego mikrobatcha oblicz wyjście, znormalizowaną stratę i przebieg wsteczny bez pośredniej aktualizacji. Zwalniaj wyjścia, których już nie potrzebujesz; przechowywanie strat powiązanych z ich grafem na liście może wydłużyć życie alokacji.
Po ostatnim wkładzie zastosuj zaplanowane operacje na pełnym gradiencie, a następnie aktualizację. Potem zresetuj gradienty dla następnej grupy. Jeśli przebieg kończy się z mniejszą liczbą niż A mikrobatchów, wybierz wyraźnie: przetworzyć tę częściową grupę z jej prawdziwym mianownikiem albo ją odrzucić; zanotuj dotknięte przykłady.
Przy mieszanej precyzji używającej GradScaler współczynnik skalowania pozostaje stały podczas akumulacji. Rzeczywiste odwrócenie skalowania i ewentualny clipping następują po wkładach; aktualizacja skalera następuje po próbie kroku. Kontrole wartości nieniosących skończoności mogą zapobiec zmianie parametrów.
Scheduler musi podążać za jednostką ogłoszoną przez twoją pętlę. Jeśli jest zdefiniowany na aktualizację optymalizatora, wywoływanie go przy każdym mikrobatchu zmieniłoby harmonogram. Rejestruj osobno próby i faktycznie zastosowane aktualizacje, gdy twój system może część pominąć.
Źródła techniczne: PyTorch — grafy autograd i tensory zachowane dla backward · PyTorch — akumulacja, unscale, clipping i GradScaler
W trybie multi-GPU sprawdź redukcję i podział przykładów
DistributedDataParallel synchronizuje gradienty między replikami. W swoim zwykłym zachowaniu uśrednia je; dlatego suma strat i lokalnie uśredniona strata nie mają tej samej skali. Przy różnej liczbie tokenów między replikami globalny mianownik i ta redukcja muszą być rozpatrywane razem.
Sprawdź faktycznie przetwarzane identyfikatory: niezamierzone zduplikowanie tych samych przykładów na wszystkich kartach nie zwiększa w takim samym stopniu informacji w grupie. Aby opóźnić pośrednie komunikacje, można użyć no_sync na mikrobatchach poprzedzających końcową synchronizację; jego kontekst musi obejmować także przebieg w przód.
Nie przenoś tej reguły na wszystkie systemy rozproszone. Sharding stanów, pipeline, hooki komunikacyjne i frameworki mogą zmieniać faktyczne operacje. Zacznij od konfiguracji obsługiwanej przez twoje narzędzie, a potem sprawdź pełną grupę na każdej replice.
Źródła techniczne: PyTorch — redukcja gradientów i zakres no_sync w DDP
Dlaczego ten sam efektywny batch nie gwarantuje tego samego doświadczenia
Równość m × A × D to zliczanie. Aby odtworzyć gradient dużego batcha, potrzebne są w szczególności odpowiednio zważone wkłady, ten sam stan parametrów w trakcie grupy oraz operacje zgodne z tym rozkładem. Bliskość numeryczną weryfikuje się z odpowiednią tolerancją; nie wynika ona z samego iloczynu.
BatchNorm oblicza statystyki na podstawie wejść ze swojego przebiegu: kilka małych mikrobatchy nie przedstawia mu tych samych grup co duży batch. Operacje losowe, kolejność obliczeń i zaokrąglenia również mogą się różnić. Nie obiecuj końcowych wag identycznych co do bitu.
Zmiana globalnego batcha może też zmienić liczbę aktualizacji przy tej samej liczbie widzianych przykładów. Ustal z góry oś porównania i swoją regułę jakości. Nie zmieniaj jednocześnie współczynnika uczenia, schedulera i czasu trwania bez udokumentowania tych nowych założeń.
Źródła techniczne: PyTorch — statystyki BatchNorm1d · PyTorch — ograniczenia odtwarzalności
Kontrolować pamięć i zdecydować o dalszych krokach
Instrumentuj grupę obejmującą przebiegi wsteczne i pierwszą aktualizację, a następnie kolejne grupy. Powodzenie w forward nie potwierdza gradientów ani stanów utworzonych przez optymalizator. Liczniki muszą zachowywać swój zakres na device. Dossier pamięci podaje metodę odczytu baseline'ów i szczytów.
Jeśli grupa zawiedzie, zmniejsz mikrobatch i przelicz A, aby zachować docelowy batch efektywny, gdy ten wybór pozostaje zasadny. Ta zmiana nie gwarantuje ani proporcjonalnego podziału szczytu, ani lepszego czasu trwania. Jeśli dominują wagi lub stany, sama akumulacja może być niewystarczająca.
Przed kampanią sprawdź jedną aktualizację na małym, kontrolowanym zbiorze: te same przykłady, ważona strata, skończone gradienty, granica grupy i liczba kroków. Następnie oceń jakość według przyjętego protokołu. Mały MLP inferencyjny z dossier do pobrania nie wykonuje tego przepisu treningowego; nie zastępuje tego sprawdzenia.
Twoja końcowa karta zbiera m, A, D, nadzorowane tokeny, precyzję, normalizację, obsługę ostatniej grupy i zaobserwowane szczyty. Wróć następnie do wyboru konfiguracji i budżetu eksperymentów, oddzielając przygotowanie, próby i faktycznie zaakceptowane wyniki.
- Nienaturalnie mała strata: szukaj podwójnego dzielenia przez akumulację.
- Wynik zmieniający się wraz z podziałem: sprawdź ignorowane tokeny i średnią ze średnich.
- Akumulacja bez efektu: sprawdź zero_grad i optimizer.step.
- Rosnąca pamięć: szukaj referencji zachowanych między mikrobatchami.
- Przesunięty kalendarz: rozróżnij przebiegi wsteczne i aktualizacje.
Źródła techniczne: Hugging Face — szczyty pamięci treningu
Praktyczne pytania
Czy akumulacja szesnastu mikrobatchy mnoży pamięć przez szesnaście?
Niekoniecznie: wkłady są przetwarzane kolejno. Gradienty utrzymują się, a niepotrzebne aktywacje mogą zostać zwolnione. Szczyt zależy jednak od modelu, zachowanych referencji i stanów optymalizatora; zmierz całą grupę.
Czy dwa GPU zawsze podwajają batch efektywny?
Tylko jeśli te GPU uczestniczą jako dwie repliki danych z ogłoszonym mikrobatchem. Karty dzielące ten sam model nie tworzą automatycznie dwóch replik. Sprawdź grupy rozproszone i przetworzone przykłady.
Czy mogę podzielić wszystkie straty przez liczbę akumulacji?
Ta prosta reguła odpowiada mikrobatchom o równej wadze, bez normalizacji już obsługiwanej przez framework. Przy zmiennych liczbach nadzorowanych tokenów lub niekompletnej ostatniej grupie użyj rzeczywistego mianownika celu.