Co będziesz uruchamiać
Mini-projekt Kernodeck zawiera mały syntetyczny zbiór danych, sieć z dropoutem, pętlę treningową i weryfikator. Protokół wymusza CPU, aby odizolować logikę zapisu i wznowienia. Nie stanowi on kwalifikacji CUDA, ROCm, wielokartowej ani pomiaru wydajności wynajętego GPU.
Weryfikator otwiera nowe procesy dla przebiegu ciągłego, przerwania, pełnego wznowienia oraz przypadku negatywnego, który nie przywraca generatorów liczb losowych. Celem tego ostatniego jest sprawdzenie, czy kontrola potrafi wykryć niepełne wznowienie, nawet jeśli wagi i numer kroku wydają się poprawne.
Przewiń tabelę, aby zobaczyć wszystkie kolumny.| Przebieg | Wykonanie | Weryfikowane pytanie |
|---|---|---|
| Ciągły | 10 aktualizacji od stanu początkowego. | Jaki stan osiągamy bez przerwy? |
| Przerwanie | 5 aktualizacji, następnie zapis i zatrzymanie. | Czy punkt pośredni zawiera oczekiwane stany? |
| Pełne wznowienie | Nowy proces, wczytanie punktu 5, następnie 5 aktualizacji. | Czy otrzymujemy tę samą sekwencję wejść, tempa uczenia i parametrów w wybranej tolerancji? |
| Wznowienie bez RNG | Nowy proces, ten sam punkt wznowienia, ale pominięte przywrócenie losowości. | Czy test wykrywa dryf, który przepuściłoby samo wczytanie wag? |
Wymagania wstępne i uruchomienie protokołu
Pobierz archiwum, rozpakuj je do folderu roboczego, a następnie przejdź do folderu zawierającego train.py i verify_resume.py. Użyj środowiska Python z PyTorch i NumPy. Archiwum zawiera kod i syntetyczne dane; nie pobiera żadnego modelu i nie wymaga konta Kernodeck do uruchomienia ćwiczenia.
Dostarczony dowód został wykonany z Python 3.14.6, PyTorch 2.11.0+cu128 i NumPy 2.4.4. Program wymusza CPU, precyzję float64 i jeden wątek PyTorch. Sufiks pakietu nie oznacza więc, że wznowienie korzystało z CUDA. W innym środowisku wykonaj własną weryfikację.
Wybierz katalog wyjściowy, który jeszcze nie istnieje. Każdy przebieg tworzy checkpoint.pt, jego skrót checkpoint.pt.sha256 i summary.json. Weryfikator zbiera porównanie w verification.json. Opcja --steps liczy dodatkowe kroki: po przerwaniu na 5 polecenie wznowienia wykonuje 5, aby dojść do 10. Opcja Python -B zapobiega tworzeniu pamięci podręcznej bajtkodu w folderze ćwiczenia.
python -B verify_resume.py --output runs/preuve-cpupython -B train.py --steps 10 --output runs/continu
python -B train.py --steps 5 --output runs/coupure
python -B train.py --steps 5 --resume runs/coupure/checkpoint.pt --output runs/repriseEksport wag i checkpoint wznowienia mają różne role
Zacznij od wyboru tego, co chcesz odtworzyć. Eksport do wnioskowania służy do generowania predykcji za pomocą wytrenowanego modelu. Wznowienie treningu musi odtworzyć również stan, który determinuje kolejne aktualizacje. Przetwarzanie wnioskowania plik po pliku wymaga natomiast niezawodnej listy już ukończonych elementów. Te trzy potrzeby tworzą różne zapisy.
Nie myl tego trwałego zapisu z activation checkpointing. Ta technika redukuje część aktywacji przechowywanych w pamięci, przeliczając je podczas propagacji wstecznej; sama w sobie nie tworzy pliku umożliwiającego wznowienie po zatrzymaniu. Doprecyzuj więc w swoim projekcie, czy słowo checkpoint oznacza optymalizację pamięci, czy punkt wznowienia.
Stany, które trzeba zachować razem
state_dict modelu zawiera parametry i zarejestrowane bufory; optymalizator ma własny stan. Tutaj Adam, StepLR, dropout i trzy generatory liczb losowych wpływają na kolejne aktualizacje. Checkpoint musi reprezentować ten sam moment dla wszystkich tych elementów.
Udokumentuj także wersję kodu, parametry eksperymentu i tożsamość danych. W środku epoki sama znajomość jej numeru nie wystarcza: trzeba móc odtworzyć kolejność przykładów i następną partię do przetworzenia. Błąd w tym miejscu może pominąć wpisy lub przetworzyć je dwukrotnie.
Zbiór 24 wierszy opisuje syntetyczną zależność między dwiema zmiennymi a celem. Sieć ma 33 parametry, z jedną warstwą ośmiu neuronów i dropoutem 0,25. Batch zawiera cztery wiersze. Po pięciu aktualizacjach kursor wynosi 20 z 24: przerwanie następuje w środku epoki. Dziesięć aktualizacji zużywa 40 obserwacji, co zmusza test do przejścia przez nową permutację danych.
Przewiń tabelę, aby zobaczyć wszystkie kolumny.| Stan | Rola | Kontrola do wykonania |
|---|---|---|
| Model | Zachować wagi i bufory. | Porównać końcowe parametry i wynik ewaluacji. |
| Optymalizator | Zachować stany używane przez następną aktualizację. | Sprawdzić jego ponowne wczytanie, nie tylko hiperparametry. |
| Scheduler | Kontynuować sekwencję współczynników uczenia. | Porównać następny zastosowany współczynnik, a potem kolejne. |
| RNG Python, NumPy i PyTorch | Kontynuować faktycznie użyte losowania. | Sprawdzić, że ćwiczenie negatywne bez przywracania daje rozbieżność. |
| Dane | Wznowić permutację i kursor. | Porównać identyfikatory wpisów po przerwaniu. |
| Postęp | Zinterpretować kroki i epoki. | Osiągnąć łącznie 10 aktualizacji, bez powtarzania lub pomijania którejkolwiek. |
| Konfiguracja | Odtworzyć ten sam eksperyment. | Zachować wymiary, precyzję, ustawienia i wersje. |
Przywracać we właściwej kolejności
Odtwórz model, optymalizator i scheduler, zanim wczytasz ich stany. Scheduler musi zostać utworzony przed optimizer.load_state_dict(): jego konstrukcja może w przeciwnym razie nadpisać przywrócone współczynniki uczenia. Wczytaj także jego własny stan, a potem sprawdź współczynnik faktycznie użyty w następnym kroku.
Przywróć generatory liczb losowych po utworzeniu obiektów, które zużywają losowania, tuż przed kontynuowaniem pracy. Samo ponowne ustawienie początkowego ziarna rozpoczęłoby sekwencję od nowa; to nie to samo co odtworzenie stanu osiągniętego po piątej aktualizacji. W swoim projekcie zlokalizuj wszystkie używane generatory, w tym te od transformacji i wczytywania danych.
W tym ćwiczeniu Python ustawia niewielki wzrost na wejściach, generator NumPy PCG64 produkuje szum i permutacje, a PyTorch produkuje dropout. Checkpoint zachowuje ich stany osiągnięte w momencie przerwania. Weryfikator obserwuje też ich następne losowania, natychmiast przywracając stan, aby nie zakłócić dalszego obliczenia.
optimizer = torch.optim.Adam(model.parameters(), lr=0.03)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=3, gamma=0.5)
# W ścieżce wznowienia, po utworzeniu obiektów:
state = load_checkpoint(resume)
model.load_state_dict(state["model"])
scheduler.load_state_dict(state["scheduler"])
optimizer.load_state_dict(state["optimizer"])
progress = state["progress"]
history = state["history"]
restore_rng(state["rng"], generator)
model.train()Wybierz spójną granicę zapisu
Ustal wyraźną granicę, na przykład po pełnej aktualizacji optymalizatora. Jeśli akumulujesz kilka mikrobatchy przed tą aktualizacją, zapis w środku wymusza obsługę również stanu pośredniego. Pierwszą implementację łatwiej zweryfikować, gdy zapisuje na granicy, w której skumulowane gradienty zostały już zużyte.
Zachowaj kilka generacji kopii zapasowych. Zapisz nowy plik pod odrębną nazwą, poczekaj na zakończenie zapisu, sprawdź, czy jest czytelny, a następnie oznacz go jako użytkowy. Nie zastępuj swojego jedynego ważnego checkpointu przed tą kontrolą. Częstotliwość zależy od pracy, którą jesteś gotów wykonać ponownie, oraz od zaobserwowanego czasu zapisu; nie wynika wyłącznie z czasu wynajmu.
Mini-projekt wykonuje kopię zapasową po zakończonej iteracji, a następnie eksportuje plik i jego odcisk. Używa nowego folderu dla każdego przebiegu i nie zastępuje poprzedniego dowodu. Jeśli Twoje trenowanie korzysta z mieszanej precyzji z GradScaler, jego stan również jest częścią wznowienia. Ten wariant nie jest objęty ćwiczeniem CPU.
Odczytaj porównanie i jego tolerancję
Protokół porównuje kontynuację po punkcie 5: zużyte dane, tempo uczenia, straty i osiągnięte parametry. Zgodność samego numeru kroku nie wystarcza. Zresetowany optymalizator może kontynuować pętlę, generując jednocześnie inne aktualizacje.
Tolerancja wybrana dla tego ćwiczenia jest bezwzględna: 1e-12, z tolerancją względną 0. Ten próg jest częścią dostarczonego protokołu CPU; nie stanowi uniwersalnej reguły dla Twoich modeli. Porównanie musi sygnalizować wartości niefinitywne oraz różnice w strukturze, zamiast po cichu akceptować nieużyteczne dane wyjściowe.
PyTorch nie gwarantuje identyczności wyników między wersjami, platformami, CPU i GPU. Jeśli przenosisz to ćwiczenie, ponownie wykonaj dowód na docelowym środowisku i wyjaśnij przyjętą tolerancję. Nie poszerzaj progu tylko po to, by zniknął błąd, którego przyczyny nie rozumiesz.
W dostarczonym dowodzie wszystkie odchylenia pełnego przebiegu wynoszą zero: parametry, stan optymalizatora, straty, tempa i MSE. Kolejność wierszy, postęp, stan schedulera i kolejne losowania również się pokrywają. Następne tempo uczenia po kroku 10 wynosi 0,00375 w obu przebiegach. Wynik nie zależy więc wyłącznie od pojedynczej metryki końcowej, która mogłaby maskować różnice pośrednie.
Przewiń tabelę, aby zobaczyć wszystkie kolumny.| Porównanie | Pełne wznowienie | Wznowienie bez przywracania RNG |
|---|---|---|
| Maksymalne odchylenie wag | 0 | 0,011669328447718508 |
| Końcowa MSE | 0,09538858591775097 | 0,0936034144665111 |
| Odchylenie MSE względem ciągłego przebiegu | 0 | 0,001785171451239867 |
| Werdykt podtestu zgodności | Zgodny w tolerancji 1e-12 | Wykryto rozbieżność |
Dlaczego warto zachować przypadek negatywny bez przywróconego losowości
Kontrola jest bardziej użyteczna, gdy wiesz, jaki błąd wykrywa. Wariant negatywny ładuje te same wagi, stany optymalizatora, schedulera i postęp, ale celowo pomija przywracanie RNG. Proces może zakończyć się bez wyjątku Pythona, kontynuując jednocześnie inną trajektorię.
W dostarczonym dowodzie to pominięcie daje maksymalne odchylenie wag większe niż 0,011 oraz różnicę MSE większą niż 0,0017. Negatywna MSE jest tu niższa niż w ciągłym przebiegu: nie czyni to wznowienia poprawnym. Celem jest odtworzenie tego samego doświadczenia, a nie uszeregowanie dwóch modeli według ich błędu końcowego.
Weryfikator kończy się powodzeniem tylko wtedy, gdy pełny przebieg jest zgodny, a przypadek negatywny wykazuje rozbieżność. Wyświetla wówczas all_checks_passed: true, positive: true i negative_divergence_detected: true. Jego kod wyjścia wynosi 0 w przypadku powodzenia protokołu, 1 jeśli porównanie się nie powiedzie i 2 jeśli weryfikacji nie udało się ukończyć.
python -B train.py --steps 5 --resume runs/coupure/checkpoint.pt --omit-rng-restore --output runs/reprise-incompleteZaładuj plik ćwiczenia bez osłabiania zabezpieczeń
Projekt ładuje wyłącznie checkpoint, który utworzyłeś w tym ćwiczeniu i zachowałeś pod swoją kontrolą. Używa jawnie torch.load(..., map_location="cpu", weights_only=True). Stan Pythona zawiera prymitywy, stan generatora NumPy PCG64 liczby całkowite i łańcuchy znaków, a stan PyTorch CPU tensor bajtów. Żadna dowolna tablica NumPy nie jest umieszczana w zapisanym stanie RNG.
Loader sprawdza powiązany odcisk, rozmiar, schemat, postęp, wersje oraz tożsamość kodu i danych. Odrzuca niespójny stan zamiast po cichu resetować brakujący element. Odcisk wykrywa modyfikację; nie uwierzytelnia nadawcy pliku.
Nie dodawaj weights_only=False tylko po to, by uciszyć błąd ładowania. Zapisany format i jego rekonstrukcja muszą być spójne. Ograniczone ładowanie zmniejsza możliwości deserializacji, ale nie czyni nieznanego pliku godnym zaufania.
Co się zmienia przy treningu rozproszonym
Przy wielu procesach lub stanach rozdzielonych między GPU sprawdź, kto co zapisuje. Plik wytworzony przez pojedynczy proces nie musi być pełną kopią pracy rozproszonej. Użyj procedury tworzenia kopii przewidzianej w Twojej strategii i poczekaj na jej zakończenie u odpowiednich uczestników. Wyraźnie oznacz fragmenty należące do tego samego punktu wznowienia.
Zmiana liczby GPU może wymagać redystrybucji stanów i zmienić podział danych. Mechanizmy rozproszonego checkpointu mogą obsłużyć niektóre zmiany, ale tę możliwość trzeba zweryfikować dla Twojego formatu i konfiguracji. Wykonaj próbne ładowanie na docelowym środowisku. Dodanie partii do zamówienia nie zamienia automatycznie kopii jednokartowej w program rozproszony.
Zakończ realnie odzyskiwalnym eksportem
Przed upływem terminu wyeksportuj przydatne checkpointy wraz z konfiguracją, metrykami, instrukcjami ładowania i identyfikatorami danych. Sprawdź rozmiar i odcisk skopiowanych plików, a następnie wczytaj przynajmniej jedną kopię z jej miejsca docelowego. Ten sam odcisk kontroluje kopię; ponowne wczytanie weryfikuje, czy zawartość naprawdę wystarcza do odtworzenia pracy.
Wczytuj wyłącznie pliki o znanym pochodzeniu i wybierz format oraz opcje deserializacji odpowiednie do sytuacji. Zachowaj ostatni zatwierdzony punkt wznowienia, dopóki nowy nie przejdzie Twoich kontroli. Oczekiwany wynik to odzyskiwalny katalog i krótki dowód wznowienia: wykonana komenda, odnaleziony krok, udana kontrola i wyeksportowany wynik. Zaplanuj na to czas w swoich 3, 7 lub 30 dniach.
Zakres dowodu i wybór wynajmu
Dowód z 24 września 2026 porównuje cztery nowe procesy na CPU, z tolerancją bezwzględną 1e-12 i bez tolerancji względnej. Nie obejmuje CUDA, ROCm, AMP, treningu rozproszonego ani workerów ładowania danych. Potwierdza logikę wznowienia dostarczonej wersji, w opisanym środowisku, i nie mierzy możliwości wynajętego GPU.
Po tym małym ćwiczeniu przenieś ten sam protokół na swój model, swoje dane i swój backend. Karta 80 GB lub karta 192 GB nie naprawi niekompletnego checkpointu: najpierw wybierz kompatybilny łańcuch, a potem dobierz pamięć do rzeczywistego kroku. Oferty podlinkowane poniżej nie są przedstawiane jako sprzęt przetestowany na potrzeby tego dowodu.
Zaplanuj w swoim okresie 3, 7 lub 30 dni pierwszy cykl zapis–zatrzymanie–wznowienie oraz czas na końcowy eksport. Użytecznym wynikiem jest katalog, którego wersje, punkt wznowienia, kontrolę porównawczą i ograniczenia potrafisz wyjaśnić; samo istnienie pliku .pt nie daje takiej pewności.