Aide à protéger la Grande barrière de corail avec tensorflow sur Kaggle Rejoignez Défi

Optimiser les performances de TensorFlow à l'aide du profileur

Ce guide montre comment utiliser les outils disponibles avec TensorFlow Profiler pour suivre les performances de vos modèles TensorFlow. Vous apprendrez à comprendre les performances de votre modèle sur l'hôte (CPU), le périphérique (GPU) ou sur une combinaison de l'hôte et du ou des périphériques.

Le profilage permet de comprendre la consommation de ressources matérielles (temps et mémoire) des différentes opérations TensorFlow (ops) dans votre modèle et de résoudre les goulots d'étranglement des performances et, finalement, d'accélérer l'exécution du modèle.

Ce guide vous expliquera comment installer le profileur, les différents outils disponibles, les différents modes de collecte des données de performances par le profileur et quelques bonnes pratiques recommandées pour optimiser les performances du modèle.

Si vous souhaitez profiler les performances de votre modèle sur le Cloud PUT, consultez le Guide TPU - Cloud .

Installer les prérequis Profiler et GPU

Installez le plugin Profiler pour TensorBoard avec pip. Notez que le profileur nécessite les dernières versions de TensorFlow et TensorBoard (>=2.2).

pip install -U tensorboard_plugin_profile

Pour profiler sur le GPU, vous devez :

  1. Rencontrer le pilote GPU NVIDIA® et exigences Toolkit CUDA ® figurant sur les exigences logicielles de support GPU tensorflow .
  2. Assurez - vous que les Interface Outils NVIDIA® CUDA ® profilage (CUPTI) existe sur le chemin:

    /sbin/ldconfig -N -v $(sed 's/:/ /g' <<< $LD_LIBRARY_PATH) | \
    grep libcupti
    

Si vous ne disposez pas CUPTI sur le chemin, préfixer son répertoire d'installation du $LD_LIBRARY_PATH variable d'environnement en cours d' exécution:

export LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH

Ensuite, exécutez la ldconfig commande ci - dessus pour vérifier que la bibliothèque CUPTI se trouve.

Résoudre les problèmes de privilège

Lorsque vous exécutez le profilage avec Toolkit CUDA ® dans un environnement Docker ou sous Linux, vous pouvez rencontrer des problèmes liés aux droits d'CUPTI insuffisants ( CUPTI_ERROR_INSUFFICIENT_PRIVILEGES ). Accédez aux Docs de NVIDIA Developer pour en savoir plus sur la façon dont vous pouvez résoudre ces problèmes sur Linux.

Pour résoudre les problèmes de privilèges CUPTI dans un environnement Docker, exécutez

docker run option '--privileged=true'

Outils de profilage

Accédez au Profiler de l'onglet Profil TensorBoard, qui apparaît seulement après avoir capturé des données du modèle.

Le Profiler dispose d'une sélection d'outils pour aider à l'analyse des performances :

  • Page d'aperçu
  • Analyseur de pipeline d'entrée
  • Statistiques TensorFlow
  • Visionneuse de traces
  • Statistiques du noyau GPU
  • Outil de profil de mémoire
  • Visionneuse de pod

Page de présentation

La page de présentation fournit une vue de haut niveau des performances de votre modèle lors d'une exécution de profil. La page vous montre une page de présentation agrégée pour votre hôte et tous les appareils, et quelques recommandations pour améliorer les performances de formation de votre modèle. Vous pouvez également sélectionner des hôtes individuels dans la liste déroulante Hôte.

La page d'aperçu affiche les données comme suit :

image

  • Sommaire du rendement: Affiche un résumé de haut niveau de performance de votre modèle. Le résumé des performances comporte deux parties :

    1. Répartition du temps d'étape : répartit le temps d'étape moyen en plusieurs catégories d'endroits où le temps est passé :

      • Compilation : Temps passé à compiler les noyaux.
      • Entrée : Temps passé à lire les données d'entrée.
      • Sortie : temps passé à lire les données de sortie.
      • Lancement du noyau : temps passé par l'hôte pour lancer les noyaux
      • Temps de calcul de l'hôte..
      • Temps de communication appareil à appareil.
      • Temps de calcul sur l'appareil.
      • Tous les autres, y compris les frais généraux Python.
    2. Précisions de calcul du périphérique - Indique le pourcentage de temps de calcul du périphérique qui utilise des calculs 16 et 32 ​​bits.

  • Étape temps Graph: affiche un graphique de la durée de l' étape de dispositif (en millisecondes) au cours de toutes les étapes de l' échantillon. Chaque étape est divisée en plusieurs catégories (avec des couleurs différentes) où le temps est passé. La zone rouge correspond à la partie du pas de temps pendant laquelle les périphériques étaient inactifs en attendant les données d'entrée de l'hôte. La zone verte indique combien de temps l'appareil fonctionnait réellement.

  • Top 10 des opérations de tensorflow sur l' appareil (par exemple GPU): Affiche les ops sur périphérique qui ont fonctionné le plus long.

    Chaque ligne affiche le temps libre d'une opération (en pourcentage du temps pris par toutes les opérations), le temps cumulé, la catégorie et le nom.

  • Run Environnement: Affiche un résumé de haut niveau de l'environnement d'exécution de modèle comprenant:

    • Nombre d'hôtes utilisés.
    • Type d'appareil (GPU/TPU).
    • Nombre de cœurs de périphérique.
  • Recommandation pour la prochaine étape: Rapports lorsqu'un modèle est entrée lié et recommande des outils que vous pouvez utiliser pour localiser et goulots d' étranglement détermination de la performance du modèle.

