HyperAI

Blog Officiel De PyTorch : Explication Détaillée De PyTorch Profiler V1.9

il y a 4 ans
Science populaire
Yang Bai
特色图像


Les améliorations apportées à Profiler v1.9 se concentrent sur le ciblage des étapes d'exécution les plus gourmandes en énergie en termes de temps d'exécution et/ou de mémoire, tout en visualisant la répartition de la charge de travail entre le GPU et le CPU.

Profiler v1.9 ajoute cinq nouvelles fonctionnalités majeures, notamment :

1. Vue de formation distribuée : Cela vous aide à comprendre le temps et la mémoire consommés par les tâches de formation distribuées. Supposons que vous ayez un modèle de formation. Lorsque vous divisez la charge en nœuds de travail et que vous les exécutez en parallèle, cela peut ressembler à une boîte noire et divers problèmes peuvent survenir. L’objectif global du modèle est d’augmenter la vitesse d’entraînement. Cette vue de formation distribuée vous aide à diagnostiquer et à déboguer les problèmes au sein d'un seul nœud.

2. Vue mémoire : Cette vue vous donne une meilleure compréhension de l’utilisation de la mémoire. Cet outil peut afficher l'allocation de mémoire active du programme à différentes étapes de fonctionnement, vous aidant ainsi à éviter les erreurs de mémoire insuffisante.

3. Visualisation des applications GPU : Cet outil garantit que le GPU est pleinement utilisé.

4. Prise en charge du stockage dans le cloud : Le plug-in Tensorboard peut désormais lire les données analysées à partir d’Azure Blob Storage, d’Amazon S3 et de Google Cloud Platform.

5. Accéder au code source : Cette fonctionnalité prend en charge la visualisation des informations de trace de pile et permet d'accéder directement au code source. Cela vous aide à optimiser et à itérer rapidement votre code en fonction des résultats du profilage.

Portail Colab du profileur PyTorch

Version chinoise du portail Colab

Aperçu du contenu de Colab :

  • Préparation des données et des modèles
  • Enregistrement des événements d'exécution à l'aide de Profiler
  • Exécuter le profileur
  • Utilisez TensorBoard pour afficher les résultats et analyser les performances du modèle
  • Améliorer les performances avec Profiler
  • Analyser les performances à l’aide d’autres fonctionnalités avancées

Premiers pas avec le profilage PyTorch

d'abord:

$ pip install torch-tb-profiler

import torch.profiler as profiler
With profiler.profile(XXXX)

Remarque: Pour plus d'informations sur CUDA et l'analyse CPU, voir Ici

