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é :
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).
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 deswift-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 valeursFloat
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 S4TFLong
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.