di Steven Chen, Feng Wang, Bhavik Soni, Chengguang Yang, Albert Zhong, Naren Loganathan, Harsh Panchal e Jianwei Xie
L'addestramento distribuito su GPU è ormai diventato una prassi comune in tutto il settore. Oggi i team addestrano foundation model, eseguono il fine-tuning di modelli su scala di frontiera, creano grandi sistemi di computer vision e gestiscono reti di raccomandazione profonde a livelli di scalabilità che un tempo erano riservati esclusivamente ai laboratori di ricerca più avanzati.
La creazione di un'infrastruttura GPU in grado di soddisfare la scalabilità odierna richiede un'attenzione meticolosa a molti aspetti: rilevare i guasti che interrompono un'esecuzione, far emergere i lenti deterioramenti che non si manifestano chiaramente, convalidare l'integrità del fabric su migliaia di collegamenti, pianificare le attività aggirando l'hardware destinato a guastarsi e ripristinare il sistema in modo pulito quando ciò accade. Molti di questi aspetti sono fondamentali e i problemi più complessi che si presentano ai livelli superiori dello stack dipendono proprio da essi.
In Databricks AI, eseguiamo carichi di lavoro di addestramento su scala massiva ogni settimana, riscontrando continuamente guasti a livello di hardware, fabric e software. Questa serie illustra ciò che serve per mantenere l'affidabilità delle GPU a questa scala, partendo dalle fondamenta in questo primo post: le modalità di guasto che si riscontrano durante l'esecuzione delle GPU, i diversi carichi di lavoro che le fanno emergere e il sistema di controlli di integrità (health check) a più fasi che le rileva. L'addestramento è la classe di carico di lavoro più esigente ed è il tema centrale di questo articolo, anche se lo stesso approccio ingegneristico supporta l'inferenza e altri carichi di lavoro GPU in Databricks.
La maggior parte dei guasti delle GPU su larga scala rientra in tre categorie: crash dei job, rallentamenti silenziosi e corruzione numerica. I crash dei job rappresentano il caso più semplice, nel senso che ci si accorge immediatamente del problema. I guasti più difficili da gestire riguardano i carichi di lavoro che si completano con valori errati nel modello o che vengono eseguiti con prestazioni ridotte per ore senza che nessuno se ne accorga.
Crash dei job. I job di addestramento distribuito subiscono crash per molti motivi: una GPU che si deteriora o si disconnette dal bus, problemi al fabric RDMA, un blocco del sistema di I/O, un rank lato CPU che diverge dagli altri. Dal punto di vista del carico di lavoro, quasi tutti questi problemi si manifestano nello stesso modo: il crash del job con il temuto messaggio di NCCL watchdog timeout nei log. Ogni rank si blocca sulla stessa operazione collettiva, il watchdog alla fine interrompe il job e si riparte dall'ultimo checkpoint. Tuttavia, il timeout in sé non dice quasi nulla sulla causa radice. Diagnosticare cosa sia andato storto significa spesso tracciare i problemi tra i livelli di hardware, fabric, filesystem e software a partire da uno stack trace che mostra solo il sintomo.
Rallentamenti silenziosi. Una GPU deteriorata in modo silenzioso può continuare a far progredire l'addestramento, con log apparentemente normali e una perdita (loss) che continua a diminuire. Tuttavia, il throughput è limitato dalla GPU più lenta, con conseguente spreco di risorse di calcolo e budget. Questi rallentamenti derivano da hardware che opera in uno stato degradato, in cui i sensori termici si attivano sotto carico prolungato, i collegamenti di interconnessione subiscono un downgrade a causa di errori persistenti o la larghezza di banda della memoria si riduce con l'accumularsi dei guasti. Ciascuno di essi si manifesta attraverso diversi segnali a livello hardware, ad esempio i motivi di limitazione (throttle) di DCGM come HW_SLOWDOWN o HW_THERMAL_SLOWDOWN per i problemi termici, o l'integrità dei collegamenti per le interconnessioni.
Corruzione numerica. Le GPU moderne utilizzano l'Error Correction Code (ECC) per rilevare e correggere automaticamente molti guasti temporanei della memoria senza interrompere l'addestramento. Tuttavia, non tutti i guasti possono essere ripristinati. La corruzione può avere origine nella memoria, nelle interconnessioni, nei kernel o nei livelli software e può propagarsi prima di essere rilevata o contenuta. In questi casi, l'addestramento può interrompersi immediatamente o proseguire con valori errati. I guasti possono manifestarsi come perdite (loss) NaN, convergenza instabile o regressioni della qualità del modello che vengono scoperte solo in un secondo momento.
I tassi di eventi di guasto dell'hardware GPU possono essere superiori di un ordine di grandezza rispetto a quelli delle CPU. Come stima approssimativa e prudente, ipotizziamo che ogni GPU abbia un tasso annuo di eventi di guasto dell'1%. Per un job che utilizza N GPU per T giorni, la probabilità che si verifichi almeno un evento è approssimativamente:
Un job con 256 GPU in esecuzione per 30 giorni ha circa il 19% di probabilità di subire un guasto. Con 1.024 GPU, questa percentuale sale al 57%. A questa scala, i guasti durante un'esecuzione sono la norma, non l'eccezione. Come base di partenza, due investimenti ingegneristici garantiscono l'affidabilità dell'addestramento nonostante questi problemi: stress test con carichi di lavoro diversi e all'avanguardia che fanno emergere i guasti tempestivamente, e un sistema di controlli di integrità (health check) a più fasi che li rileva in tutta la flotta.
Databricks AI esegue una serie di carichi di lavoro di addestramento impegnativi sulla stessa piattaforma utilizzata dai clienti: addestramento tramite reinforcement learning per modelli come KARL, modelli di codifica agentici, sistemi di document intelligence come quello alla base di PDF in produzione e altro ancora. Non si tratta di tipici job di addestramento. I carichi di lavoro RL combinano addestramento, inferenza e calcolo delle ricompense in cicli stretti su molte GPU. I modelli di codifica agentici eseguono valutazioni ad alta intensità di inferenza parallelamente all'addestramento. Le pipeline di document intelligence combinano l'addestramento dei modelli con un pesante caricamento di dati basati su immagini.
Ognuno di essi sollecita la piattaforma in modi diversi, il che li rende efficaci nel far emergere problemi operativi come l'instabilità del fabric, hotspot termici e casi limite nella comunicazione collettiva prima che questi influiscano sui carichi di lavoro di produzione più ampi.

