GPU's voor je projecten · crypto-betaling zonder KYC Hoe huren
Nederlands
Console openen
Praktische gids / KERNODECK

Een PyTorch-stap profilen om te weten waar de tijd naartoe gaat

Bepaal eerst de stap die je wilt observeren, scheid laden, overdracht, berekening en update, en leg vervolgens een kort representatief venster vast met torch.profiler. Lees de CPU-tijdlijn en de beschikbare GPU-activiteiten samen. Een Python-lanceringstijd is niet de voltooide uitvoeringstijd op de accelerator, en een geïnstrumenteerde trace is op zichzelf geen benchmark.

7 min leestijd · Gids voor ontwikkelaars

Kies een vraag voordat je een trace opent

Een trace beantwoordt beter een precieze vraag: wacht de berekening op de gegevens, wordt een kopie herhaald, of wordt een kleine operator te vaak aangeroepen? Definieer de invoer, de uitvoer en de grenzen van je stap. Geef voor training aan of deze backward, optimizer-update en het lezen van de batch bevat. Scheid voor inferentie het laden van het model en de aanvraag.

Houd een kort scenario aan waarvan je de correctheid kent. Noteer vormen, batch, precisie, modus van het model, eventuele compilatie en de bron van de gegevens. Een vereenvoudigde invoer kan helpen om een gedrag te isoleren, maar vertegenwoordigt niet noodzakelijk meer de volledige belasting. Vermeld dit verschil in de meting.

Leg de uiteindelijke eenheid vast: milliseconden per stap of verwerkte voorbeelden per seconde. De sommen van gebeurtenissen vervangen niet de verstreken tijd. Vergelijk vensters met dezelfde grenzen voor lezen en overdracht.

CPU-tijd, GPU-werk en wachttijd onderscheiden

De CPU bereidt bewerkingen voor en start ze; de GPU kan ze later uitvoeren. Een Python-interval kan dus lancering, wachttijd of beide bevatten. De CUDA-documentatie van PyTorch geeft aan dat nauwkeurige metingen met deze asynchronie rekening moeten houden, met name door synchronisatie of gebeurtenissen die passen bij de scope.

Voor een gerichte meting van de GPU-duur kunnen CUDA-gebeurtenissen geschikt zijn. Wacht voor een end-to-end latentie op het einde van het werk dat binnen die latentie valt en meet het geheel van de aanvraag. Meng deze twee eenheden niet. Een synchronisatie die tussen elke bewerking wordt toegevoegd kan een werkelijke overlap wegnemen en het programma veranderen dat je probeert te begrijpen.

In de profiler beantwoorden de eigen tijden van een operator en de tijden inclusief suboperaties ook verschillende vragen. Bekijk de tijdlijn voordat je de rijen van de tabel optelt. Gelijktijdige of geneste activiteiten vertegenwoordigen geen losse delen van verstreken tijd.

Reserveer een opstartfase en een actief venster

De eerste doorgang kan initialisatie, laden of compilatie bevatten. Bepaal of je vraag over deze opstart gaat of over een al gestabiliseerde fase. Bewaar beide observaties wanneer ze van belang zijn voor het gebruik, in plaats van de initiële kosten weg te strepen uit een gemiddelde dat als geheel wordt gepresenteerd.

De functie schedule maakt het mogelijk om wachttijd, voorbereiding van de collectie en actief venster te onderscheiden. De opwarming van de profiler is geen bewijs dat je model zijn stabiele toestand heeft bereikt. Controleer ook de aangetroffen vormen en de staat van de caches. Een applicatie met variabele invoer kan na meerdere iteraties nieuwe paden tegenkomen.

Het hieronder voorgestelde didactische schema wacht op een stap, bereidt er een voor en legt er twee vast. Vier stappen volstaan om het mechanisme uit te leggen, niet om een prestatieverdeling vast te stellen. Kies in een echte campagne een onderbouwd venster en herhaal de meting buiten de profiler na de analyse.

Voorgesteld voorbeeld: vier stappen met leesbare grenzen

Het volgende fragment is niet uitgevoerd. Het veronderstelt dat model, optimizer, loss_fn, loader en device bestaan, dat het model op device staat en dat de loader minstens vier batches van paren x, y levert. Het voert updates uit: gebruik een experimentele toestand die daarvoor bedoeld is, niet een sessie waarvan je de gewichten moet behouden.

De labels scheiden CPU-lezen, overdracht en training. De iterator wordt vóór het venster aangemaakt, wat een deel van zijn opstart buiten het bereik houdt. Het bestand wordt nieuw gekozen om een bestaand spoor niet te overschrijven. Het voorbeeld weigert een GPU-collectie die niet beschikbaar is in plaats van stilletjes een CPU-spoor als GPU-analyse te presenteren.

Het signaal step() laat de planning na elke stap opschuiven. Het officiële recept beschrijft dit verband tussen iteraties en collectie. Op een ROCm-stack blijft het PyTorch-apparaat cuda heten; de beschikbaarheid van de acceleratorcollectie hangt niettemin af van de build en zijn tools. Controleer welke activiteiten daadwerkelijk in het resultaat aanwezig zijn.

