Débogage des problèmes X10

Le backend de l'accélérateur X10 peut fournir un débit nettement plus élevé pour le calcul parallèle basé sur des graphes, mais son traçage différé et sa compilation juste à temps peuvent parfois conduire à un comportement non évident. Cela peut inclure une recompilation fréquente des traces en raison de changements de forme de graphique ou de tenseur, ou de graphiques volumineux entraînant des problèmes de mémoire lors de la compilation.

Une façon de diagnostiquer les problèmes consiste à utiliser les métriques et compteurs d’exécution fournis par X10. La première chose à vérifier lorsqu'un modèle est lent est de générer un rapport de métriques.

Métrique

Pour imprimer un rapport de métriques, ajoutez un appel PrintX10Metrics() à votre programme :

import TensorFlow

...
PrintX10Metrics()
...

Cela enregistrera diverses métriques et compteurs au niveau INFO .

Comprendre le rapport de métriques

Le rapport comprend des éléments tels que :

  • Combien de fois déclenchons-nous les compilations XLA et le temps total passé à la compilation.
  • Combien de fois nous lançons un calcul XLA et le temps total passé à l'exécution.
  • Combien de données d'appareil nous créons/détruisons, etc.

Ces informations sont rapportées en termes de centiles des échantillons. Un exemple est :

Metric: CompileTime
  TotalSamples: 202
  Counter: 06m09s401ms746.001us
  ValueRate: 778ms572.062us / second
  Rate: 0.425201 / second
  Percentiles: 1%=001ms32.778us; 5%=001ms61.283us; 10%=001ms79.236us; 20%=001ms110.973us; 50%=001ms228.773us; 80%=001ms339.183us; 90%=001ms434.305us; 95%=002ms921.063us; 99%=21s102ms853.173us

Nous fournissons également des compteurs, appelés variables entières, qui suivent l'état interne du logiciel. Par exemple:

Counter: CachedSyncTensors
  Value: 395

Mises en garde connues

Tensor soutenus par X10 se comportent sémantiquement comme les Tensor en mode impatient par défaut. Cependant, il existe quelques mises en garde en matière de performances et d'exhaustivité :

  1. Performances dégradées à cause d'un trop grand nombre de recompilations.

    La compilation XLA coûte cher. X10 recompile automatiquement le graphique chaque fois que de nouvelles formes sont rencontrées, sans intervention de l'utilisateur. Les modèles doivent voir les formes stabilisées en quelques étapes de formation et à partir de ce moment, aucune recompilation n'est nécessaire. De plus, les chemins d'exécution doivent se stabiliser rapidement pour la même raison : X10 se recompile lorsqu'un nouveau chemin d'exécution est rencontré. En résumé, afin d'éviter les recompilations :

    • Évitez les formes dynamiques très variables. Cependant, un faible nombre de formes différentes pourrait convenir. Rembourrez les tenseurs à des tailles fixes lorsque cela est possible.
    • Évitez les boucles avec un nombre différent d'itérations entre les étapes d'entraînement. X10 déroule actuellement les boucles, donc un nombre différent d'itérations de boucle se traduit par différents chemins d'exécution (déroulés).
  2. Un petit nombre d'opérations ne sont pas encore prises en charge par X10.

    Nous avons actuellement une poignée d'opérations qui ne sont pas prises en charge, soit parce qu'il n'existe pas de bon moyen de les exprimer via XLA et des formes statiques (actuellement uniquement nonZeroIndices ), soit par manque de cas d'utilisation connus (plusieurs opérations d'algèbre linéaire et initialisation multinomiale). . Alors que la deuxième catégorie est facile à traiter selon les besoins, la première catégorie ne peut être abordée que grâce à l'interopérabilité avec le CPU, implémentation non XLA. Utiliser trop souvent l’interopérabilité a des implications significatives en termes de performances en raison des allers-retours des hôtes et de la fragmentation d’un modèle entièrement fusionné en plusieurs traces. Il est donc conseillé aux utilisateurs d'éviter d'utiliser de telles opérations dans leurs modèles.

    Sous Linux, utilisez XLA_SAVE_TENSORS_FILE (documenté dans la section suivante) pour obtenir la trace de la pile Swift qui a appelé l'opération non prise en charge. Les noms de fonctions peuvent être démêlés manuellement à l'aide de swift-demangle .

Obtention et représentation graphique de traces

Si vous soupçonnez qu'il y a des problèmes avec la façon dont les graphiques sont tracés, ou si vous souhaitez comprendre le processus de traçage, des outils sont fournis pour vous déconnecter et visualiser les traces. Vous pouvez demander à X10 de déconnecter les traces qu'il trouve en définissant la variable d'environnement XLA_SAVE_TENSORS_FILE :

export XLA_SAVE_TENSORS_FILE=/home/person/TraceLog.txt

Ces journaux de trace sont disponibles en trois formats : text , hlo et dot , le format pouvant être défini via la variable d'environnement XLA_SAVE_TENSORS_FMT :

export XLA_SAVE_TENSORS_FMT=text

Lorsque vous exécutez votre application, la représentation text déconnectée affichera chaque trace individuelle dans une notation textuelle de haut niveau utilisée par X10. La représentation hlo montre la représentation intermédiaire transmise au compilateur XLA. Vous souhaiterez peut-être limiter le nombre d'itérations dans vos boucles d'entraînement ou de calcul pour éviter que ces journaux ne deviennent trop volumineux. De plus, chaque exécution de votre application sera ajoutée à ce fichier, vous souhaiterez donc peut-être le supprimer entre les exécutions.

La définition de la variable XLA_LOG_GRAPH_CHANGES sur 1 indiquera également dans le journal de trace où les modifications dans le graphique se sont produites. Ceci est extrêmement utile pour trouver les endroits où la recompilation aura lieu.

Pour une représentation visuelle d'une trace, l'option dot déconnectera les graphiques compatibles Graphviz. Si vous extrayez la partie d'une trace qui ressemble à

digraph G {
    ...
}

dans son propre fichier, Graphviz (en supposant qu'il soit installé) peut générer un diagramme visuel via

dot -Tpng trace.dot -o trace.png

Notez que la définition de la variable d'environnement XLA_SAVE_TENSORS_FILE , en particulier lorsqu'elle est utilisée en combinaison avec XLA_LOG_GRAPH_CHANGES , aura un impact négatif substantiel sur les performances. Utilisez-les uniquement lors du débogage et non pour un fonctionnement régulier.

Variables d'environnement supplémentaires

Les variables d'environnement supplémentaires pour le débogage incluent :

  • XLA_USE_BF16 : Si défini sur 1, transforme toutes les valeurs Float en BF16. Ne doit être utilisé que pour le débogage puisque nous proposons une précision mixte automatique.

  • XLA_USE_32BIT_LONG : Si défini sur 1, mappe le type S4TF Long au type entier XLA 32 bits. Sur TPU, les calculs d'entiers 64 bits sont coûteux, donc la définition de cet indicateur peut être utile. Bien entendu, l'utilisateur doit être certain que les valeurs tiennent toujours dans un entier de 32 bits.