Ecco come si presentava un problema recente. Un'esecuzione di addestramento si è interrotta con un timeout NCCL dopo sette ore dall'inizio. L'analisi ha mostrato che una singola porta InfiniBand utilizzata per le operazioni collettive NCCL RDMA era andata offline una volta per poi riattivarsi. Non si sono verificati altri fenomeni di flapping. I nostri controlli di integrità continui monitorano il flapping delle porte IB, ma un singolo evento isolato di flapping normalmente non indica una porta non integra, quindi non avrebbe superato la soglia da solo.
Il crash è dipeso da quale dei due timeout NCCL si è attivato per primo. La maggior parte delle discussioni sulla configurazione di NCCL si concentra sul timeout del watchdog NCCL di PyTorch, configurabile tramite init_process_group(timeout=...), che interrompe un'operazione collettiva bloccata dopo una durata configurabile (in genere 10 minuti). Un secondo timeout si trova più in basso nello stack e si attiva molto prima: NCCL_IB_TIMEOUT, a livello di trasporto InfiniBand, controlla per quanto tempo una connessione attende il ripristino di una porta offline prima di interrompere la connessione stessa. Il suo valore predefinito effettivo è di circa sette secondi, tenendo conto dei tentativi di ripristino, un tempo molto più breve di quanto la maggior parte dei team immagini. Una volta che una singola finestra di inattività della porta supera tale limite, la connessione viene persa e l'operazione collettiva è già compromessa, indipendentemente da come è impostato il timeout del watchdog di PyTorch. Nel momento in cui il watchdog rileva il blocco, il crash dell'esecuzione è ormai inevitabile.
Il segnale cruciale per l'impatto sull'addestramento è il tempo di inattività cumulativo, non il numero di flap. Un singolo flap sufficientemente lungo può causare il crash di un'esecuzione di addestramento di più giorni, proprio come i flap ripetuti nell'arco di diverse ore. Abbiamo ottimizzato i nostri valori predefiniti di NCCL_IB_TIMEOUT per renderli più resilienti, e lo stesso segnale di porta offline ci consente di interrompere e riavviare il job da un checkpoint senza lasciare le GPU inattive in attesa dell'attivazione del watchdog. Questa indagine è una delle tante che alimentano il sistema di controlli di integrità descritto nel resto di questo post.
Abbiamo sviluppato gpu-monitor como servizio di osservabilità e controllo dell'integrità a più fasi che viene eseguito su ogni nodo GPU, coprendo l'intero ciclo di vita del nodo. Diverse categorie di controlli vengono eseguite in fasi differenti, poiché diverse modalità di guasto sono rilevabili solo in determinate condizioni.

