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

Profilare un passo PyTorch per capire dove va il tempo

Definisci prima il passo da osservare, separa caricamento, trasferimento, calcolo e aggiornamento, poi cattura una breve finestra rappresentativa con torch.profiler. Leggi insieme la cronologia CPU e le attività GPU disponibili. Un tempo di lancio Python non è il tempo di esecuzione completato sull'acceleratore, e una traccia strumentata non costituisce di per sé un benchmark.

7 min di lettura · Guida per sviluppatori

Scegliere una domanda prima di aprire una traccia

Una traccia risponde meglio a una domanda precisa: il calcolo attende i dati, una copia viene ripetuta o un piccolo operatore viene chiamato troppo spesso? Definisci input, output e confini del tuo passo. Per l'addestramento, specifica se include backward, aggiornamento dell'ottimizzatore e lettura del batch. Per l'inferenza, separa caricamento del modello e richiesta.

Mantieni uno scenario breve di cui conosci la correttezza. Annota forme, batch, precisione, modalità del modello, eventuale compilazione e origine dei dati. Un input semplificato può aiutare a isolare un comportamento, ma non rappresenta più necessariamente il carico completo. Menziona questa differenza nel rilevamento.

Fissa l'unità finale: millisecondi per passo o esempi elaborati al secondo. Le somme degli eventi non sostituiscono il tempo trascorso. Confronta finestre con gli stessi confini di lettura e trasferimento.

Distinguere tempo CPU, lavoro GPU e attesa

La CPU prepara e lancia le operazioni; la GPU può eseguirle più tardi. Un intervallo Python può quindi contenere lancio, attesa o entrambi. La documentazione CUDA di PyTorch indica che le misurazioni precise devono tenere conto di questo asincronismo, in particolare tramite sincronizzazione o eventi adatti al perimetro.

Per una misura mirata della durata GPU, gli eventi CUDA possono essere adatti. Per una latenza end-to-end, attendi la fine del lavoro compreso in questa latenza e misura l'intera richiesta. Non mescolare queste due unità. Una sincronizzazione aggiunta tra ogni operazione può eliminare una sovrapposizione reale e trasformare il programma che cerchi di comprendere.

Nel profiler, i tempi propri di un operatore e i suoi tempi che includono sotto-operazioni rispondono anch'essi a domande diverse. Guarda la cronologia prima di sommare le righe della tabella. Attività simultanee o annidate non rappresentano porzioni di tempo trascorso disgiunte.

Riservare una fase di avvio e una finestra attiva

Il primo passaggio può includere inizializzazione, caricamento o compilazione. Decidi se la tua domanda riguarda questo avvio o una fase già stabilizzata. Conserva entrambe le osservazioni quando contano per l'uso, invece di cancellare il costo iniziale con una media presentata come globale.

La funzione schedule permette di distinguere attesa, preparazione della raccolta e finestra attiva. Il riscaldamento del profiler non è una prova che il tuo modello abbia raggiunto il regime stabile. Verifica anche le forme incontrate e lo stato delle cache. Un'applicazione con input variabili può incontrare nuovi percorsi dopo diverse iterazioni.

Il planning didattico proposto più sotto attende un passo, ne prepara uno e ne cattura due. Quattro passi bastano a spiegare il meccanismo, non a stabilire una distribuzione delle prestazioni. In una vera campagna, scegli una finestra giustificata e ripeti la misura fuori dal profiler dopo l'analisi.

Esempio proposto: quattro passi con confini leggibili

Il frammento seguente non è stato eseguito. Presuppone che model, optimizer, loss_fn, loader e device esistano, che il modello sia su device e che il loader fornisca almeno quattro batch di coppie x, y. Esegue aggiornamenti: usa uno stato sperimentale previsto per questo, non una sessione di cui devi preservare i pesi.

Le etichette separano lettura CPU, trasferimento e addestramento. L'iteratore viene creato prima della finestra, il che esclude una parte del suo avvio dal perimetro. Il file viene scelto nuovo per evitare di sovrascrivere una traccia. L'esempio rifiuta una raccolta GPU non disponibile invece di presentare di nascosto una traccia CPU come analisi GPU.

Il segnale step() avanza la pianificazione dopo ogni passo. La ricetta ufficiale descrive questo legame tra iterazioni e raccolta. Su una pila ROCm, il dispositivo PyTorch resta denominato cuda; la disponibilità della raccolta acceleratore dipende comunque dal build e dai suoi strumenti. Verifica le attività effettivamente presenti nel risultato.

Cattura didattica di una breve finestra, non eseguita
from pathlib import Path
import torch
from torch.profiler import (
    profile, schedule, record_function,
    ProfilerActivity, supported_activities,
)

trace = Path("trace-etape.json")
if trace.exists():
    raise FileExistsError("Choisissez un nouveau nom de trace")
activities = [ProfilerActivity.CPU]
if device.type == "cuda":
    if ProfilerActivity.CUDA not in supported_activities():
        raise RuntimeError("Collecte GPU indisponible dans ce build")
    activities.append(ProfilerActivity.CUDA)
iterator = iter(loader)
model.train()