Analyseur de pipeline d'entrée

Lorsqu'un programme TensorFlow lit les données d'un fichier, il commence en haut du graphique TensorFlow de manière pipeline. Le processus de lecture est divisé en plusieurs étages de traitement de données connectés en série, où la sortie d'un étage est l'entrée du suivant. Ce système de lecture de données est appelé le pipeline d'entrée.

Un pipeline typique de lecture d'enregistrements à partir de fichiers comporte les étapes suivantes :

  1. Lecture de fichiers.
  2. Prétraitement des fichiers (facultatif).
  3. Transfert de fichiers de l'hôte vers l'appareil.

Un pipeline d'entrée inefficace peut considérablement ralentir votre application. Une application est entrée considérée comme liée lorsqu'elle passe une partie importante du temps dans la canalisation d'entrée. Utilisez les informations obtenues à partir de l'analyseur de pipeline d'entrée pour comprendre où le pipeline d'entrée est inefficace.

L'analyseur de pipeline d'entrée vous indique immédiatement si votre programme est lié à l'entrée et vous guide à travers l'analyse côté périphérique et hôte pour déboguer les goulots d'étranglement des performances à n'importe quelle étape du pipeline d'entrée.

Consultez les conseils sur les performances du pipeline d'entrée pour connaître les meilleures pratiques recommandées pour optimiser vos pipelines d'entrée de données.

Tableau de bord du pipeline d'entrée

Pour ouvrir l'analyseur de pipeline d'entrée, sélectionnez le profil, puis sélectionnez input_pipeline_analyzer dans la liste déroulante Outils.

image

Le tableau de bord contient trois sections :

  1. Résumé: Résume le pipeline global d'entrée avec des informations sur votre demande si est entrée liée et, si oui, combien.
  2. Analyse du côté de l' appareil: Affiche détaillés, des résultats d'analyse du côté du dispositif, y compris le dispositif pas à temps et l'intervalle de temps de dispositif passé à attendre des données d'entrée à travers des noyaux à chaque étape.
  3. Analyse du côté de l' hôte: montre une analyse détaillée du côté de l' hôte, ainsi que la répartition du temps de traitement d'entrée sur l'hôte.

Résumé du pipeline d'entrée

Le résumé indique si votre programme est entré lié en présentant le pourcentage du temps de l' appareil consacré à l' attente pour l' entrée de l'hôte. Si vous utilisez un pipeline d'entrée standard qui a été instrumenté, l'outil indique où se passe la majeure partie du temps de traitement des entrées.

Analyse côté appareil

L'analyse côté appareil fournit des informations sur le temps passé sur l'appareil par rapport à l'hôte et sur le temps passé par l'appareil à attendre les données d'entrée de l'hôte.

  1. Temps de mise en route tracée en fonction de l'étape numéro: affiche un graphique de la durée de l' étape de l' appareil (en millisecondes) au cours de toutes les étapes de l' échantillon. Chaque étape est divisée en plusieurs catégories (avec des couleurs différentes) où le temps est passé. La zone rouge correspond à la partie du pas de temps pendant laquelle les périphériques étaient inactifs en attendant les données d'entrée de l'hôte. La zone verte indique combien de temps l'appareil fonctionnait réellement.
  2. Statistiques du temps d'étape: Rapports l'écart - type moyen, et la plage ([minimum, maximum]) de la durée de l' étape de l' appareil.

Analyse côté hôte

L'analyse côté hôte signale une répartition du temps de traitement d'entrée (le temps passé sur tf.data ops API) sur l'hôte en plusieurs catégories:

  • La lecture des données à partir des fichiers sur la demande: Le temps consacré à la lecture des données à partir de fichiers sans mise en cache, préchargement, et entrelacer.
  • La lecture des données à partir de fichiers à l' avance: Le temps passé à lire des fichiers, y compris la mise en cache, préchargement, et entrelacer.
  • Prétraiter des données: Le temps passé sur les opérations de pré - traitement, comme la décompression d'image.
  • Données mise en attente d'être transférés à un appareil: Le temps passé en mettant les données en file d' attente une entrée avant de transférer les données à l'appareil.

Développez Statistiques d' entrée Op pour inspecter les statistiques pour les opérations d'entrée et de leurs catégories ventilées par temps d'exécution.

image

Un tableau de données source apparaîtra avec chaque entrée contenant les informations suivantes :

  1. Entrée Op: Indique le nom op tensorflow de l'op d'entrée.
  2. Count: Indique le nombre total d'instances d'exécution op au cours de la période de profilage.
  3. Temps total (en ms): Indique la somme cumulée du temps consacré à chacun de ces cas.
  4. Durée totale%: Indique le temps total passé sur un op comme une fraction du temps total passé dans le traitement d'entrée.
  5. Temps total Self (en ms): Affiche la somme cumulée du temps libre consacré à chacun de ces cas. Le temps de soi mesure ici le temps passé à l'intérieur du corps de la fonction, à l'exclusion du temps passé dans la fonction qu'elle appelle.
  6. Proportion totale Temps%. Affiche le temps libre total sous forme de fraction du temps total consacré au traitement des entrées.
  7. Catégorie. Affiche la catégorie de traitement de l'op d'entrée.