I controlli di bootstrap attivi vengono eseguiti quando un nodo viene allocato per la prima volta e successivamente ogni volta che viene ripulito tra i carichi di lavoro dei clienti. Ogni carico di lavoro si avvia su un nodo che ha appena superato l'intera suite di controlli. Questi controlli rilevano guasti deterministici, ovvero problemi che possono essere fatti emergere in modo affidabile da un test mirato preliminare. Ecco un campione rappresentativo di ciò che viene eseguito da gpu-monitor:
Un nodo che non supera un controllo attivo viene immediatamente rimosso dalla flotta prima che vi venga eseguito qualsiasi carico di lavoro. I nodi difettosi vengono messi in quarantena, quindi sottoposti a ripristini e test approfonditi prima di tornare nella flotta o essere rimossi in modo permanente.
I controlli continui passivi monitorano le modalità di guasto non deterministiche descritte nelle sezioni precedenti, ovvero i guasti che emergono solo sotto una pressione prolungata del carico di lavoro. Per questi, gpu-monitor esegue un secondo livello di controlli su ogni nodo attivo, come ad esempio:
HW_SLOWDOWN, HW_THERMAL_SLOWDOWN, HW_POWER_BRAKE)I nodi che mostrano errori nei controlli continui vengono isolati, svuotati e sottoposti allo stesso processo di quarantena dei fallimenti dei controlli di bootstrap attivi.
I controlli attivi multi-nodo periodici convalidano il comportamento del fabric inter-nodo che nessun singolo nodo può rilevare da solo. Vengono eseguiti periodicamente sui nodi inattivi tra i carichi di lavoro dei clienti per isolare i problemi del fabric inter-nodo dal degrado del singolo nodo, che viene già rilevato dal livello di bootstrap. Poiché questi controlli vengono eseguiti su nodi inattivi e possono essere interrotti quando i carichi di lavoro dei clienti richiedono i nodi, possono essere più onerosi rispetto a quanto consentito da un controllo attivo in fase di provisioning.
I test stessi includono sonde di larghezza di banda collettiva NCCL tra gruppi di nodi, analizzando dimensioni di payload da 8 byte a 2 GiB. Le diverse dimensioni dei payload sono importanti perché NCCL attiva percorsi di codice differenti. I messaggi di piccole dimensioni nell'ordine dei KB passano attraverso protocolli a bassa latenza come LL e LL128 e sono dominati dalla latenza, rendendo la latenza p95 il criterio di superamento utile. I messaggi medi nell'ordine dei MB superano le soglie in cui NCCL passa dagli algoritmi ad albero (tree) a quelli ad anello (ring). I messaggi di grandi dimensioni mettono alla prova il chunking e il pipelining al raggiungimento dei limiti di larghezza di banda, rendendo la BusBW (larghezza di banda del bus) il criterio di superamento utile. I problemi hardware spesso emergono in uno solo di questi percorsi di codice. Ecco un output rappresentativo delle condizioni che verifichiamo per la larghezza di banda all-reduce nel nostro controllo dello stato (health check):
| Dimensione del payload | Latenza p50 | Latenza p95 | AlgBW | BusBW | Criterio di superamento |
|---|---|---|---|---|---|
| 1 KB | 118 µs | 120 µs | 0.009 GB/s | 0.016 GB/s | Superato se la latenza p95 è ≤ 250 µs. |
| 1 MB | 288 µs | 319 µs | 3.64 GB/s | 6.82 GB/s | Superato se la latenza p95 è ≤ 500 µs. |
| 16 MB | 398 µs | 408 µs | 42.2 GB/s | 79.1 GB/s | Superato se BusBW è ≥ 50 GB/s e la latenza p95 è ≤ 750 µs. |
| 128 MB | 1.18 ms | 1.20 ms | 114 GB/s | 213 GB/s | Superato se BusBW è ≥ 150 GB/s. |
| 256 MB | 1.68 ms | 1.70 ms | 160 GB/s | 299 GB/s | Superato se BusBW è ≥ 225 GB/s. |
| 1 GB | 6.39 ms | 6.50 ms | 168 GB/s | 315 GB/s | Superato se BusBW è ≥ 250 GB/s. |
| 2 GB | 9.05 ms | 9.07 ms | 237 GB/s | 445 GB/s | Superato se BusBW è ≥ 350 GB/s. |
La AlgBW (larghezza di banda dell'algoritmo) misura il throughput così come viene visto dal carico di lavoro. La BusBW (larghezza di banda del bus) tiene conto del fatto che un'operazione collettiva come all-reduce sposta ogni byte attraverso il fabric più volte, riflettendo quindi meglio l'effettivo utilizzo del collegamento e lo stato dell'hardware.
Insieme, i tre livelli verificano l'hardware prima dell'avvio dei carichi di lavoro, lo monitorano durante l'esecuzione e convalidano il fabric più ampio nei periodi intermedi. Man mano che emergono nuove modalità di guasto, integriamo nuovi controlli dello stato e distribuiamo gpu-monitor all'intera flotta.
L'affidabilità delle GPU è un sistema cumulativo. Le nuove generazioni di hardware e i modelli di carico di lavoro continuano a far emergere modalità di guasto che devono essere integrate nuovamente nei controlli, e ognuna di esse rende il sistema più forte. Questo post ha trattato le fondamenta su cui poggia tutto il resto. I prossimi post di questa serie partiranno da qui per analizzare il lavoro che mantiene affidabile l'addestramento man mano che le esecuzioni diventano più grandi, le architetture cambiano e i carichi di lavoro di RL combinano addestramento e inferenza nello stesso ciclo.
Un'infrastruttura GPU affidabile su questa scala è ciò che rende possibile la prossima generazione di prodotti di IA. Se l'affidabilità delle GPU su larga scala è il tipo di problema su cui desideri lavorare, stiamo assumendo!
(Questo post sul blog è stato tradotto utilizzando strumenti basati sull'intelligenza artificiale) Post originale
Iscriviti al nostro blog e ricevi gli ultimi articoli direttamente nella tua casella di posta.