GPU per i tuoi progetti · pagamento crypto senza KYC Come noleggiare
Italiano
Apri la console
Guida pratica / KERNODECK

Passare alla precisione mista senza perdere il controllo numerico

Stabilisci una baseline in precisione abituale, attiva autocast sul calcolo in avanti e sulla loss, poi confronta output, gradienti e qualità sugli stessi input. In addestramento FP16, GradScaler aiuta a gestire gradienti di piccola ampiezza; non rende compatibile qualsiasi modello. BF16 ha un comportamento numerico diverso. Mantieni un criterio esplicito di rollback prima di cercare un guadagno di memoria o di velocità.

7 min di lettura · Guida per sviluppatori

Iniziare da una baseline che risponde al bisogno

Scegli un set breve con input ordinari, casi limite e frontiere di decisione. Fissa modello, pesi, pretrattamento e modalità train o eval. Un confronto tra due modelli o due batch non permette di attribuire la loro differenza alla precisione.

Registra l'output utile alla tua applicazione, non solo la loss. Per un classificatore, questo può includere score e decisioni; per una regressione, errore e valori estremi. Verifica già la presenza di NaN o inf nella baseline. Un'esecuzione FP32 scorretta non diventa una base affidabile solo perché ha più bit.

Fissa tolleranza, qualità minima e assenza di non finiti prima della prova. PyTorch ricorda che il calcolo in virgola mobile non garantisce risultati identici tra dispositivi o percorsi di esecuzione.

Distinguere autocast, formato numerico e GradScaler

autocast sceglie il tipo di alcune operazioni in base alla loro politica di calcolo. Non trasforma l'intero programma in un formato unico. Con questo utilizzo, evita di convertire manualmente tutto il modello con half(). La documentazione attuale consiglia torch.autocast o torch.amp.autocast; le vecchie interfacce torch.cuda.amp sono deprecate.

GradScaler agisce sulla scala della loss e dei gradienti durante l'addestramento. Non si usa come acceleratore dell'inferenza, che non esegue il backward. FP16 ha un intervallo numerico più ristretto di BF16; un modello progettato per BF16 può andare in overflow in FP16. Una diminuzione ripetuta della scala non dimostra quindi che il problema sia risolto.

Scegli il formato partendo dai vincoli del modello e dalle operazioni realmente utilizzate, poi verifica il supporto della destinazione. Il nome commerciale di una scheda o una preferenza di preparazione PyTorch non prova che il tuo operatore personalizzato disponga del kernel desiderato.

Scorri la tabella per leggere tutte le colonne.
Decisioni di precisione da validare sul progetto
SceltaRuoloControllo necessario
Riferimento FP32Punto di confronto del progettoOutput finiti e qualità attesa
Autocast FP16Alcune operazioni in precisione ridottaIntervallo numerico e gradienti
Autocast BF16Altra combinazione intervallo/precisioneOperatori disponibili e qualità
GradScalerGestione della scala dei gradientiAggiornamenti effettivamente eseguiti

Mettere le fasi dell'addestramento nell'ordine giusto

Il frammento proposto presuppone un modello e un optimizer già costruiti, un input e un target sulla stessa GPU e una loss scalare. Non è stato eseguito e non costituisce una validazione di un'offerta. Il contesto autocast racchiude il forward e la loss; il backward avviene dopo la sua chiusura. Lo scaler viene creato una volta per la sessione di addestramento, non a ogni batch.

Per ispezionare o clippare i gradienti, rimuovi prima il loro fattore di scala con unscale_. Gli esempi AMP ufficiali precisano di farlo una sola volta per optimizer e dopo l'accumulo dei gradienti destinati al suo aggiornamento. La soglia di clipping 1.0 qui sotto è un valore illustrativo da scegliere per il tuo progetto, non una raccomandazione universale.

Le guardie interrompono qui la diagnosi se loss, gradienti o norma totale non sono finiti. Queste letture su CPU sono intrusive: non cronometrare questo frammento. Accumulo, optimizer multipli e scheduler richiedono una propria definizione dell'aggiornamento.

Sequenza AMP didattica su GPU, non eseguita
import torch

# Precondizioni: model, optimizer, loss_fn, inputs e targets esistono.
# Il modello e gli input sono sullo stesso dispositivo CUDA/HIP.
dtype = torch.float16  # Scelta da validare; BF16 è un'altra prova.
scaler = torch.amp.GradScaler("cuda", enabled=(dtype == torch.float16))

# Da inserire nel tuo ciclo, con scaler mantenuto tra i batch.
optimizer.zero_grad(set_to_none=True)
with torch.autocast(device_type="cuda", dtype=dtype):
    prediction = model(inputs)
    loss = loss_fn(prediction, targets)
if not bool(torch.isfinite(loss).item()):
    raise FloatingPointError("Loss non finita: interrompere la diagnosi")
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
if any(p.grad is not None and
       not bool(torch.isfinite(p.grad).all().item())
       for p in model.parameters()):
    raise FloatingPointError("Gradiente non finito: interrompere la diagnosi")
torch.nn.utils.clip_grad_norm_(
    model.parameters(), max_norm=1.0, error_if_nonfinite=True,
)
scaler.step(optimizer)
scaler.update()

Esempio svolto: due decisioni vicine non sono intercambiabili