Didactische vastlegging van een kort venster, niet uitgevoerd
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("Kies een nieuwe tracenaam")
activities = [ProfilerActivity.CPU]
if device.type == "cuda":
    if ProfilerActivity.CUDA not in supported_activities():
        raise RuntimeError("GPU-collectie niet beschikbaar in deze 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,
))

Een observatie omzetten in een toetsbare hypothese

Begin met het actieve venster en controleer of de verwachte labels verschijnen. Bekijk daarna de gaten tussen activiteiten, de kopieën en de herhalingen. Een lange wachttijd in lecture_batch_cpu wijst op de invoerpipeline; die meet niet rechtstreeks de opslag. Een frequente kopie nodigt uit om de plaatsing van de tensors te onderzoeken, zonder te bewijzen dat ze nutteloos is.

Formuleer één enkele hypothese en stel dan een gecontroleerde wijziging voor. Als bijvoorbeeld een constante bij elke stap opnieuw wordt opgebouwd en overgedragen, controleer dan of haar levensduur meerdere stappen kan overspannen zonder het resultaat te veranderen. Als een operator dominant lijkt, inspecteer dan zijn vormen en het aantal aanroepen voordat je een vervanging zoekt.

De onderstaande regels zijn mogelijke lezingen, geen vaststellingen uit een uitgevoerd spoor. Er wordt geen enkele duur of versnelling aangekondigd. De nuttige conclusie is een volgend experiment dat de voorgestelde oorzaak kan bevestigen of weerleggen.

Scroll door de tabel om alle kolommen te lezen.
Didactische interpretaties om in je eigen spoor te controleren
Mogelijke observatieHypotheseVolgende controle
GPU zonder activiteit tijdens het lezenDe invoerpipeline kan niet volgenDezelfde berekening met een al voorbereide batch
Terugkerende kopieën van een constanteOngeschikte plaatsing of levensduurVerplaats één keer, controleer de uitvoer
Veel kleine lanceringenVersnipperd werkOnderzoek groepering en totale kost
Eén lange operatorBepalende vorm of algoritmeVergelijk dezelfde operator en zijn invoer

De kost en de informatie van de instrumentatie beperken

Begin met een korte collectie en weinig opties. Activeer vormen, stacks of geheugen alleen als een vraag dat vereist. De PyTorch-API vermeldt dat deze informatie een kost toevoegt; het verzamelen van vormen kan zelfs verwijzingen naar tensors vasthouden. Een gedetailleerd profiel kan dus de duur of het geheugengebruik van het programma veranderen.

Een trace kan namen van operators, vormen en, afhankelijk van de opties, codepaden bevatten. Inspecteer die voordat je hem deelt. Een zonelabel moet de stap beschrijven zonder een e-mailadres, token, privépad of invoerinhoud mee te nemen. Kies een trace-viewer die bij je omgeving past en houd de verzameling onder je eigen controle.

Als de verwachte GPU-events ontbreken, vul hun tijden dan niet met nul. Geef aan dat ze niet zijn waargenomen en onderzoek de ondersteuning van de verzameling. Een ontbrekend event in de tool is geen bewijs dat er niet is gerekend.

De optimalisatie buiten de profiler valideren

Vertrek vanuit dezelfde relevante staat en vergelijk de correctheid voor en na de wijziging. Bij training verandert de gewichten bij een extra stap; twee opeenvolgende captures vormen niet noodzakelijk een gelijkwaardige vergelijking. Bewaar code, parameters en startpunt zodat je het verschil kunt verklaren.

Meet daarna het scenario zonder gedetailleerde verzameling, met dezelfde warming-up en meerdere runs. Rapporteer het bereik, de ruwe waarden en hun spreiding. Een lokale verbetering kan in de hele lus verdwijnen of de kwaliteit verslechteren: beide moeten in de beslissing blijven.

Gebruik de observaties ten slotte om de werkelijk benodigde resources te bepalen. Een trace van je eigen machine rangschikt de aanbiedingen van Kernodeck niet en bewijst noch de hostprocessor noch het netwerk van een gehuurde server. GPU-vergelijking vereist een vergelijkbare belasting, omstandigheden en resultaten op de betrokken resources.

Jouw vragen

Wijst de grootste CPU-tijd op de traagste GPU-operator?

Nee. Die kan lancering, verwerking aan de hostzijde of wachten omvatten. Bekijk de GPU-events en hun chronologie wanneer de verzameling die levert. De tabel gesorteerd op CPU-tijd beantwoordt alleen dat perspectief.

Moet ik alle CUDA-tijden in de tabel optellen?

Niet om automatisch de totale duur te krijgen. Activiteiten kunnen elkaar overlappen en events kunnen genest zijn. Definieer een venster van verstreken tijd en gebruik de trace om de inhoud ervan te verklaren.

Volstaan twee actieve stappen om een prestatie te publiceren?

Nee. De kleine planning die wordt voorgesteld illustreert de API. Een bruikbaar resultaat vereist een representatief venster, herhalingen, een expliciete warming-up en een eindmeting zonder de overhead van de gedetailleerde verzameling.

Kan een CPU-trace ROCm diagnosticeren?

Die kan het werk aan de hostzijde verhelderen, maar vervangt de GPU-activiteiten niet. PyTorch gebruikt ook op ROCm de naam cuda; controleer de backend, de ondersteunde activiteiten en welke daadwerkelijk zijn vastgelegd voordat je de trace interpreteert.