Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les graphiques en flammes de profilage du GPU montrent quelles fonctions consomment le plus de mémoire GPU. Cet article explique comment interpréter les graphiques de flamme générés par les outils de profilage GPU pour Azure Kubernetes Service (AKS).
Important
Les fonctionnalités d’évaluation AKS sont disponibles en libre-service et font l’objet d’un abonnement. Les versions préliminaires sont fournies « en l’état » et « selon leur disponibilité » et ne sont pas couvertes par les accords de niveau de service ni par la garantie limitée. Les versions préliminaires d’AKS sont partiellement couvertes par le support client, dans la limite du raisonnable. Par conséquent, ces fonctionnalités ne sont pas destinées à une utilisation en production. Pour plus d’informations, consultez les articles de support suivants :
Avant de commencer, configurez le profilage GPU et vérifiez que les données de profilage sont disponibles dans Pyroscope et Grafana.
Note
La première exécution de profilage peut ne pas afficher chaque symbole, y compris les symboles des opérations de démarrage telles que le chargement du modèle, tandis que le profileur analyse la charge de travail et résout les symboles. Réexécutez la charge de travail après l’analyse initiale pour capturer ces symboles dans les profils suivants.
Comprendre les graphiques de flammes
Un graphe de flamme visualise les piles d’appels profilées. Chaque barre représente une fonction, et les barres empilées indiquent la chaîne d’appels, c’est-à-dire quelle fonction en a appelé une autre. La largeur de chaque barre représente la quantité de la ressource mesurée, telle que le temps processeur ou la mémoire GPU allouée, qui transite par cette fonction.
Règle de clé : plus une barre est large, plus la ressource mesurée transite par cette fonction.
Les exemples de graphiques de flamme suivants sont capturés à partir d’une charge de travail d’inférence vLLM.
Tip
Utilisez Développer tous les groupes dans le panneau de graphique en flammes de Grafana pour afficher la pile d’appels complète sans repli. Utilisez la zone de recherche pour rechercher des fonctions ou des mots clés spécifiques. Pour éviter que le panneau ne se replie à nouveau, mettez en pause l’actualisation automatique du tableau de bord en réglant l’intervalle d’actualisation sur Désactivé dans le coin supérieur droit du tableau de bord Grafana pendant que vous inspectez le graphique en flammes déplié.
Tip
Utilisez le bloc Focus pour vous concentrer sur un chemin d’allocation spécifique.
Lire les symboles
Les étiquettes de graphe de flamme suivent les conventions suivantes :
| Format de symbole | Meaning |
|---|---|
Foo > bar |
class Foo: method def bar() |
Foo > __init__ |
Constructeur de classe Foo |
bar (seul) |
Fonction autonome def bar() |
<interpreter trampoline> |
Surcharge de CPython. Vous pouvez ignorer ce symbole. |
<raw-address>, par exemple, 0x7f151 |
Code C ou CUDA natif sans symbole Python disponible. |
Voici quelques exemples :
-
GPUModelRunner/_allocate_kv_cache_tensors: méthode sur une classe. Lisez ce symbole en tant queclass GPUModelRunner: def _allocate_kv_cache_tensors(self). -
LlamaMLP/__init__: constructeur appelé lors de la création d’unLlamaMLP(...)objet. -
_compile_fx_inner: fonction au niveau du module autonome qui n’est pas à l’intérieur d’une classe.
Comprendre l’allocation propre par rapport à l’allocation totale
Utilisez les valeurs Self et Total pour déterminer où la ressource est consommée :
- Total est la ressource consommée par une fonction et tout ce qu’elle appelle. Une fonction peut avoir un total élevé sans rien allouer elle-même, parce qu’elle fait partie de la chaîne d’appels.
- Self désigne les ressources consommées directement par la fonction, à l’exclusion de ses fonctions filles. Une valeur d’auto-valeur élevée signifie que cette fonction est l’endroit où la ressource est consommée.
Par exemple, si GPUModelRunner._allocate_kv_cache_tensors a 55,1 Go d’allocation propre, c’est la fonction qui appelle torch.empty() pour créer les tenseurs du cache de paires clé-valeur (KV).
Utilisez les techniques de navigation suivantes :
- Commencez par les nœuds feuilles, qui sont des barres sans rien au-dessus de celles-ci. Leur largeur entière représente l’allocation automatique.
- Ignorez les barres larges avec zéro allocation automatique lorsque vous recherchez la source d’une allocation. Ces fonctions orchestrent les appels à d’autres fonctions.
- Analysez les barres larges avec une allocation propre élevée comme pistes d’optimisation potentielles.
Rechercher le plus grand consommateur de ressources
Procédez comme suit pour identifier les points d’accès :
Examinez les barres les plus larges en haut du graphique. Ces fonctions feuilles allouent de la mémoire. Plus la barre est large, plus elle consomme de mémoire.
Vérifier l’allocation propre par rapport à l’allocation totale. Une barre large en bas avec
self: 0fait partie de la chaîne d’appels. Suivez-le de bas en haut jusqu’à trouver une barre avec une forte allocation en self.Lisez la pile des appels de bas en haut pour comprendre pourquoi la fonction a été appelée. L’exemple suivant se termine par la fonction qui effectue l’allocation :
<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
Utilisez le tableau suivant comme référence rapide :
| Goal | Ce qu’il faut rechercher |
|---|---|
| Rechercher ce qui alloue le plus de mémoire | Barre feuille la plus large en haut de la pile |
| Trouvez ce qui utilise le plus de mémoire | Barre la plus large en bas de la pile |
| Identifier les cibles d’optimisation | Barres à allocation propre large |
| Identifier les fonctions que vous pouvez ignorer | Barres larges avec zéro allocation automatique |