Supponiamo un servizio che sceglie la classe con il punteggio massimo. Su un input didattico, il riferimento produce due punteggi molto vicini: 1,0000 e 1,0003. Un altro percorso numerico potrebbe modificarne l'ordine o creare un pareggio. Questi numeri illustrano una frontiera decisionale; non sono output misurati di FP16 o BF16.

La verifica corretta comporta due livelli. Confronta i punteggi con tolleranze esplicite, poi confronta la decisione e la regola applicata ai pareggi. Una differenza piccola in valore assoluto può cambiare l'azione scelta. Al contrario, una differenza numerica visibile può restare senza conseguenze per un'attività la cui soglia è lontana dai punteggi osservati.

Registra identificatori, output di riferimento, test AMP e impatto sulla decisione. Stabilisci la regola di accettazione prima di leggere i risultati. Non ampliare la tolleranza per far sparire un caso scomodo; output di scale diverse possono richiedere criteri distinti.

Scorri la tabella per leggere tutte le colonne.
Scheda didattica di confronto, da completare con le misurazioni
CriterioRiferimentoTest AMPDecisione
Output finitiDa verificareDa verificareRifiutare i non finiti ingiustificati
Scostamento numericoValori conservatiScostamento da calcolareTolleranza definita prima del test
Decisione applicativaClasse o azioneClasse o azioneEsaminare le modifiche
Qualità sul set fissoDa misurareDa misurareRispettare la soglia del progetto

Interpretare i NaN e gli aggiornamenti saltati

Quando compaiono dei non finiti, cerca la prima fase che li produce: input, output intermedio, perdita o gradiente. Riproduci lo stesso caso in riferimento, poi disattiva localmente autocast attorno all'operazione sospetta controllando anche il tipo dei suoi input. Riportare un intero addestramento in FP32 può servire da confronto, ma non individua automaticamente il problema.

Lo scaler può evitare un aggiornamento quando i gradienti contengono inf o NaN. Un ciclo che continua non ha quindi necessariamente effettuato tanti aggiornamenti quante iterazioni. Registra questo comportamento durante la diagnosi. Non far progredire ciecamente una politica di apprendimento che si presume segua gli aggiornamenti effettivi.

Una perdita finita non garantisce gradienti finiti. Al contrario, un incidente sporadico non basta a dichiarare un addestramento inutilizzabile: esamina la frequenza, la progressione e la qualità. La ricetta AMP fornisce un metodo per isolare separatamente autocast e lo scaling quando uno dei due è sospetto.

Preparare un rollback riproducibile

Prima del test, conserva la configurazione di riferimento, i pesi, lo stato dell'ottimizzatore e un checkpoint coerente. Se il tuo addestramento usa uno scaler, anche il suo stato fa parte della ripresa. Documenta il dtype ed eventuali regioni lasciate in FP32. Riprendere con una politica diversa è una modifica sperimentale da identificare, non una continuazione implicitamente equivalente.

Torna alla configurazione precedente se gli output diventano non finiti, se la qualità esce dal criterio stabilito o se gli aggiornamenti smettono di avanzare in modo utilizzabile. Conserva il caso che ha motivato questo ritorno. Dopo una modifica, ricomincia il confronto sullo stesso set prima di estendere la durata.

L'esercizio Kernodeck sui checkpoint verifica una ripresa CPU senza AMP. Riutilizza il suo metodo di confronto aggiungendo gli stati realmente consumati dal tuo ciclo.

Misurare i guadagni solo dopo la convalida numerica

Dopo la convalida, misura memoria e tempo senza la diagnosi dettagliata. Mantieni forme, batch, modello e qualità. Le letture di scalari, le sincronizzazioni e i profiler possono modificare le durate; rimuovi i controlli intrusivi dalla misurazione finale.

Su ROCm, il nome del dispositivo PyTorch resta cuda e le interfacce corrispondenti vengono riutilizzate. Ciò non garantisce né gli stessi kernel né risultati identici a NVIDIA. Verifica il backend e gli operatori del progetto sulla destinazione. Questa guida non annuncia alcuna riduzione fissa di memoria, moltiplicazione di velocità o compatibilità di preparazione Kernodeck.

Le tue domande

AMP significa che tutti i tensori passano in FP16?

No. autocast applica una politica per operazione. Alcune operazioni restano in una precisione diversa. Convertire manualmente tutto il modello con half() non equivale a usare autocast e può modificare le condizioni di stabilità.

BF16 sostituisce sempre FP16 vantaggiosamente?

No. I due formati hanno compromessi diversi, e il loro supporto dipende dalle operazioni e dall'ambiente. Confronta qualità e costo sul tuo carico di lavoro; la gamma più ampia di BF16 non garantisce da sola la precisione richiesta.

GradScaler è necessario per un'inferenza?

Lo scaler interviene nell'addestramento con gradienti, non in un'inferenza senza backward. Per quest'ultima, controlla piuttosto gli output e la qualità sotto autocast, mantenendo la modalità di valutazione prevista.

Una perdita finita basta ad accettare AMP?

No. Controlla anche i gradienti, gli aggiornamenti, la qualità e le decisioni dell'applicazione. Una piccola differenza numerica può essere decisiva vicino a una soglia; un addestramento che continua può anche saltare alcuni aggiornamenti.