with torch.profiler.profile( 
activities=[ 
torch.profiler.ProfilerActivity.CPU, 
torch.profiler.ProfilerActivity.CUDA],
  • profiler.record_function("$NAME") : permet d'ajouter des décorateurs aux blocs de fonctions.
  • Le paramètre Profile_memory=True sous profiler.profile peut analyser l'utilisation de la mémoire du CPU et du GPU.

Visualisation des performances du modèle PyTorch

### Formation distribuée

Les progrès récents en matière d’apprentissage profond ont démontré la valeur des grands ensembles de données et des grands modèles, ce qui signifie également que la formation des modèles nécessite davantage de ressources informatiques.

Le parallélisme de données distribuées (DDP) et NVIDIA Multi-Card Communication Framework (NCCL) sont des paradigmes largement adoptés dans PyTorch pour accélérer la formation en apprentissage profond.

Dans cette version de PyTorch Profiler, DDP avec backend NCCL est désormais pris en charge.
insérer la description de l'image ici

Présentation de l'informatique et des communications

Dans la « Vue d'ensemble du calcul/de la communication » de la vue de formation distribuée, les utilisateurs peuvent observer le rapport de calcul et de communication des nœuds « équilibreur de charge » entre tous les travailleurs, qui est mesuré en fonction de la granularité.

Liens relatifs à l'équilibreur de charge : Ici

Scénario 1 :

Si le temps de calcul et de chevauchement d'un travailleur est plus long que celui des autres travailleurs, cela peut indiquer un problème d'équilibrage de la charge de travail ou qu'un nœud est un retardataire. Le calcul est la somme du temps du noyau GPU, moins le temps de chevauchement. Le temps de chevauchement fait référence au temps économisé en entrelaçant les communications pendant le processus de calcul.

Un chevauchement plus long indique un meilleur parallélisme entre le calcul et la communication.Idéalement, le calcul et la communication devraient se chevaucher complètement. La communication est le temps total de communication moins le temps de chevauchement.

L'exemple suivant montre à quoi cela pourrait ressembler sur Tensorboard.
insérer la description de l'image ici
exemple de retardataire

Scénario 2 :

Si la taille du lot est petite (c'est-à-dire que les calculs sur tous les travailleurs sont petits) ou si les données à transmettre sont volumineuses, le rapport calcul/communication peut également être petit, et le taux d'utilisation du GPU et le temps d'attente peuvent être visibles dans le Profiler.

Les utilisateurs peuvent réviser le code en fonction de cette perspective de calcul/communication et réduire la communication en adoptant l’accumulation de gradient ou en augmentant la taille du lot pour réduire le ratio de communication. Le temps de communication DDP dépend de la taille du modèle. La taille du lot n'a rien à voir avec la taille du modèle. Par conséquent, l’augmentation de la taille du lot peut entraîner un temps de calcul plus long et des instances de calcul-communication plus importantes.

Présentation de la synchronisation/communication ###

Dans la vue Synchronisation/Communication, les utilisateurs peuvent observer l’efficacité de la communication. Cela est calculé en soustrayant le temps de calcul et de communication du temps d'étape. Le temps de synchronisation est la partie du temps de communication total consacrée à l'attente et à la synchronisation avec d'autres travailleurs. La vue Synchronisation/Communication inclut l'initialisation, le chargeur de données, le calcul du processeur, etc.

De cette vue, nous pouvons voir :Quelle proportion du volume total de communication est réellement utilisée pour échanger des données et quel est le temps d'inactivité en attendant que d'autres travailleurs fournissent des données.

insérer la description de l'image ici

Par exemple, s'il existe un équilibrage de charge de travail inefficace ou des problèmes de retardataire, cela peut être découvert dans la vue de synchronisation/communication. Cette vue montrera que certains travailleurs attendent plus longtemps que d’autres.

image

À partir du tableau ci-dessus, nous pouvons connaître les statistiques détaillées de tous les opérateurs de communication dans chaque nœud. Ce tableau peut être utilisé pour comprendre quels types d'opérateurs sont appelés, combien de fois chaque opérateur est appelé, la taille des données transmises par chaque opérateur, etc.

Vue mémoire

Cet outil peut être utilisé pour comprendre la consommation de ressources matérielles des opérateurs dans le modèle. Comprendre la consommation de temps et de mémoire au niveau de l’opérateur peut aider à résoudre les goulots d’étranglement des performances et à accélérer l’exécution du modèle.Étant donné que la taille de la mémoire du GPU est limitée, l’optimisation de l’efficacité de l’utilisation de la mémoire permet de :

  • Permet d'exécuter des modèles plus grands et d'obtenir de meilleures performances sur les tâches au niveau du terminal.
  • Permet des lots de plus grande taille, augmentant ainsi la vitesse de formation.

Le profileur enregistre toutes les allocations de mémoire pendant l'intervalle du profileur. Sélectionnez « Périphérique » pour voir les détails d’utilisation de la mémoire de chaque opérateur côté GPU ou côté hôte.

REMARQUE : profile_memory=True doit être activé pour générer les données de mémoire suivantes.

Liens connexes : Ici

With torch.profiler.profile(
Profiler_memory=True # this will take 1 – 2 minutes to complete. 
)

Définitions importantes :

  • « Augmentation de la taille » affiche la somme de tous les octets alloués, moins tous les octets de mémoire désalloués.
  • « Taille d'allocation » affiche la somme de tous les octets alloués, à l'exclusion de la désallocation de mémoire.
  • « Self » signifie que la mémoire allouée ne provient d'aucun opérateur enfant, mais est allouée par l'opérateur lui-même.
image

Mesures GPU sur une chronologie

Cette fonctionnalité vous permet de déboguer facilement les problèmes de performances lorsqu'un ou plusieurs GPU sont sous-utilisés. Idéalement, votre programme devrait avoir une utilisation GPU élevée (jusqu'à 100% d'utilisation GPU), un coût de communication CPU-GPU minimal et aucune consommation d'énergie.

Aperçu: La page de présentation met en évidence les résultats de trois indicateurs importants d'utilisation du GPU (utilisation du GPU, efficacité SM estimée et occupation estimée atteinte) à différents niveaux.

Essentiellement, chaque GPU possède de nombreux SM, et chaque SM possède de nombreux Warps, qui peuvent exécuter plusieurs threads simultanément. L'exécution de Warp comporte de nombreux threads car son nombre dépend du GPU. D'un point de vue général, les mesures GPU sur une chronologie peuvent aider les développeurs à obtenir une vue holistique de l'ensemble de la pile, ce qui est très important.

Si l’utilisation du GPU est faible, cela indique un problème potentiel avec votre modèle. Les causes courantes incluent :

  • Parallélisme insuffisant dans le noyau, c'est-à-dire que la taille du lot est trop petite
  • Appeler le petit noyau dans une boucle signifie que la surcharge de démarrage n'est pas amortie.
  • Les goulots d'étranglement du processeur ou des E/S entraînent une charge de travail insuffisante et une faible utilisation du GPU

Dans la page Présentation, la section Recommandations de performances contient des suggestions concrètes pour améliorer l’utilisation du GPU. Dans cet exemple, l’utilisation du GPU est faible, la suggestion de performances est donc d’augmenter la taille du lot. Suite à la recommandation de performances, l'augmentation de la taille du lot de 4 à 32 a augmenté l'utilisation du GPU de 60,68%.

Utilisation du GPU : Dans le profileur, un intervalle de temps d'étape apparaît lorsque le moteur GPU exécute une charge de travail. Plus le pourcentage d’utilisation est élevé, mieux c’est. Il n’est pas exact d’évaluer les goulots d’étranglement des performances uniquement en fonction de l’utilisation du GPU. Vous ne pouvez pas l'utiliser pour savoir combien de multiprocesseurs de streaming sont en cours d'exécution.

Notez que même si cette mesure est utile pour détecter les périodes d’inactivité, une valeur élevée ne signifie pas nécessairement que le GPU est utilisé très efficacement. Par exemple, un noyau monothread exécuté en continu aura une utilisation GPU de 100%.

L'efficacité estimée du processeur de flux (Est. SM Efficiency) est un indicateur plus détaillé. Il indique le pourcentage du SM qui était utilisé pendant la trace, le pourcentage de temps pendant lequel il y avait au moins une chaîne active sur le SM et le pourcentage de temps pendant lequel les chaînes étaient inactives.

Documentation NVIDIA : Ici

HNE. L’efficacité SM a également des limites. Par exemple, un noyau avec un seul thread par bloc ne peut pas utiliser pleinement tous les SM. L’utilisation de chaque SM ne peut pas être connue uniquement sur la base de l’efficacité du SM. On ne peut connaître que les opérations effectuées par chaque SM, y compris les pauses lors de l'attente des résultats de chargement de la mémoire.

Afin de maintenir une utilisation élevée du SM, un nombre suffisant de tours prêts doit être garanti pour fonctionner chaque fois qu'un blocage se produit.

Pour les problèmes de diagnostic de performance, Est. L'occupation atteinte est plus précise que l'occupation estimée. Efficacité SM et utilisation du GPU. L'occupation estimée atteinte indique combien de chaînes par SM peuvent être actives simultanément. Disposer d’un nombre suffisant de chaînes actives est souvent la clé pour obtenir un bon débit. Contrairement à l’utilisation du GPU et à l’efficacité du SM, rendre cette valeur aussi élevée que possible n’est pas l’objectif ultime.

D'un point de vue empirique, de bons gains de débit peuvent être obtenus en augmentant cet indicateur à 15% ou plus. Mais à un moment donné, les rendements diminuent. Par exemple, si la valeur a atteint 30%, les bénéfices ultérieurs deviennent incertains. Cette métrique montre la moyenne de tous les planificateurs de distorsion pendant l'exécution du noyau.

Documentation NVIDIA : Ici

Plus la valeur de Est. Atteindre l'occupation, c'est mieux.

image

Détails : Resnet50_batchsize4

image

Détails : Resnet50_batchsize32

Vue du noyau : le noyau a des « blocs par SM » et une « occupation estimée atteinte ».

HNE. L'occupation atteinte est un outil utile pour comparer les performances des modèles.

image

Blocs moyens par SM :

Le nombre de blocs par SM = le nombre de blocs du noyau / le nombre de SM du GPU. Si ce nombre est inférieur à 1, cela indique que le multiprocesseur GPU n'est pas pleinement utilisé. « Moyenne des blocs par SM » est la moyenne pondérée de toutes les exécutions de ce nom de noyau, en utilisant la durée de chaque exécution comme pondération.

Estimation moyenne Occupation atteinte

La définition de Est. L'occupation obtenue est la même que celle décrite ci-dessus. Estimation moyenne L'occupation atteinte est la moyenne pondérée de toutes les exécutions du nom du noyau, en utilisant la durée de chaque exécution comme pondération.

Vue de suivi :

La vue Trace affiche une chronologie indiquant la durée des opérateurs dans le modèle et le système qui a effectué l'opération. Cette vue peut vous aider à identifier les frais généraux élevés et les temps d'exécution longs, qu'ils soient causés par l'entrée ou par la formation du modèle. Actuellement, la vue de trace affiche l'utilisation du GPU et l'estimation. L'efficacité SM dans une chronologie.

image

Dans l'exemple ci-dessus, l'utilisation du GPU pendant « ProfilerStep5 » dans le thread 28022 est supérieure à celle pendant « Optimizer.step ». Vous pouvez zoomer pour voir la cause.

image

Comme on peut le voir sur la figure ci-dessus, le noyau du premier est plus long que celui du second. Le temps d’exécution du noyau de ce dernier est trop court, ce qui entraîne une faible utilisation du GPU.

HNE. Efficacité SM : Chaque noyau a un EST calculé. Efficacité SM entre 0-100%. Par exemple, le noyau ci-dessous n'a que 64 tuiles, et le SM de ce GPU est de 80, donc son « Est. SM Efficiency » est de 64/80, soit 0,8.

image

Prise en charge du stockage dans le cloud

Après avoir exécuté pip install tensorboard , pour lire les données via un fournisseur de cloud, vous pouvez exécuter :

torch-tb-profiler[blob] 
torch-tb-profiler[gs] 
torch-tb-profiler[s3]

Vous pouvez utiliser pip install torch-tb-profiler[blob], pip install torch-tb-profiler[gs] ou pip install torch-tb-profiler[S3] pour lire les données d'un fournisseur cloud.

Pour plus d'informations, voir : Ici

Accéder au code source

L’un des grands avantages de l’intégration de TensorBoard et de PyTorch Profiler directement dans Visual Studio Code (VS Code) est la possibilité d’accéder directement au code source (fichier et ligne) à partir de la trace de la pile de Profiler. L'extension Python VS Code prend désormais en charge l'intégration de TensorBoard.

L'accès au code source n'est disponible que lorsque Tensorboard est exécuté dans VS Code. Si le profilage avec_stack=True, la trace de la pile apparaîtra dans l'interface utilisateur du plugin. Cliquez sur la trace de la pile dans le profileur PyTorch, VS Code ouvrira le fichier correspondant et accédera directement au code correspondant pour le débogage. Cela permet d’optimiser et de modifier rapidement le code en fonction des résultats d’analyse et des suggestions.

image

Accédez au code source avec l'interface utilisateur du plug-in Visual Studio Code

Pour plus d'informations sur la façon d'optimiser les performances de la taille des lots, veuillez consulter le didacticiel détaillé : Ici

PyTorch Profiler peut également être intégré à PyTorch Lightning. Démarrez simplement une tâche de formation Lightning avec trainer.profiler=pytorch pour générer une trace.

Exemple détaillé : Ici

Adresse d'origine : Ici