Statistiques TensorFlow

L'outil TensorFlow Stats affiche les performances de chaque opération TensorFlow (op) exécutée sur l'hôte ou l'appareil au cours d'une session de profilage.

image

L'outil affiche des informations sur les performances dans deux volets :

  • Le volet supérieur affiche jusqu'à quatre graphiques à secteurs :

    1. La distribution du temps d'auto-exécution de chaque opération sur l'hôte.
    2. La distribution du temps d'auto-exécution de chaque type d'opération sur l'hôte.
    3. La distribution du temps d'auto-exécution de chaque opération sur l'appareil.
    4. La distribution du temps d'auto-exécution de chaque type d'opération sur l'appareil.
  • Le volet inférieur affiche un tableau qui rapporte des données sur les opérations TensorFlow avec une ligne pour chaque opération et une colonne pour chaque type de données (tri des colonnes en cliquant sur l'en-tête de la colonne). Cliquez sur le bouton Exporter au format CSV sur le côté droit du volet supérieur pour exporter les données de ce tableau sous forme de fichier CSV.

    Noter que:

    • Si des opérations ont des opérations enfants :

      • Le temps total « accumulé » d'une opération comprend le temps passé à l'intérieur des opérations enfants.
      • Le temps "soi" total d'une opération n'inclut pas le temps passé à l'intérieur des opérations enfants.
    • Si une opération s'exécute sur l'hôte :

      • Le pourcentage du temps libre total sur l'appareil encouru par l'op on sera 0.
      • Le pourcentage cumulé du temps libre total sur l'appareil jusqu'à et y compris cette opération sera de 0.
    • Si une opération s'exécute sur l'appareil :

      • Le pourcentage du temps libre total sur l'hôte encouru par cette opération sera de 0.
      • Le pourcentage cumulé du temps libre total sur l'hôte jusqu'à et y compris cette opération sera de 0.

Vous pouvez choisir d'inclure ou d'exclure le temps d'inactivité dans les graphiques à secteurs et le tableau.

Visionneuse de traces

La visionneuse de trace affiche une chronologie qui montre :

  • Durées des opérations exécutées par votre modèle TensorFlow
  • Quelle partie du système (hôte ou périphérique) a exécuté une opération. En règle générale, l'hôte exécute les opérations d'entrée, prétraite les données d'entraînement et les transfère vers l'appareil, tandis que l'appareil exécute l'entraînement du modèle réel.

La visionneuse de trace vous permet d'identifier les problèmes de performances dans votre modèle, puis de prendre des mesures pour les résoudre. Par exemple, à un niveau élevé, vous pouvez déterminer si l'entraînement par entrée ou par modèle prend la majorité du temps. En approfondissant, vous pouvez identifier les opérations qui prennent le plus de temps à s'exécuter. Notez que la visionneuse de trace est limitée à 1 million d'événements par appareil.

Interface de visualisation de traces

Lorsque vous ouvrez la visionneuse de trace, elle affiche votre exécution la plus récente :

image

Cet écran contient les éléments principaux suivants :

  1. Volet Chronologie: Spectacles ops que le périphérique et l'hôte exécuté au fil du temps.
  2. Volet Détails: affiche des informations supplémentaires pour les opérations sélectionnées dans le volet Timeline.

Le volet Chronologie contient les éléments suivants :

  1. Barre supérieure: Contient différents contrôles auxiliaires.
  2. L' axe du temps: temps Affiche par rapport au début de la trace.
  3. Section et piste des étiquettes: Chaque section contient plusieurs pistes et a un triangle sur la gauche que vous pouvez cliquer pour développer et réduire la section. Il y a une section pour chaque élément de traitement dans le système.
  4. Outil de sélection: Contient divers outils pour interagir avec le spectateur de trace tels que Zoom, Pan, Select et synchronisation. Utilisez l'outil Chronométrage pour marquer un intervalle de temps.
  5. Événements: Ceux - ci montrent le temps pendant lequel un op a été exécuté ou la durée des méta-événements, comme les étapes de formation.
Sections et pistes

La visionneuse de trace contient les sections suivantes :

  • Une section pour chaque noeud de dispositif, marqué avec le numéro de la puce de dispositif et le noeud de dispositif au sein de la puce (par exemple, /device:GPU:0 (pid 0) ). Chaque section de nœud de périphérique contient les pistes suivantes :
    • Étape: Affiche la durée des étapes de formation qui ont été en cours d' exécution sur l'appareil
    • Tensorflow Ops: Affiche les ops exécutées sur le dispositif
    • XLA Ops: Spectacles XLA opérations (ops) qui ont fonctionné sur l'appareil si XLA est le compilateur utilisé (chaque op tensorflow se traduit en une ou plusieurs opérations de XLA Le compilateur XLA traduit les opérations de XLA en code qui fonctionne sur l'appareil.).
  • Une section pour les threads en cours d' exécution sur le processeur de la machine hôte, étiqueté « Threads hôte ». La section contient une piste pour chaque thread CPU. Notez que vous pouvez ignorer les informations affichées à côté des étiquettes de section.
Événements

Les événements de la chronologie sont affichés dans différentes couleurs ; les couleurs elles-mêmes n'ont pas de signification particulière.

