Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Plamenné grafy profilování GPU ukazují, které funkce spotřebovávají nejvíce paměti GPU. Tento článek vysvětluje, jak interpretovat grafy plamene generované nástroji pro profilaci GPU pro Azure Kubernetes Service (AKS).
Important
Funkce AKS ve verzi Preview jsou k dispozici na bázi samoobsluhy a dobrovolného přihlášení. Ukázky jsou poskytovány "tak, jak jsou" a "dle dostupnosti" a jsou vyloučeny ze smluv o úrovni služeb a z omezené záruky. Předběžné verze AKS jsou částečně pokryty zákaznickou podporou podle možností. Proto tyto funkce nejsou určené pro produkční použití. Další informace najdete v následujících článcích podpory:
Než začnete, nastavte profilaci GPU a ověřte, že jsou data profilace dostupná v Pyroskopu a Grafana.
Note
Při prvním spuštění profilace se nemusí zobrazit všechny symboly, včetně symbolů ze spouštěcích operací, jako je načítání modelu, protože profiler analyzuje zátěž a rozpoznává symboly. Spusťte úlohu znovu po počáteční analýze a zachyťte tyto symboly v následných profilech.
Principy grafů plamene
Plamenný graf znázorňuje profilované zásobníky volání. Každý pruh představuje funkci a skládané pruhy zobrazují řetěz volání nebo funkci, která se nazývá jiná funkce. Šířka každého pruhu představuje množství měřeného prostředku, jako je čas procesoru nebo přidělená paměť GPU, která prochází touto funkcí.
Klíčové pravidlo: Čím širší je pruh, tím více měřených prostředků prochází danou funkcí.
Následující ukázkové grafy plamene jsou zachyceny z úlohy odvozování vLLM.
Tip
Pomocí Rozbalit všechny skupiny na panelu flame graph v Grafaně si zobrazíte celý zásobník volání bez sbalování. Pomocí vyhledávacího pole můžete najít konkrétní funkce nebo klíčová slova. Pokud chcete zabránit tomu, aby se panel znovu sbalil, pozastavte automatické obnovení dashboardu nastavením intervalu obnovení na Vypnuto v pravém horním rohu dashboardu Grafana během prohlížení rozbaleného flame graphu.
Tip
Pomocí bloku Zaměření můžete zaměřit konkrétní cestu alokace.
Čtení symbolů
Popisky flame graphu se řídí těmito konvencemi:
| Formát symbolu | Význam |
|---|---|
Foo > bar |
class Foo: method def bar() |
Foo > __init__ |
Konstruktor třídy Foo |
bar (samostatně) |
Samostatná def bar() funkce |
<interpreter trampoline> |
Režie CPythonu Tento symbol můžete ignorovat. |
<raw-address>, například 0x7f151 |
Nativní kód C nebo CUDA bez dostupného symbolu Python. |
Mezi příklady patří:
-
GPUModelRunner/_allocate_kv_cache_tensors: Metoda třídy. Tento symbol si můžete přečíst jakoclass GPUModelRunner: def _allocate_kv_cache_tensors(self). -
LlamaMLP/__init__: Konstruktor volaný při vytváření objektuLlamaMLP(...). -
_compile_fx_inner: Samostatná funkce na úrovni modulu, která není uvnitř třídy.
Porozumět rozdílu mezi vlastní a celkovou alokací
Pomocí hodnot Self a Total určete, kde se prostředek spotřebuje:
- Celkem jsou prostředky spotřebované funkcí a vším, co volá. Funkce může mít velkou celkovou hodnotu, ale sama nic nealokovat, protože je součástí řetězce volání.
- Self je zdroj, který funkce spotřebovává přímo, bez započtení jejích podřízených funkcí. Vysoká vlastní hodnota znamená, že tato funkce je tam, kde se prostředek spotřebovává.
Pokud má například GPUModelRunner._allocate_kv_cache_tensors 55,1 GB vlastní alokace, je to funkce, která volá torch.empty() k vytvoření tenzorů mezipaměti klíč–hodnota (KV).
Použijte následující navigační techniky:
- Začněte listovými uzly, což jsou sloupce, nad nimiž už nic není. Celá jejich šířka znázorňuje vlastní alokaci.
- Při hledání zdroje alokace přeskočte široké pruhy s nulovou vlastní alokací. Tyto funkce orchestrují volání jiných funkcí.
- Prozkoumejte široké sloupce s vysokou vlastní alokací jako potenciální cíle optimalizace.
Vyhledání největšího příjemce prostředků
K identifikaci hotspotů použijte následující postup:
Podívejte se na nejširší pruhy v horní části grafu. Tyto funkce typu list přidělují paměť. Čím širší je pruh, tím více paměti spotřebuje.
Zkontrolujte vlastní a celkové přidělení. Široký pruh ve spodní části s
self: 0je součástí řetězu volání. Postupujte po něm směrem nahoru, dokud nenajdete řádek s vysokou vlastní alokací.Čtěte zásobník volání zdola nahoru, abyste pochopili, proč byla funkce zavolána. Následující příklad končí funkcí, která provádí přidělení:
<raw-address>, for example, 0x7f151 -> native code entry <interpreter trampoline> -> CPython dispatch <module> -> script top level EngineCoreProc.run_engine_core -> vLLM engine startup EngineCore.__init__ -> engine initialization EngineCore._initialize_kv_caches -> KV cache setup Worker.initialize_from_config -> worker setup GPUModelRunner.initialize_kv_cache -> model runner GPUModelRunner._allocate_kv_cache_tensors -> actual allocation
Jako stručný přehled použijte následující tabulku:
| Goal | Co hledat |
|---|---|
| Zjištění toho, co přiděluje nejvíce paměti | Široký listový pruh v horní části zásobníku |
| Zjištění, co je zodpovědné za většinu paměti | Nejširší pruh v dolní části zásobníku |
| Identifikace cílů optimalizace | Pruhy s širokým vlastním přidělením |
| Identifikace funkcí, které můžete přeskočit | Široké pruhy s nulovou vlastní alokací |