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.
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.| Mogelijke observatie | Hypothese | Volgende controle |
|---|---|---|
| GPU zonder activiteit tijdens het lezen | De invoerpipeline kan niet volgen | Dezelfde berekening met een al voorbereide batch |
| Terugkerende kopieën van een constante | Ongeschikte plaatsing of levensduur | Verplaats één keer, controleer de uitvoer |
| Veel kleine lanceringen | Versnipperd werk | Onderzoek groepering en totale kost |
| Eén lange operator | Bepalende vorm of algoritme | Vergelijk 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.