La visionneuse de traces peut également afficher des traces d'appels de fonction Python dans votre programme TensorFlow. Si vous utilisez l' tf.profiler.experimental.start API, vous pouvez activer le traçage Python en utilisant le ProfilerOptions namedtuple lors du démarrage de profilage. Par ailleurs, si vous utilisez le mode d'échantillonnage pour le profilage, vous pouvez sélectionner le niveau de traçage en utilisant les options déroulantes dans la boîte de dialogue du profil de capture.

image

Statistiques du noyau GPU

Cet outil affiche les statistiques de performances et l'opération d'origine pour chaque noyau accéléré par GPU.

image

L'outil affiche des informations dans deux volets :

  • Le volet supérieur affiche un graphique à secteurs qui montre les noyaux CUDA qui ont le temps total écoulé le plus élevé.

  • Le volet inférieur affiche un tableau avec les données suivantes pour chaque paire noyau-opération unique :

    • Un classement par ordre décroissant de la durée totale écoulée du GPU, regroupé par paire noyau-opération.
    • Le nom du noyau lancé.
    • Le nombre de registres GPU utilisés par le noyau.
    • La taille totale de la mémoire partagée (statique + partagée dynamique) utilisée en octets.
    • La dimension du bloc exprimée en blockDim.x, blockDim.y, blockDim.z .
    • Les dimensions de la grille exprimées en gridDim.x, gridDim.y, gridDim.z .
    • Que l'op est admissible à utiliser Cores Tensor .
    • Si le noyau contient des instructions Tensor Core.
    • Le nom de l'opération qui a lancé ce noyau.
    • Le nombre d'occurrences de cette paire noyau-opération.
    • Le temps GPU total écoulé en microsecondes.
    • Le temps GPU moyen écoulé en microsecondes.
    • Le temps GPU minimum écoulé en microsecondes.
    • Le temps GPU écoulé maximum en microsecondes.

Outil de profil de mémoire

L'outil Profil de la mémoire surveille l'utilisation de la mémoire de votre appareil pendant l'intervalle de profilage. Vous pouvez utiliser cet outil pour :

  • Déboguez les problèmes de mémoire insuffisante (MOO) en identifiant l'utilisation maximale de la mémoire et l'allocation de mémoire correspondante aux opérations TensorFlow. Vous pouvez également déboguer les problèmes OOM qui peuvent survenir lorsque vous exécutez plusieurs mutualisée inférence.
  • Déboguez les problèmes de fragmentation de la mémoire.

L'outil de profil de mémoire affiche les données en trois sections :

  1. Résumé du profil de mémoire
  2. Graphique de la chronologie de la mémoire
  3. Tableau de répartition de la mémoire

Résumé du profil de mémoire

Cette section affiche un résumé de haut niveau du profil de mémoire de votre programme TensorFlow, comme illustré ci-dessous :

Le résumé du profil de mémoire comporte six champs :

  1. ID de mémoire: Dropdown qui énumère tous les systèmes de mémoire de l' appareil disponible. Sélectionnez le système de mémoire que vous souhaitez afficher dans la liste déroulante.
  2. #Allocation: Le nombre d'allocations de mémoire effectuées pendant l'intervalle de profilage.
  3. #Deallocation: Le nombre de libérations de mémoire dans l'intervalle de profilage
  4. Capacité de la mémoire: La capacité totale (en GIB) du système de mémoire que vous sélectionnez.
  5. Utilisation maximale du Heap: L'utilisation de la mémoire de pointe (en GIB) puisque le modèle a commencé à courir.
  6. Utilisation pic mémoire: L'utilisation de la mémoire de crête (en GIBS) dans l'intervalle de profilage. Ce champ contient les sous-champs suivants :
    1. Timestamp: l'horodatage de l'utilisation de la mémoire maximale a été atteinte dans le scénario graphique.
    2. Stack Réservation: quantité de mémoire réservée sur la pile (en GIB).
    3. Heap Allocation: quantité de mémoire allouée sur le tas (en GIBS).
    4. Mémoire libre: quantité de mémoire libre (en GIB). La capacité de mémoire est la somme totale de la réservation de pile, de l'allocation de tas et de la mémoire libre.
    5. Fragmentation: Le pourcentage de fragmentation (plus faible est le meilleur). Il est calculé en pourcentage de (1 - Size of the largest chunk of free memory / Total free memory) la (1 - Size of the largest chunk of free memory / Total free memory) .

Graphique chronologique de la mémoire

Cette section affiche un graphique de l'utilisation de la mémoire (en Gio) et du pourcentage de fragmentation en fonction du temps (en ms).

image

L'axe X représente la chronologie (en ms) de l'intervalle de profilage. L'axe Y sur la gauche représente l'utilisation de la mémoire (en Gio) et l'axe Y sur la droite représente le pourcentage de fragmentation. A chaque instant sur l'axe X, la mémoire totale est décomposée en trois catégories : pile (en rouge), tas (en orange) et libre (en vert). Survolez un horodatage spécifique pour afficher les détails des événements d'allocation/désallocation de mémoire à ce stade, comme ci-dessous :

image

