Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
I grafici di fiamma di profilatura GPU mostrano quali funzioni utilizzano la maggior parte della memoria GPU. Questo articolo illustra come interpretare i grafici di fiamma generati dagli strumenti di profilatura GPU per Servizio Azure Kubernetes (AKS).
Important
Le funzionalità in anteprima di AKS sono disponibili in modalità self-service, su base volontaria. Le anteprime vengono fornite "così come sono" e "come disponibili" e sono escluse dai contratti di servizio e dalla garanzia limitata. Le anteprime di AKS sono coperte solo parzialmente dall'assistenza clienti nei limiti del possibile. Di conseguenza, queste funzionalità non sono destinate all'uso in produzione. Per altre informazioni, vedere gli articoli di supporto seguenti:
Prima di iniziare, configurare la profilatura GPU e verificare che i dati di profilatura siano disponibili in Pyroscope e Grafana.
Annotazioni
La prima esecuzione della profilatura potrebbe non visualizzare tutti i simboli, inclusi i simboli delle operazioni di avvio, ad esempio il caricamento del modello, mentre il profiler analizza il carico di lavoro e risolve i simboli. Eseguire di nuovo il carico di lavoro dopo l'analisi iniziale per acquisire questi simboli nei profili successivi.
Comprendere i grafici delle fiamme
Un grafico di fiamma visualizza gli stack di chiamate profilati. Ogni barra rappresenta una funzione e le barre in pila mostrano la catena di chiamate o quale funzione ha chiamato un'altra funzione. La larghezza di ogni barra rappresenta la quantità della risorsa misurata, ad esempio il tempo cpu o la memoria GPU allocata, che passa attraverso tale funzione.
Regola chiave: più ampia è una barra, maggiore è il flusso delle risorse misurate attraverso tale funzione.
I grafici di fiamma di esempio seguenti vengono acquisiti da un carico di lavoro di inferenza vLLM.
Tip
Usare Espandi tutti i gruppi nel pannello del grafico flame di Grafana per visualizzare l'intero stack di chiamate senza comprimerlo. Usare la casella Di ricerca per trovare funzioni o parole chiave specifiche. Per evitare che il pannello si richiuda di nuovo, metti in pausa l'aggiornamento automatico della dashboard impostando l'intervallo di aggiornamento su Disattivato nell'angolo in alto a destra della dashboard di Grafana mentre esamini il flame graph espanso.
Tip
Usa blocco di messa a fuoco per focalizzarti su un percorso di allocazione specifico.
Leggi i simboli
Le etichette dei grafi di fiamma seguono queste convenzioni:
| Formato del simbolo | Meaning |
|---|---|
Foo > bar |
class Foo: method def bar() |
Foo > __init__ |
Costruttore della classe Foo |
bar (solo) |
Funzione autonoma def bar() |
<interpreter trampoline> |
Overhead di CPython. È possibile ignorare questo simbolo. |
<raw-address>, ad esempio, 0x7f151 |
Codice C o CUDA nativo senza simbolo Python disponibile. |
Ecco alcuni esempi:
-
GPUModelRunner/_allocate_kv_cache_tensors: metodo in una classe. Leggere questo simbolo comeclass GPUModelRunner: def _allocate_kv_cache_tensors(self). -
LlamaMLP/__init__: costruttore chiamato durante la creazione di unLlamaMLP(...)oggetto . -
_compile_fx_inner: funzione autonoma a livello di modulo che non si trova all'interno di una classe.
Comprendere l'allocazione propria rispetto a quella totale
Usare i valori Self e Total per determinare dove viene utilizzata la risorsa:
- Total è la risorsa utilizzata da una funzione e tutto ciò che chiama. Una funzione può avere un totale elevato, ma allocare nulla perché fa parte della catena di chiamate.
- Self indica la risorsa utilizzata direttamente dalla funzione, escluse le relative funzioni figlio. Un valore proprio elevato indica che in questa funzione viene consumata la risorsa.
Ad esempio, se GPUModelRunner._allocate_kv_cache_tensors ha 55,1 GB di allocazione automatica, è la funzione che chiama torch.empty() per creare i tensori della cache chiave-valore (KV).
Usare le tecniche di spostamento seguenti:
- Inizia con i nodi foglia, che sono barre senza nulla sopra. L'intera larghezza rappresenta l'allocazione propria.
- Quando si cerca l'origine di un'allocazione, ignorare le barre larghe con allocazione propria pari a zero. Queste funzioni coordinano le chiamate ad altre funzioni.
- Esaminare le barre larghe con un'allocazione propria elevata come potenziali destinazioni di ottimizzazione.
Individua il maggior consumatore di risorse
Per identificare gli hotspot, seguire questa procedura:
Esaminare le barre più ampie nella parte superiore del grafico. Queste funzioni foglia allocano memoria. Più ampia è la barra, maggiore è la quantità di memoria utilizzata.
Controllare l'allocazione propria rispetto all'allocazione totale. Una barra larga nella parte inferiore con
self: 0fa parte della catena di chiamate. Seguirlo verso l'alto fino a trovare una barra con autoallocazione elevata.Leggere lo stack di chiamate dal basso verso l'alto per comprendere il motivo per cui è stata chiamata la funzione. L'esempio seguente termina con la funzione che esegue l'allocazione:
<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
Usare la tabella seguente come riferimento rapido:
| Obiettivo | Cosa cercare |
|---|---|
| Trovare ciò che alloca la maggior parte della memoria | Barra foglia più larga nella parte superiore dello stack |
| Trovare ciò che è responsabile della maggior parte della memoria | Barra più larga nella parte inferiore dello stack |
| Identificare le destinazioni di ottimizzazione | Barre con allocazione propria elevata |
| Identificare le funzioni che è possibile ignorare | Barre larghe con allocazione propria pari a zero |