Debug dei problemi di X10

Il backend dell'acceleratore X10 può fornire un throughput significativamente più elevato per il calcolo parallelo basato su grafici, ma la sua traccia differita e la compilazione just-in-time possono talvolta portare a comportamenti non ovvi. Ciò potrebbe includere la frequente ricompilazione di tracce a causa di modifiche alla forma del grafico o del tensore, oppure grafici di grandi dimensioni che portano a problemi di memoria durante la compilazione.

Un modo per diagnosticare i problemi è utilizzare le metriche di esecuzione e i contatori forniti da X10. La prima cosa da verificare quando un modello è lento è generare un report sulle metriche.

Metrica

Per stampare un report delle metriche, aggiungi una chiamata PrintX10Metrics() al tuo programma:

import TensorFlow

...
PrintX10Metrics()
...

Verranno registrati vari parametri e contatori a livello INFO .

Comprendere il rapporto sulle metriche

Il rapporto include cose come:

  • Quante volte attiviamo le compilazioni XLA e il tempo totale impiegato nella compilazione.
  • Quante volte lanciamo un calcolo XLA e il tempo totale impiegato per l'esecuzione.
  • Quanti dati del dispositivo gestiscono creiamo/distruggiamo, ecc.

Questa informazione è riportata in termini di percentili dei campioni. Un esempio è:

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

Forniamo anche contatori, ovvero variabili intere denominate che tengono traccia dello stato interno del software. Per esempio:

Counter: CachedSyncTensors
  Value: 395

Avvertenze note

I Tensor supportati da X10 si comportano semanticamente come i Tensor in modalità desiderosa predefinita. Tuttavia, ci sono alcuni avvertimenti sulle prestazioni e sulla completezza:

  1. Prestazioni ridotte a causa di troppe ricompilazioni.

    La compilazione XLA è costosa. X10 ricompila automaticamente il grafico ogni volta che vengono incontrate nuove forme, senza alcun intervento da parte dell'utente. I modelli devono vedere forme stabilizzate in pochi passaggi di training e da quel momento in poi non è necessaria alcuna ricompilazione. Inoltre, i percorsi di esecuzione devono stabilizzarsi rapidamente per lo stesso motivo: X10 si ricompila quando viene incontrato un nuovo percorso di esecuzione. Riassumendo, per evitare ricompilazioni:

    • Evitare forme dinamiche altamente variabili. Tuttavia, un numero basso di forme diverse potrebbe andare bene. Tensori del cuscinetto a dimensioni fisse quando possibile.
    • Evitare cicli con numero diverso di iterazioni tra le fasi di training. X10 attualmente svolge i loop, pertanto un numero diverso di iterazioni del loop si traduce in percorsi di esecuzione diversi (srotolati).
  2. Un numero limitato di operazioni non è ancora supportato da X10.

    Al momento disponiamo di una manciata di operazioni che non sono supportate, sia perché non esiste un buon modo per esprimerle tramite XLA e forme statiche (attualmente solo nonZeroIndices ) sia perché mancano casi d'uso noti (diverse operazioni di algebra lineare e inizializzazione multinomiale) . Mentre la seconda categoria è facile da gestire in base alle necessità, la prima categoria può essere gestita solo attraverso l'interoperabilità con la CPU, implementazione non XLA. L'utilizzo dell'interoperabilità troppo spesso ha implicazioni significative sulle prestazioni a causa dei viaggi di andata e ritorno dell'host e della frammentazione di un modello completamente fuso in più tracce. Si consiglia pertanto agli utenti di evitare di utilizzare tali operazioni nei propri modelli.

    Su Linux, utilizzare XLA_SAVE_TENSORS_FILE (documentato nella sezione successiva) per ottenere l'analisi dello stack Swift che ha chiamato l'operazione non supportata. I nomi delle funzioni possono essere demangle manualmente utilizzando swift-demangle .

Ottenere e rappresentare graficamente le tracce

Se sospetti che ci siano problemi con il modo in cui vengono tracciati i grafici o desideri comprendere il processo di tracciamento, vengono forniti strumenti per disconnettersi e visualizzare le tracce. Puoi fare in modo che X10 disconnetta le tracce trovate impostando la variabile d'ambiente XLA_SAVE_TENSORS_FILE :

export XLA_SAVE_TENSORS_FILE=/home/person/TraceLog.txt

Questi log di traccia sono disponibili in tre formati: text , hlo e dot , con il formato impostabile tramite la variabile di ambiente XLA_SAVE_TENSORS_FMT:

export XLA_SAVE_TENSORS_FMT=text

Quando esegui l'applicazione, la rappresentazione text disconnessa mostrerà ogni singola traccia in una notazione testuale di alto livello utilizzata da X10. La rappresentazione hlo mostra la rappresentazione intermedia passata al compilatore XLA. Potresti voler limitare il numero di iterazioni all'interno dei cicli di addestramento o di calcolo per evitare che questi log diventino troppo grandi. Inoltre, ogni esecuzione dell'applicazione verrà aggiunta a questo file, quindi potresti volerlo eliminare tra un'esecuzione e l'altra.

Impostando la variabile XLA_LOG_GRAPH_CHANGES su 1 indicherà anche all'interno del registro di traccia dove si sono verificate le modifiche nel grafico. Ciò è estremamente utile per trovare i luoghi in cui risulterà la ricompilazione.

Per una rappresentazione visiva di una traccia, l'opzione dot disconnetterà i grafici compatibili con Graphviz. Se estrai la porzione di traccia che assomiglia

digraph G {
    ...
}

nel proprio file, Graphviz (supponendo che sia installato) può generare un diagramma visivo tramite

dot -Tpng trace.dot -o trace.png

Tieni presente che l'impostazione della variabile di ambiente XLA_SAVE_TENSORS_FILE , soprattutto se utilizzata in combinazione con XLA_LOG_GRAPH_CHANGES , avrà un impatto sostanzialmente negativo sulle prestazioni. Utilizzarli solo durante il debug e non per il funzionamento regolare.

Variabili d'ambiente aggiuntive

Ulteriori variabili di ambiente per il debug includono:

  • XLA_USE_BF16 : Se impostato a 1, trasforma tutti i valori Float in BF16. Dovrebbe essere utilizzato solo per il debug poiché offriamo precisione mista automatica.

  • XLA_USE_32BIT_LONG : se impostato su 1, mappa il tipo S4TF Long sul tipo intero XLA a 32 bit. Su TPU, i calcoli con numeri interi a 64 bit sono costosi, quindi l'impostazione di questo flag potrebbe essere d'aiuto. Naturalmente, l'utente deve essere certo che i valori rientrino ancora in un numero intero a 32 bit.