La fenêtre contextuelle affiche les informations suivantes :

  • horodatage (ms): L'emplacement de l'événement sélectionné sur la ligne de temps.
  • action: Le type d'événement (allocation ou la désallocation).
  • requested_size (GIB): La quantité de mémoire demandé. Ce sera un nombre négatif pour les événements de désallocation.
  • allocation_size (clavettes): la quantité réelle de mémoire allouée. Ce sera un nombre négatif pour les événements de désallocation.
  • tf_op: L'op tensorflow qui demande l'allocation / désallocation.
  • step_id: L'étape de formation dans laquelle cet événement a eu lieu.
  • region_type: le type d'entité de données que la mémoire allouée est pour. Les valeurs possibles sont temp pour temporaires, la output pour les activations et les gradients, et persist / dynamic pour des poids et des constantes.
  • data_type: Le type d'élément de tenseur (par exemple, pour uint8 nombre entier non signé de 8 bits).
  • tensor_shape: La forme du tenseur étant répartie / désallouée.
  • memory_in_use (clavettes): La mémoire totale qui est en cours d' utilisation à ce point de temps.

Tableau de répartition de la mémoire

Ce tableau affiche les allocations de mémoire actives au moment de l'utilisation maximale de la mémoire dans l'intervalle de profilage.

image

Il y a une ligne pour chaque opération TensorFlow et chaque ligne comporte les colonnes suivantes :

  • Op Nom: Le nom de l'op tensorflow.
  • Taille d'allocation (GIB): Le montant total de la mémoire allouée à cette op.
  • Taille demandé (GIB): Le montant total de la mémoire requise pour cette op.
  • Occurrence: Le nombre d'allocations pour cette op.
  • Type de région: Le type d'entité de données que cette mémoire allouée est pour. Les valeurs possibles sont temp pour temporaires, la output pour les activations et les gradients, et persist / dynamic pour des poids et des constantes.
  • Type de données: Le type d'élément de tenseur.
  • Forme: La forme des tenseurs alloués.

Visionneuse de pod

L'outil Pod Viewer montre la répartition d'une étape de formation pour tous les travailleurs.

image

  • Le volet supérieur a un curseur pour sélectionner le numéro d'étape.
  • Le volet inférieur affiche un graphique à colonnes empilées. Il s'agit d'une vue de haut niveau des catégories de pas de temps décomposées placées les unes au-dessus des autres. Chaque colonne empilée représente un travailleur unique.
  • Lorsque vous survolez une colonne empilée, la carte sur le côté gauche affiche plus de détails sur la répartition des étapes.

analyse des goulots d'étranglement tf.data

Le tf.data outil d'analyse de goulot d' étranglement détecte automatiquement les goulots d' étranglement dans tf.data conduites d'entrée dans votre programme et fournit des recommandations sur la façon de les corriger. Il fonctionne avec tout programme en utilisant tf.data quelle que soit la plate - forme (CPU / GPU / TPU). L'analyse et les recommandations sont basées sur ce manuel .

Il détecte un goulot d'étranglement en suivant ces étapes :

  1. Trouvez l'hôte le plus lié à l'entrée.
  2. Trouver la plus lente exécution d'un tf.data pipeline d'entrée.
  3. Reconstruisez le graphique du pipeline d'entrée à partir de la trace du profileur.
  4. Recherchez le chemin critique dans le graphique du pipeline d'entrée.
  5. Identifiez la transformation la plus lente sur le chemin critique comme un goulot d'étranglement.

L'interface est divisée en trois sections: Analyse des performances Résumé, résumé de toutes les entrées et les pipelines d' entrée de pipeline graphique.

Résumé de l'analyse des performances

image

Cette section présente le résumé de l'analyse. Il rend compte de la lenteur tf.data pipelines d'entrée détectés dans le profil. Cette section montre également l'hôte le plus lié aux entrées et son pipeline d'entrée le plus lent avec la latence maximale. Plus important encore, il identifie quelle partie du pipeline d'entrée est le goulot d'étranglement et comment le corriger. Les informations sur le goulot d'étranglement sont fournies avec le type d'itérateur et son nom long.

Comment lire le nom long de l'itérateur tf.data

Un nom long est formaté comme Iterator::<Dataset_1>::...::<Dataset_n> . Au nom long, <Dataset_n> correspond au type iterator et les autres jeux de données du nom long représentent des transformations en aval.

Par exemple, considérons l'ensemble de données de pipeline d'entrée suivant :

dataset = tf.data.Dataset.range(10).map(lambda x: x).repeat(2).batch(5)

Les noms longs des itérateurs de l'ensemble de données ci-dessus seront :

Type d'itérateur Nom long
Varier Iterator::Batch::Repeat::Map::Range
Carte Iterator::Batch::Repeat::Map
Répéter Iterator::Batch::Repeat
Grouper Itérateur :: Lot

Résumé de tous les pipelines d'entrée

image

Cette section fournit le résumé de tous les pipelines d'entrée sur tous les hôtes. En règle générale, il existe un seul pipeline d'entrée. Lors de l' utilisation de la stratégie de distribution, il y a une canalisation d'entrée d'hôte en cours d' exécution du programme tf.data code et de canalisations d'entrée de dispositif multiples récupération des données à partir de la canalisation d'entrée d'hôte et de le transférer aux dispositifs.

Pour chaque pipeline d'entrée, il affiche les statistiques de son temps d'exécution. Un appel est compté comme lent s'il dure plus de 50 s.

Graphique du pipeline d'entrée

image

Cette section présente le graphique du pipeline d'entrée avec les informations sur le temps d'exécution. Vous pouvez utiliser "Host" et "Input Pipeline" pour choisir l'hôte et le pipeline d'entrée à voir. Exécutions du pipeline d'entrée sont triés par le temps d'exécution dans l' ordre décroissant que vous pouvez choisir en utilisant le menu déroulant Rank.

