Zestien Dagen Rekenkracht op Eén GPU
Eén Lange Run
ANDREA-120M duurt ~23 dagen op een RTX 4090 (FP16, 6 stappen/min, 200K stappen). Wandstroom, kernel panics, proxy crashes, & bewuste config-veranderingen gebeuren allemaal in dat tijdsvenster. Zonder checkpoints gooit één hapering de hele run weg.
v1 verloor 27K stappen door één fout (lr=0.001 te agressief) omdat geen checkpoint dichterbij zat dan het lanceerpunt. v2 nam die les op: checkpoint-frequentie daalde naar elke 100 stappen, & een CUDA signaalhandler garandeert een checkpoint-schrijf op SIGTERM.
Drie Rollen
Een checkpoint vervult drie taken tegelijk:
1. Herstelpunt. Proces crasht, machine herstart, kernel panic: hervat vanaf het nieuwste step_NNNNNN.bin.
2. Polish pivot. Stap 112.619: wijzig curriculum zonder hertraining. SIGUSR1 forceert een schoon checkpoint, proxy stopt, nieuwe caps & floors worden ingediend, CUDA hervat vanaf het opgeslagen punt onder een nieuw beleid.
3. Audit fork. Vergelijk twee configuraties bij dezelfde startgewichten: kopieer een checkpoint, voer twee divergerende takken vooruit, observeer welke convergeert.
Elke 100 stappen geeft ~17 minuten training tussen writes bij 6 stappen/min. 100 stappen komt ook overeen met sample_every: elke checkpoint komt overeen met één verse sample-audit, & elke sample-audit komt overeen met een herstelbaar punt.
Drie Rollen voor Één Bestand
Vijf Regio's in Één Bestand
Het Format
Elke step_NNNNNN.bin bevat vijf aaneengesloten gebieden:
[int32 step] [int32 n_params] [n_params x float32 weights] [n_params x float32 m] [n_params x float32 v]
Regio voor Regio
Kop (8 bytes totaal). Een 32-bit stapnummer vertelt ons waar in de training dit snapshot zich bevindt; een 32-bit parameteraantal vertelt ons hoe groot de drie daaropvolgende arrays elk zijn.
Gewichten (n_params x 4 bytes). Elke geleerde parameter, plat. Volgorde komt overeen met de parameteriterator van het model: token- en positieloggingen, dan per-laag attention- en MLP-gewichten, dan de outputkop.
Adam eerste moment m (n_params x 4 bytes). EMA van eerdere gradiënten (beta1 = 0.9). Dezelfde vorm als de gewichten. Vereist voor hervatting van AdamW.
Tweede moment van Adam v (n_params x 4 bytes). EMA van eerdere gekwadrateerde gradiënten (beta2 = 0.999). Dezelfde vorm als de gewichten. Vereist voor hervatting van AdamW.
Totale Grootte
Totale bytes = 8 + 12 x n_params. ANDREA-12M (12.8M params): 154 MB op schijf (147 MB afgerond). ANDREA-120M (~120M params) FP32: ~1.44 GB. Drie arrays van identieke vorm, achter elkaar gestapeld, met een kleine header.
Waarom m & v Opslaan
Vanilla Adam volgt per-parameter leerpercentages via m & v. Laat ze vallen bij checkpoint-schrijven & een hervatte run start met nul momentum & nul variantie-schatting, equivalent aan leerpercentage 0 voor één stap en dan een plotselinge ramp. Verlies piekt; het model kan uit zijn huidige bekken vallen. Het opslaan van m & v maakt hervatten bit-equivalent (modulo dataloader willekeur) aan de nooit-gestopte baseline.
Eén Checkpoint Formaten
SIGTERM & SIGUSR1
Waarom CUDA Signalen Afhandelt
Training draait als een langlevend voorgrondproces. Wanneer de proxy of operator wil dat de GPU stopt, wordt een signaal naar de CUDA-engine gestuurd. Zonder handler doodt een standaard SIGTERM het proces onmiddellijk: in-flight gradient computation weggegooid, nieuwste gewichten sinds de laatste checkpoint verloren. Met een handler schrijft de engine eerst een checkpoint en stopt dan netjes.
SIGTERM: schrijf & stop
Verstuurd door een stopknop, een systemctl stop, of een kill van een parent proxy. CUDA voltooit de huidige stap, schrijft step_NNNNNN.bin naar schijf, en stopt dan. Herstel uit deze toestand vereist alleen de nieuwste .bin: nul werk verloren behalve de gedeeltelijke stap in uitvoering.
SIGUSR1: schrijf & ga door
Op verzoek verstuurd door een operator of proxy-script. CUDA voltooit de huidige stap, schrijft step_NNNNNN.bin, en zet de training voort alsof er niets gebeurd is. Nuttig voor: activeren van een auditpunt vlak voor een config-wijziging; vastleggen van gewichten op een bekend-goed moment; uitlijnen van een checkpoint met een externe sample-kwaliteitsbeoordeling.
De Poolse Draaipuntvolgorde (stap 112,619)
1. Operator verstuurt SIGUSR1 naar CUDA. Checkpoint wordt geschreven bij de volgende 100-stapgrens (stap 112,700).
2. Operator stopt de proxy.
3. .samples.json & .state.json worden gearchiveerd (sample log & bandit status bewaard als historisch verslag).
4. .loss.json blijft op zijn plaats. Cumulatieve trainingsgeschiedenis; nooit gearchiveerd.
5. Proxy herstart met nieuwe caps & floors.
6. CUDA hervat vanaf step_112700.bin met een nieuwe bandit maar volledige weights, m, & v.
De loss-geschiedenis blijft ononderbroken doorgaan over de pivot heen. Sample log reset schoon. Bandit krijgt een frisse start onder nieuw beleid.
Het Signaal Kiezen
Cumulatieve Trainingsgeschiedenis
Drie Sidecar-bestanden
Naast elk checkpoint onderhoudt de proxy drie JSON-sidecars in de run-directory:
- .loss.json -- één entry per stap, altijd. ~200.000 entries aan het einde van de run. Cumulatieve trainingsgeschiedenis.
- .samples.json -- recente gegenereerde samples voor audit. Reset op polish-pivots.
- .state.json -- bandit arm pulls, EMA rewards, fase-tellers. Reset op polish-pivots.
Wat reset, wat blijft behouden
Poolschoonmaakdraaiingen zijn beleidswijzigingen, geen run-resets. De modelgewichten, m, v, & loss-geschiedenis blijven allemaal ononderbroken doorgaan. De opgebouwde beloningen van de bandit gaan NIET door: de nieuwe caps & floors definiëren een ander beleid, & de bandit moet onder het nieuwe beleid opnieuw leren vanaf een schone staat.
Waarom .loss.json Blijft
De loss-geschiedenis dient als de audit trail van de run. Elke gepubliceerde claim over ANDREA-120M (loss EMA op stap 110K, polish-pivot herstel, convergentie op stap 112K) traceert terug naar vermeldingen in dit bestand. Het archiveren van .loss.json tussen fasen zou lezers dwingen om fragmenten aan elkaar te naaien om de run te reconstrueren; het append-only & onaangeraakt houden behoudt de herkomst.
De Zombie Arm Les
Stap 112,619 vond een repo-docstrings arm in .state.json met gewicht 1.546 uit een eerdere run. De bandit-staat was bewaard gebleven over een eerdere herstart, maar de databron was niet meer beschikbaar, wat zombie pulls produceerde die de exploratie-accounting vervormden. Les: bandit-staat MAG wel op verrassende manieren afdwalen over herstarts heen. Loss-geschiedenis is het enige bestand dat onaangeraakt moet blijven voor de volledige levensduur van de run.
Eén Regel om Ze Allemaal te Besturen
Archiveer .samples.json & .state.json vrij tussen fasen. Archiveer nooit .loss.json. De nieuwste .loss.json is altijd de canonieke trainingsgeschiedenis.
De Regel Toepassen
Wat is gebouwd & waarom
Vijf Beslissingen
1. Cadans: elke 100 stappen. Granulariteit van herstelpunt ~17 minuten. Afgestemd op sample_every zodat elke checkpoint overeenkomt met één verse sample-audit.
2. Formaat: header + 3 arrays. Minimaal: 8-byte header vertelt ons hoe groot elk volgend array wordt. Geen metadata-bloat. Bit-equivalente hervatting wanneer m & v worden opgeslagen.
3. Signalen: SIGTERM & SIGUSR1. Twee rollen, twee signalen. Standaard systemd-afsluiting krijgt een schoon checkpoint via SIGTERM; op-aanvraag auditpunten krijgen een schoon checkpoint via SIGUSR1 zonder te stoppen.
4. Loss-continuïteit: nooit gearchiveerd. Cumulatieve trainingsgeschiedenis blijft bestaan over polish-pivots, herstarts & beleidswijzigingen heen. Eén auditspoor voor de hele run.
5. Bandit-staat: resets toegestaan. Bandit-beleid leeft onder één config tegelijk. Polish-pivots resetten; loss-geschiedenis gaat door. Twee verschillende levenscycli delen dezelfde run-directory.
Waar Deze Les Naar Verwijst
- Activiteit 23 (grow_a_language_model_sample_audit). sample_every cadence komt overeen met checkpoint cadence; beide activeren elke 100 stappen.
- Activiteit 24 (grow_a_language_model_microgpt_to_andrea). v1 collapse, v2.5 patch, v3 polish pivot vereisen allemaal schone checkpoints om te werken.
- Activiteit 10 (grow_a_language_model_adamw). Het opslaan van m & v in de checkpoint is belangrijk omdat de update-regel van AdamW afhankelijk is van beide. Laat ze weg & hervatten divergeert.
Eén Laatste Technische Waarheid
Code overleeft auteurs. Infrastructuur overleeft bouwers. Een eenvoudig checkpoint-formaat overleeft elk ingewikkeld hervattingsplan dat beloofde de optimizer-staat over te slaan. Sla de bytes op; sla de run op.