with profile(
    activities=activities,
    schedule=schedule(wait=1, warmup=1, active=2, repeat=1),
    record_shapes=False, profile_memory=False, with_stack=False,
    on_trace_ready=lambda p: p.export_chrome_trace(str(trace)),
) as prof:
    for _ in range(4):
        with record_function("lecture_batch_cpu"):
            x, y = next(iterator)
        with record_function("transfert"):
            x, y = x.to(device), y.to(device)
        with record_function("entrainement"):
            optimizer.zero_grad(set_to_none=True)
            loss = loss_fn(model(x), y)
            loss.backward()
            optimizer.step()
        prof.step()
print(prof.key_averages().table(
    sort_by="self_cpu_time_total", row_limit=8,
))

Trasformare un'osservazione in un'ipotesi verificabile

Inizia dalla finestra attiva e verifica che compaiano le etichette attese. Esamina poi gli spazi tra le attività, le copie e le ripetizioni. Un'attesa lunga in lecture_batch_cpu orienta verso la pipeline di input; non misura direttamente lo storage. Una copia frequente invita a esaminare il posizionamento dei tensori, senza provare che sia inutile.

Formula una sola ipotesi e poi proponi una modifica controllata. Per esempio, se una costante viene ricostruita e trasferita a ogni passo, verifica se la sua durata di vita può coprire più passi senza cambiare il risultato. Se un operatore sembra dominante, ispeziona le sue forme e il numero di chiamate prima di cercarne un sostituto.

Le righe seguenti sono letture possibili, non constatazioni tratte da una traccia eseguita. Non viene annunciata alcuna durata né accelerazione. La conclusione utile è un esperimento successivo che possa confermare o confutare la causa proposta.

Scorri la tabella per leggere tutte le colonne.
Interpretazioni didattiche da verificare nella tua traccia
Osservazione possibileIpotesiControllo successivo
GPU senza attività durante la letturaLa pipeline di input non segueStesso calcolo con batch già preparato
Copie ricorrenti di una costantePosizionamento o durata di vita inadeguatiSpostare una volta, verificare le uscite
Numerosi lanci piccoliLavoro frammentatoEsaminare raggruppamento e costo complessivo
Un operatore lungoForma o algoritmo determinantiConfrontare lo stesso operatore e i suoi input

Limitare il costo e le informazioni della strumentazione

Inizia con una raccolta breve e poche opzioni. Attiva forme, pile o memoria solo se una domanda lo richiede. L'API PyTorch precisa che queste informazioni aggiungono un costo; la raccolta delle forme può persino trattenere riferimenti ai tensori. Un profilo dettagliato può quindi cambiare le durate o l'occupazione di memoria del programma.

Una traccia può contenere nomi di operatori, forme e, a seconda delle opzioni, percorsi di codice. Ispezionala prima di condividerla. Un'etichetta di zona deve descrivere la fase senza includere email, token, percorsi privati o contenuti di input. Scegli un visualizzatore di tracce adatto al tuo ambiente e mantieni la raccolta sotto il tuo controllo.

Se gli eventi GPU attesi sono assenti, non riempire i loro tempi con zero. Indica che non sono stati osservati ed esamina il supporto della raccolta. Un'assenza di eventi nello strumento non è una prova di assenza di calcolo.

Convalidare l'ottimizzazione al di fuori del profiler

Ripartirai dallo stesso stato pertinente e confronterai la correttezza prima e dopo la modifica. Per l'addestramento, un passaggio aggiuntivo cambia i pesi; due catture avviate in successione non costituiscono necessariamente un confronto equivalente. Conserva codice, parametri e punto di partenza per poter spiegare la differenza.

Misura poi lo scenario senza raccolta dettagliata, con lo stesso riscaldamento e più passaggi. Riporta il perimetro, i valori grezzi e la loro dispersione. Un miglioramento locale può sparire nel ciclo completo o degradare la qualità: entrambi devono restare nella decisione.

Usa infine le osservazioni per precisare le risorse realmente necessarie. Una traccia della tua macchina non classifica le offerte Kernodeck e non prova né il processore host né la rete di un server noleggiato. Il confronto di GPU richiede un carico, condizioni e risultati comparabili sulle risorse interessate.

Le tue domande

Il tempo CPU più elevato indica l'operatore GPU più lento?

No. Può includere lancio, elaborazione lato host o attesa. Guarda gli eventi GPU e la loro cronologia quando la raccolta li fornisce. La tabella ordinata per tempo CPU risponde solo a questa prospettiva.

Devo sommare tutti i tempi CUDA della tabella?

No, non per ottenere automaticamente la durata totale. Le attività possono sovrapporsi e gli eventi possono essere annidati. Definisci una finestra di tempo trascorso e usa la traccia per spiegarne il contenuto.

Due passaggi attivi bastano per pubblicare una performance?

No. Il piccolo planning proposto illustra l'API. Un risultato utilizzabile richiede una finestra rappresentativa, ripetizioni, un riscaldamento esplicito e una misurazione finale senza il sovraccarico della raccolta dettagliata.

Una traccia CPU può diagnosticare ROCm?

Può fare luce sul lavoro lato host, ma non sostituisce le attività GPU. PyTorch usa anche il nome cuda su ROCm; verifica il backend, le attività supportate e quelle realmente registrate prima di interpretare la traccia.