image

Les nœuds sur le chemin critique ont des contours en gras. Le nœud de goulot d'étranglement, qui est le nœud avec le temps de self le plus long sur le chemin critique, a un contour rouge. Les autres nœuds non critiques ont des contours en pointillés gris.

Dans chaque nœud, Start Time indique l'heure de début de l'exécution. Le même nœud peut être exécuté plusieurs fois, par exemple, s'il y a un Batch op dans la canalisation d'entrée. S'il est exécuté plusieurs fois, il s'agit de l'heure de début de la première exécution.

Durée totale est le temps de mur de l'exécution. S'il est exécuté plusieurs fois, il s'agit de la somme des temps de mur de toutes les exécutions.

Le temps est auto Temps total sans temps chevauchée avec ses nœuds enfants immédiats.

"# Calls" est le nombre de fois que le pipeline d'entrée est exécuté.

Collecter des données de performances

TensorFlow Profiler collecte les activités de l'hôte et les traces GPU de votre modèle TensorFlow. Vous pouvez configurer le profileur pour collecter des données de performances via le mode de programmation ou le mode d'échantillonnage.

API de profilage

Vous pouvez utiliser les API suivantes pour effectuer le profilage.

  • Le mode de programmation en utilisant la TensorBoard Keras Callback ( tf.keras.callbacks.TensorBoard )

    # Profile from batches 10 to 15
    tb_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir,
                                                 profile_batch='10, 15')
    
    # Train the model and use the TensorBoard Keras callback to collect
    # performance profiling data
    model.fit(train_data,
              steps_per_epoch=20,
              epochs=5,
              callbacks=[tb_callback])
    
  • Le mode de programmation en utilisant la tf.profiler API Fonction

    tf.profiler.experimental.start('logdir')
    # Train the model here
    tf.profiler.experimental.stop()
    
  • Mode programmatique utilisant le gestionnaire de contexte

    with tf.profiler.experimental.Profile('logdir'):
        # Train the model here
        pass
    

  • Mode d' échantillonnage: Effectuer la demande en utilisant le profilage tf.profiler.experimental.server.start pour démarrer un serveur GRPC avec votre course modèle tensorflow. Après avoir démarré le serveur GRPC et l' exécution de votre modèle, vous pouvez capturer un profil via le bouton profil de capture dans le plugin profil TensorBoard. Utilisez le script de la section Installer le profileur ci-dessus pour lancer une instance TensorBoard si elle n'est pas déjà en cours d'exécution.

    Par exemple,

    # Start a profiler server before your model runs.
    tf.profiler.experimental.server.start(6009)
    # (Model code goes here).
    #  Send a request to the profiler server to collect a trace of your model.
    tf.profiler.experimental.client.trace('grpc://localhost:6009',
                                          'gs://your_tb_logdir', 2000)
    

    Exemple de profilage de plusieurs travailleurs :

    # E.g. your worker IP addresses are 10.0.0.2, 10.0.0.3, 10.0.0.4, and you
    # would like to profile for a duration of 2 seconds.
    tf.profiler.experimental.client.trace(
        'grpc://10.0.0.2:8466,grpc://10.0.0.3:8466,grpc://10.0.0.4:8466',
        'gs://your_tb_logdir',
        2000)
    

Utilisez la boîte de dialogue du profil de capture pour spécifier:

  • Une liste délimitée par des virgules d'URL de service de profil ou de noms TPU.
  • Une durée de profilage.
  • Le niveau de traçage des appels de fonction d'appareil, d'hôte et Python.
  • Combien de fois voulez-vous que le profileur réessaye de capturer des profils en cas d'échec au début.

Profilage de boucles d'entraînement personnalisées

Pour le profil de boucles de formation personnalisée dans votre code tensorflow, instrument de la boucle d'entraînement avec l' tf.profiler.experimental.Trace API pour marquer les limites de l' étape pour le Générateur de profils.

Le name argument est utilisé comme préfixe pour les noms étape, le step_num argument mot - clé est ajouté au nom de l' étape, et le _r argument mot - clé fait cet événement trace se traité comme un événement étape par le Générateur de profils.

Par exemple,

for step in range(NUM_STEPS):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_data = next(dataset)
        train_step(train_data)

Cela activera l'analyse des performances basée sur les étapes du profileur et provoquera l'affichage des événements d'étape dans la visionneuse de trace.

Assurez - vous que vous incluez l'ensemble de données iterator dans le tf.profiler.experimental.Trace contexte pour une analyse précise de la canalisation d'entrée.

L'extrait de code ci-dessous est un anti-modèle :

for step, train_data in enumerate(dataset):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_step(train_data)

Profilage des cas d'utilisation

Le profileur couvre un certain nombre de cas d'utilisation selon quatre axes différents. Certaines des combinaisons sont actuellement prises en charge et d'autres seront ajoutées à l'avenir. Certains des cas d'utilisation sont :

  • Par rapport à profilage à distance local: Ce sont deux façons communes de la configuration de votre environnement de profilage. Dans le profilage local, l'API de profilage est appelée sur la même machine que votre modèle exécute, par exemple, un poste de travail local avec des GPU. Dans le profilage à distance, l'API de profilage est appelée sur une machine différente de celle sur laquelle votre modèle s'exécute, par exemple, sur un Cloud TPU.
  • Le profilage des travailleurs multiples: Vous pouvez profiler plusieurs machines lors de l' utilisation des capacités de formation distribués de tensorflow.
  • Plate - forme matérielle: processeurs Profil, processeurs graphiques et PUT.

