Depurando problemas do X10

O back-end do acelerador X10 pode fornecer rendimento significativamente maior para computação paralela baseada em gráfico, mas seu rastreamento adiado e compilação just-in-time podem às vezes levar a um comportamento não óbvio. Isso pode incluir recompilação frequente de rastreamentos devido a alterações na forma do gráfico ou do tensor, ou gráficos enormes que levam a problemas de memória durante a compilação.

Uma maneira de diagnosticar problemas é usar as métricas e contadores de execução fornecidos pelo X10. A primeira coisa a verificar quando um modelo está lento é gerar um relatório de métricas.

Métricas

Para imprimir um relatório de métricas, adicione uma chamada PrintX10Metrics() ao seu programa:

import TensorFlow

...
PrintX10Metrics()
...

Isso registrará várias métricas e contadores no nível INFO .

Compreendendo o relatório de métricas

O relatório inclui coisas como:

  • Quantas vezes acionamos compilações XLA e o tempo total gasto na compilação.
  • Quantas vezes lançamos um cálculo XLA e o tempo total gasto na execução.
  • Quantos manipuladores de dados de dispositivos criamos/destruímos, etc.

Esta informação é reportada em termos de percentis das amostras. Um exemplo é:

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

Também fornecemos contadores, chamados de variáveis ​​inteiras que rastreiam o status interno do software. Por exemplo:

Counter: CachedSyncTensors
  Value: 395

Advertências conhecidas

Tensor s apoiados por X10 se comportam semanticamente como Tensor s de modo ansioso padrão. No entanto, existem algumas advertências de desempenho e integridade:

  1. Desempenho degradado devido a muitas recompilações.

    A compilação XLA é cara. O X10 recompila automaticamente o gráfico sempre que novas formas são encontradas, sem intervenção do usuário. Os modelos precisam ver formas estabilizadas em algumas etapas de treinamento e, a partir desse ponto, nenhuma recompilação é necessária. Além disso, os caminhos de execução devem se estabilizar rapidamente pelo mesmo motivo: o X10 recompila quando um novo caminho de execução é encontrado. Resumindo, para evitar recompilações:

    • Evite formas dinâmicas altamente variáveis. No entanto, um pequeno número de formas diferentes pode servir. Pad tensores para tamanhos fixos quando possível.
    • Evite loops com diferentes números de iterações entre as etapas de treinamento. Atualmente, o X10 desenrola loops, portanto, diferentes números de iterações de loop se traduzem em diferentes caminhos de execução (desenrolados).
  2. Um pequeno número de operações ainda não é suportado pelo X10.

    Atualmente temos algumas operações que não são suportadas, seja porque não há uma boa maneira de expressá-las via XLA e formas estáticas (atualmente apenas nonZeroIndices ) ou porque não há casos de uso conhecidos (várias operações de álgebra linear e inicialização multinomial) . Embora a segunda categoria seja fácil de resolver conforme necessário, a primeira categoria só pode ser abordada através da interoperabilidade com a CPU, implementação não XLA. Usar a interoperabilidade com muita frequência tem implicações significativas no desempenho devido às viagens de ida e volta do host e à fragmentação de um modelo totalmente fundido em vários rastreamentos. Os usuários são, portanto, aconselhados a evitar o uso de tais operações em seus modelos.

    No Linux, use XLA_SAVE_TENSORS_FILE (documentado na próxima seção) para obter o rastreamento de pilha Swift que chamou a operação não suportada. Os nomes das funções podem ser desmontados manualmente usando swift-demangle .

Obtenção e gráficos de traços

Se você suspeitar que há problemas com a maneira como os gráficos estão sendo rastreados ou quiser entender o processo de rastreamento, serão fornecidas ferramentas para efetuar logout e visualizar os rastreamentos. Você pode fazer com que o X10 efetue logout dos rastreamentos encontrados definindo a variável de ambiente XLA_SAVE_TENSORS_FILE :

export XLA_SAVE_TENSORS_FILE=/home/person/TraceLog.txt

Esses logs de rastreamento vêm em três formatos: text , hlo e dot , com formato configurável por meio da variável de ambiente XLA_SAVE_TENSORS_FMT:

export XLA_SAVE_TENSORS_FMT=text

Quando você executa seu aplicativo, a representação text desconectada mostrará cada traço individual em uma notação de texto de alto nível usada pelo X10. A representação hlo mostra a representação intermediária que é passada para o compilador XLA. Talvez você queira restringir o número de iterações em seus loops de treinamento ou cálculo para evitar que esses logs se tornem muito grandes. Além disso, cada execução do seu aplicativo será anexada a esse arquivo, portanto, você pode excluí-lo entre as execuções.

Definir a variável XLA_LOG_GRAPH_CHANGES como 1 também indicará no log de rastreamento onde ocorreram alterações no gráfico. Isso é extremamente útil para encontrar locais onde ocorrerá a recompilação.

Para uma representação visual de um traço, a opção dot desconectará os gráficos compatíveis com Graphviz. Se você extrair a parte de um traço que se parece com

digraph G {
    ...
}

em seu próprio arquivo, o Graphviz (supondo que esteja instalado) pode gerar um diagrama visual via

dot -Tpng trace.dot -o trace.png

Observe que definir a variável de ambiente XLA_SAVE_TENSORS_FILE , especialmente quando usada em combinação com XLA_LOG_GRAPH_CHANGES , terá um impacto negativo substancial no desempenho. Use-os apenas durante a depuração e não para operação regular.

Variáveis ​​de ambiente adicionais

Variáveis ​​de ambiente adicionais para depuração incluem:

  • XLA_USE_BF16 : Se definido como 1, transforma todos os valores Float em BF16. Deve ser usado apenas para depuração, pois oferecemos precisão mista automática.

  • XLA_USE_32BIT_LONG : Se definido como 1, mapeia o tipo S4TF Long para o tipo inteiro XLA de 32 bits. Na TPU, os cálculos inteiros de 64 bits são caros, portanto, definir esse sinalizador pode ajudar. Obviamente, o usuário precisa ter certeza de que os valores ainda cabem em um número inteiro de 32 bits.