Le tableau ci-dessous fournit un aperçu rapide des cas d'utilisation pris en charge par TensorFlow mentionnés ci-dessus :

API de profilage Local À distance Travailleurs multiples Plateformes matérielles
Rappel de TensorBoard Keras Prise en charge Non supporté Non supporté CPU, GPU
tf.profiler.experimental démarrage / arrêt API Prise en charge Non supporté Non supporté CPU, GPU
tf.profiler.experimental client.trace API Prise en charge Prise en charge Prise en charge CPU, GPU, TPU
API du gestionnaire de contexte Prise en charge Non supporté Non supporté CPU, GPU

Meilleures pratiques pour des performances de modèle optimales

Utilisez les recommandations suivantes applicables à vos modèles TensorFlow afin d'obtenir des performances optimales.

En général, effectuez toutes les transformations sur l'appareil et assurez-vous d'utiliser la dernière version compatible de bibliothèques telles que cuDNN et Intel MKL pour votre plate-forme.

Optimiser le pipeline de données d'entrée

Utilisez les données de [#input_pipeline_analyzer] pour optimiser votre pipeline d'entrée de données. Un pipeline d'entrée de données efficace peut considérablement améliorer la vitesse d'exécution de votre modèle en réduisant le temps d'inactivité de l'appareil. Essayez d'intégrer les meilleures pratiques détaillées dans la Meilleure performance avec l'API tf.data Guide et ci - dessous pour faire votre pipeline d'entrée de données plus efficace.

  • En général, la parallélisation de toutes les opérations qui n'ont pas besoin d'être exécutées de manière séquentielle peut considérablement optimiser le pipeline d'entrée de données.

  • Dans de nombreux cas, il est utile de modifier l'ordre de certains appels ou d'ajuster les arguments de manière à ce que cela fonctionne le mieux pour votre modèle. Lors de l'optimisation du pipeline de données d'entrée, comparez uniquement le chargeur de données sans les étapes d'apprentissage et de rétropropagation pour quantifier l'effet des optimisations de manière indépendante.

  • Essayez d'exécuter votre modèle avec des données synthétiques pour vérifier si le pipeline d'entrée est un goulot d'étranglement des performances.

  • Utilisation tf.data.Dataset.shard pour la formation multi-GPU. Assurez-vous de partitionner très tôt dans la boucle d'entrée pour éviter les réductions de débit. Lorsque vous travaillez avec des TFRecords, assurez-vous de partager la liste des TFRecords et non le contenu des TFRecords.

  • Paralléliser plusieurs ops en fixant dynamiquement la valeur de num_parallel_calls utilisant tf.data.AUTOTUNE .

  • Envisager de limiter l'utilisation de tf.data.Dataset.from_generator comme il est plus lent par rapport aux opérations de tensorflow pures.

  • Envisager de limiter l'utilisation de tf.py_function car il ne peut pas être sérialisé et n'est pas pris en charge pour fonctionner en tensorflow distribués.

  • Utilisez tf.data.Options pour contrôler les optimisations statiques à la canalisation d'entrée.

Lisez également la tf.data analyse des performances Guide pour plus de conseils sur l' optimisation de votre pipeline d'entrée.

Optimiser l'augmentation des données

Lorsque vous travaillez avec des données d'image, faites votre augmentation de données plus efficace par coulée à différents types de données après l' application de transformations spatiales, telles que le retournement, le recadrage, rotation, etc.

Utiliser NVIDIA® DALI

Dans certains cas, comme lorsque vous avez un système avec un ratio GPU/CPU élevé, toutes les optimisations ci-dessus peuvent ne pas suffire à éliminer les goulots d'étranglement dans le chargeur de données dus aux limitations des cycles CPU.

Si vous utilisez des applications processeurs graphiques NVIDIA® pour d'apprentissage en profondeur la vision par ordinateur et audio, utilisez la bibliothèque Chargement des données ( DALI ) pour accélérer le pipeline de données.

Vérifiez la NVIDIA® DALI: Opérations documentation pour une liste des opérations DALI pris en charge.

Utiliser le threading et l'exécution parallèle

Exécuter ops sur plusieurs threads CPU avec l' tf.config.threading API pour les exécuter plus rapidement.

TensorFlow définit automatiquement le nombre de threads de parallélisme par défaut. Le pool de threads disponible pour l'exécution des opérations TensorFlow dépend du nombre de threads CPU disponibles.

Contrôler l'accélération parallèle maximum pour un seul op en utilisant tf.config.threading.set_intra_op_parallelism_threads . Notez que si vous exécutez plusieurs opérations en parallèle, elles partageront toutes le pool de threads disponible.

Si vous avez des opérations indépendantes de non-blocage (ops sans chemin dirigé entre eux sur le graphique), utilisez tf.config.threading.set_inter_op_parallelism_threads pour les exécuter en utilisant en même temps que le pool de threads disponibles.

Divers

Lorsque vous travaillez avec des modèles plus petits sur les processeurs graphiques NVIDIA®, vous pouvez définir tf.compat.v1.ConfigProto.force_gpu_compatible=True pour forcer tous les tenseurs CPU à allouer CUDA mémoire épinglé pour donner un coup de pouce significatif à la performance du modèle. Cependant, soyez prudent lorsque vous utilisez cette option pour des modèles inconnus/très volumineux, car cela pourrait avoir un impact négatif sur les performances de l'hôte (CPU).

Améliorer les performances de l'appareil

Suivez les meilleures pratiques décrites ici et dans le guide d'optimisation des performances du GPU pour optimiser la performance sur l'appareil de modèle tensorflow.

Si vous utilisez des GPU NVIDIA, enregistrez l'utilisation du GPU et de la mémoire dans un fichier CSV en exécutant :

nvidia-smi
--query-gpu=utilization.gpu,utilization.memory,memory.total,
memory.free,memory.used --format=csv

Configurer la disposition des données

Lorsque vous travaillez avec des données contenant des informations sur les canaux (comme des images), optimisez le format de mise en page des données pour privilégier les canaux en dernier (NHWC sur NCHW).

Channel-derniers formats de données améliorent Tensor de base d' utilisation et apportent des améliorations de performances significatives en particulier dans les modèles convolutifs lorsqu'il est associé aux AMP. Les dispositions de données NCHW peuvent toujours être exploitées par Tensor Cores, mais introduisent une surcharge supplémentaire en raison des opérations de transposition automatique.

Vous pouvez optimiser la mise en page des données mises en page à préférer NHWC en définissant data_format="channels_last" pour les couches telles que tf.keras.layers.Conv2D , tf.keras.layers.Conv3D et tf.keras.layers.RandomRotation .

Utilisez tf.keras.backend.set_image_data_format pour définir le format de mise en page de données par défaut de l'API back - end Keras.

Maximiser le cache L2

When working with NVIDIA® GPUs, execute the code snippet below before the training loop to max out the L2 fetch granularity to 128 bytes.

import ctypes

_libcudart = ctypes.CDLL('libcudart.so')
# Set device limit on the current device
# cudaLimitMaxL2FetchGranularity = 0x05
pValue = ctypes.cast((ctypes.c_int*1)(), ctypes.POINTER(ctypes.c_int))
_libcudart.cudaDeviceSetLimit(ctypes.c_int(0x05), ctypes.c_int(128))
_libcudart.cudaDeviceGetLimit(pValue, ctypes.c_int(0x05))
assert pValue.contents.value == 128

Configure GPU thread usage

The GPU thread mode decides how GPU threads are used.

Set the thread mode to gpu_private to make sure that preprocessing does not steal all the GPU threads. This will reduce the kernel launch delay during training. You can also set the number of threads per GPU. Set these values using environment variables.

import os

os.environ['TF_GPU_THREAD_MODE']='gpu_private'
os.environ['TF_GPU_THREAD_COUNT']='1'

Configure GPU memory options

In general, increase the batch size and scale the model to better utilize GPUs and get higher throughput. Note that increasing the batch size will change the model's accuracy so the model needs to be scaled by tuning hyperparameters like the learning rate to meet the target accuracy.

Also, use tf.config.experimental.set_memory_growth to allow GPU memory to grow to prevent all the available memory from being fully allocated to ops that require only a fraction of the memory. This allows other processes which consume GPU memory to run on the same device.

To learn more, check out the Limiting GPU memory growth guidance in the GPU guide to learn more.

Miscellaneous

  • Increase the training mini-batch size (number of training samples used per device in one iteration of the training loop) to the maximum amount that fits without an out of memory (OOM) error on the GPU. Increasing the batch size impacts the model's accuracy—so make sure you scale the model by tuning hyperparameters to meet the target accuracy.

  • Disable reporting OOM errors during tensor allocation in production code. Set report_tensor_allocations_upon_oom=False in tf.compat.v1.RunOptions .

  • For models with convolution layers, remove bias addition if using batch normalization. Batch normalization shifts values by their mean and this removes the need to have a constant bias term.

  • Use TF Stats to find out how efficiently on-device ops run.

  • Use tf.function to perform computations and optionally, enable the jit_compile=True flag ( tf.function(jit_compile=True ). To learn more, go to Use XLA tf.function .

  • Minimize host Python operations between steps and reduce callbacks. Calculate metrics every few steps instead of at every step.

  • Keep the device compute units busy.

  • Send data to multiple devices in parallel.

  • Consider using 16-bit numerical representations , such as fp16 —the half-precision floating point format specified by IEEE—or the Brain floating-point bfloat16 format.

Additional resources

Known limitations

Profiling multiple GPUs on TensorFlow 2.2 and TensorFlow 2.3

TensorFlow 2.2 and 2.3 support multiple GPU profiling for single host systems only; multiple GPU profiling for multi-host systems is not supported. To profile multi-worker GPU configurations, each worker has to be profiled independently. From TensorFlow 2.4 multiple workers can be profiled using the tf.profiler.experimental.client.trace API.

CUDA® Toolkit 10.2 or later is required to profile multiple GPUs. As TensorFlow 2.2 and 2.3 support CUDA® Toolkit versions only up to 10.1, you need to create symbolic links to libcudart.so.10.1 and libcupti.so.10.1 :

sudo ln -s /usr/local/cuda/lib64/libcudart.so.10.2 /usr/local/cuda/lib64/libcudart.so.10.1
sudo ln -s /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.2 /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.1