Risoluzione dei problemi di TensorFlow - TPU

Questa guida, insieme alle Domande frequenti, fornisce assistenza per la risoluzione dei problemi agli utenti che addestrano modelli TensorFlow su Cloud TPU. Se stai risolvendo i problemi di addestramento di PyTorch o JAX, puoi consultare i documenti per la risoluzione dei problemi relativi a questi framework:

Per guide più generali su come utilizzare Cloud TPU, consulta:

Panoramica

I problemi comuni riscontrati con Cloud TPU rientrano nelle seguenti categorie:

  1. Problemi di connessione alla TPU

  2. Eseguire il debug degli errori comuni

  3. Ridurre l'utilizzo della memoria

  4. Miglioramento della velocità di allenamento

  5. Il debug comporta cali di accuratezza del modello

Problemi di connessione al server TPU

Questa sezione descrive come risolvere i problemi relativi alle situazioni in cui TensorFlow smette di rispondere o stampa un errore durante la connessione alla TPU. Il passaggio di compilazione del grafo TPU può richiedere molto tempo per i modelli di grandi dimensioni, quindi lascia che lo script venga eseguito per almeno 5 minuti prima di concludere che ha smesso di rispondere.

Il primo passaggio consiste nel verificare se il problema riguarda il server stesso o la pipeline di addestramento di TensorFlow. Per farlo, esegui il tutorial su MNIST utilizzando l'URL del server TPU e verifica che funzioni correttamente. Se i problemi di connessione con il tutorial MNIST persistono, significa che si tratta di un problema con il server TPU. In questo caso:

  1. Esegui il comando seguente per elencare le TPU disponibili. Sostituisci zone e project-id con la tua zona e l'ID progetto.

    (vm)$ gcloud compute tpus tpu-vm list --zone zone --project project-id

    Viene stampato un output come:

    NAME       ZONE           ACCELERATOR_TYPE  NETWORK_ENDPOINT   NETWORK  RANGE          STATUS
    demo-tpu   us-central1-b  v2-8              10.240.1.2:8470    default  10.240.1.0  READY

  2. Verifica di passare il valore corretto a --tpu (demo-tpu nell'esempio precedente) e che questa TPU sia elencata come READY.

  3. Se la TPU non è elencata come READY o se continui a riscontrare problemi di connessione, riavvia manualmente il server con:

    (vm)$ gcloud compute tpus tpu-vm stop $TPU_SERVER_NAME && gcloud compute tpus tpu-vm start $TPU_SERVER_NAME

    Nell'esempio precedente, $TPU_SERVER_NAME è demo-tpu. L'operazione potrebbe richiedere diversi minuti.

  4. Esegui di nuovo il comando ... tpus list e attendi che la TPU sia nello stato READY. L'operazione potrebbe richiedere alcuni minuti.

  5. Prova a eseguire di nuovo il tutorial su MNIST.

  6. Se continui a riscontrare problemi durante l'esecuzione del tutorial su MNIST, richiedi assistenza utilizzando uno dei meccanismi descritti in Ricevere assistenza.

Se l'esempio MNIST funziona correttamente, ma il modello continua a non rispondere, è probabile che il problema riguardi la pipeline di addestramento. Per eseguire il debug, inizia sostituendo TPUStrategy nel codice con la strategia predefinita. Quando utilizzi la strategia predefinita, ovunque utilizzi strategy.scope() o strategy.run(), il modello viene eseguito sulla CPU (o sulla GPU, se presente) anziché sulla TPU. Se il modello viene eseguito su CPU e non su TPU, deve esserci un problema specifico della TPU. Se il problema persiste, la best practice è eseguire il debug del problema sulla CPU.

Perdita della connessione a ssh durante l'allenamento

La connessione ssh a Cloud TPU potrebbe scadere durante un addestramento di lunga durata (in particolare se utilizzi Cloud Shell). A quel punto, non viene visualizzato alcun output nella console TPU e potrebbe sembrare che l'addestramento della TPU sia stato interrotto. Per evitare questo problema, esegui la sessione di formazione con un multiplexer di terminale o uno strumento di gestione delle sessioni come tmux o screen. In questo modo, la connessione a ssh rimarrà attiva indipendentemente dalla durata della formazione.

Eseguire il debug degli errori comuni

Questa sezione descrive come risolvere gli errori comuni che potresti riscontrare durante l'addestramento dei modelli su Cloud TPU.

Impossibile creare una TPU

Quando crei una Cloud TPU, potresti visualizzare il seguente errore:

googleapiclient.errors.HttpError: < HttpError 403 when requesting https://content-tpu.googleapis.com/v1/projects/{PROJECT}/locations/{ZONE}/nodes/{TPU_NAME}?alt=json returned "Request had insufficient authentication scopes."

Si tratta di un problema di autorizzazioni e può essere risolto eseguendo il seguente comando:

gcloud auth login --update-adc

Questo comando aggiorna le Credenziali predefinite dell'applicazione (ADC) e dovrebbe risolvere il problema. Per ulteriori informazioni, consulta gcloud auth login.

Forme dinamiche non supportate

Messaggio di errore

ValueError: shape [Shape] must have a fixed size for dimension
d that is known at graph construction time.

Framework e configurazioni interessati

Questo messaggio si verifica solo durante la compilazione XLA con TensorFlow.

Dettagli

Per eseguire un modello sulla TPU, Cloud TPU lo compila utilizzando il compilatore XLA. Anche se questo passaggio di compilazione migliora notevolmente la velocità di addestramento e l'utilizzo della memoria, le forme (dimensioni) di tutti i tensori nel grafo devono essere note al momento della compilazione del grafo. Se non è possibile determinare le forme in fase di compilazione, la compilazione della TPU non va a buon fine con un errore simile a quello mostrato in precedenza.

Un'operazione comune che restituisce una forma dinamica è dataset.batch(batch_size), poiché il numero di campioni rimanenti in uno stream potrebbe essere inferiore alla dimensione del batch. Pertanto, durante l'addestramento sulla TPU, imposta drop remainder=True per dataset.batch. In questo modo, è possibile eliminare gli ultimi campioni di un file per garantire che ogni batch abbia una forma statica di batch_size. Ad esempio:

dataset = tf.data.Dataset.range(8)
dataset = dataset.batch(3, drop_remainder=True)

Operazione TensorFlow non disponibile

Messaggio di errore

NotFoundError: No registered 'OpName' OpKernel for XLA_TPU_JIT
devices compatible with node

Framework e configurazioni interessati

Questo messaggio può verificarsi durante l'addestramento con TensorFlow.

Dettagli

Il modello utilizza un'operazione TensorFlow non disponibile su TPU.

Per un elenco delle operazioni disponibili sulla TPU, oltre ai piani per l'assistenza futura e ai suggerimenti per le soluzioni alternative, consulta la guida alle operazioni TensorFlow disponibili.

Messaggio di errore relativo alla memoria insufficiente

Messaggio di errore

ResourceExhaustedError: Ran out of memory in memory space hbm; used:
YYY; limit: 7.48G.

Framework e configurazioni interessati

Questo messaggio può verificarsi durante l'addestramento con TensorFlow, PyTorch o JAX.

Dettagli

Ogni Cloud TPU è composta da otto core TPU, le TPU v2 hanno 8 GB e le TPU v3 hanno 16 GB di RAM (o HBM, memoria ad alta larghezza di banda). Questa memoria viene utilizzata per memorizzare i tensori dei pesi (variabili), nonché i tensori dei risultati intermedi necessari per il calcolo del gradiente. Se il modello è troppo grande per essere inserito nella RAM della TPU, l'inizializzazione non va a buon fine e viene stampato il messaggio di errore. Per ulteriore assistenza, consulta la sezione sulla riduzione dell'utilizzo della memoria.

Suggerimenti per ridurre l'utilizzo della memoria:

Problemi di interruzione dell'esecuzione

Se TensorFlow rileva un errore durante l'esecuzione della TPU, a volte lo script sembra smettere di rispondere anziché uscire dalla shell. In questo caso, premi CTRL+C sulla tastiera per attivare un SIGQUIT, che fa uscire Python immediatamente.

Analogamente, se premi CTRL+C durante l'esecuzione della TPU, TensorFlow non viene arrestato immediatamente, ma attende la fine dell'attuale ciclo di iterazione per uscire correttamente.

Se riscontri nuovi errori durante la riconnessione alla TPU dopo l'uscita in questo modo, reimposta manualmente il server TPU con i seguenti comandi:

gcloud compute tpus tpu-vm stop tpu-name --zone=zone
gcloud compute tpus tpu-vm start tpu-name --zone=zone

dove tpu-name è preso dalla prima colonna visualizzata dal comando gcloud compute tpus tpu-vm list e zone è la zona mostrata nella seconda colonna.

Riempimento eccessivo dei tensori

Possibile causa del problema di memoria

I tensori nella memoria TPU sono con spaziatura interna, ovvero la TPU arrotonda per eccesso le dimensioni dei tensori memorizzati nella memoria per eseguire i calcoli in modo più efficiente. Questo riempimento avviene in modo trasparente a livello hardware e non influisce sui risultati. Tuttavia, in alcuni casi il padding può comportare un aumento significativo dell'utilizzo della memoria e del tempo di esecuzione.

Come ridurre l'utilizzo della memoria

Il software TPU tenta di disporre i tensori in memoria per massimizzare l'efficienza di calcolo e ridurre al minimo il padding. Questa procedura di layout della memoria è complessa, ma per ottenere i risultati migliori il modello deve rispettare la seguente regola empirica. Per ridurre al minimo l'overhead della memoria e massimizzare l'efficienza di calcolo, deve essere vera una delle seguenti condizioni:

  • La dimensione totale del batch deve essere un multiplo di 64 (8 per core TPU) e le dimensioni degli elementi devono essere un multiplo di 128.

    o

  • La dimensione totale del batch deve essere un multiplo di 1024 (128 per core TPU) e le dimensioni degli elementi devono essere un multiplo di 8.

L'utilizzo di un batch di dimensioni pari a 1024 e di dimensioni delle funzionalità che sono un multiplo di 128 consente di ottenere l'efficienza migliore, anche se ciò potrebbe non essere possibile per tutti i modelli. Per chiarezza, "dimensione delle funzionalità" si riferisce alle dimensioni nascoste di un livello completamente connesso o al numero di canali di output in una convezione. Non tutti gli strati possono essere conformi a questa regola, in particolare il primo e l'ultimo della rete. Non c'è problema, è normale che la maggior parte dei modelli richieda un po' di spaziatura interna.

Riduzione dell'utilizzo della memoria

Se si verifica un errore di esaurimento della memoria durante l'esecuzione del modello sulla TPU, devi adottare misure per ridurre l'utilizzo della memoria del modello.

I modi più efficaci per ridurre l'utilizzo della memoria sono:

  • Riduci il padding eccessivo dei tensori
  • Riduci le dimensioni del batch

Dimensione del batch o modello troppo grande

Possibile causa del problema di memoria

Quando si addestra una rete neurale su una CPU, una GPU o una TPU, l'utilizzo della memoria proviene da due fonti:

  1. L'utilizzo della memoria è proporzionale al numero di coefficienti nel modello.
  2. Memorizzazione delle attivazioni intermedie dal passaggio in avanti necessario per calcolare il passaggio all'indietro. L'utilizzo della memoria è direttamente proporzionale alle dimensioni del batch, alle dimensioni dei livelli e al numero di livelli.

Pertanto, la memoria richiesta da un modello dipende in gran parte dalle dimensioni del batch.

La memoria richiesta da un modello dipende dal numero di strati della rete.

Il runtime TPU tenta di ottimizzare gli operatori per adattare il modello in memoria (operazione chiamata rematerializzazione, simile al controllo punto di interruzione del gradiente), ma non sempre ci riesce.

Come ridurre l'utilizzo della memoria

Riduci lentamente le dimensioni del batch finché non rientrano nella memoria, assicurandoti che le dimensioni totali del batch siano un multiplo di 64 (le dimensioni del batch per core devono essere un moltiplo di 8). Tieni presente che dimensioni dei batch più grandi sono più efficienti sulla TPU. In genere, una dimensione del batch totale di 1024 (128 per core) è un buon punto di partenza.

Se il modello non può essere eseguito sulla TPU anche con un lotto di piccole dimensioni (ad esempio 64), prova a ridurre il numero di livelli o le dimensioni dei livelli.

Migliorare la velocità di addestramento

Se il tuo modello è in grado di funzionare correttamente sulla TPU, ma la velocità di addestramento è inferiore alle aspettative, questa sezione illustra diversi potenziali modi per migliorare la velocità. Consulta la guida sul rendimento per altri suggerimenti su come migliorare il rendimento dell'addestramento.

Numero di passaggi per esecuzione per ciclo di addestramento troppo ridotto

Descrizione del problema di rendimento

Il passaggio dell'argomento steps_per_execution a Model.compile controlla quanti passaggi di addestramento vengono eseguiti tra i callback dell'host. Ogni callback dell'host richiede una comunicazione significativa tra la CPU dell'host del server TPU e il dispositivo TPU, quindi se steps_per_execution è troppo piccolo, l'addestramento può rallentare.

Come sapere se il tuo modello è interessato

Se un profilo TPU rivela frequenti callback della CPU dell'host tra i passaggi del dispositivo TPU, l'addestramento può trarre vantaggio da un valore steps_per_execution maggiore.

Come mitigare il problema

Imposta un valore di steps_per_execution maggiore. Tieni presente che steps_per_execution può essere impostato su un valore elevato, ma tieni presente che la registrazione dei messaggi e il salvataggio di un checkpoint possono avvenire solo dopo che è stato eseguito il numero specificato di passaggi.

Bottleneck di elaborazione dell'input

Descrizione del problema di rendimento

Mentre la TPU esegue l'addestramento su un determinato blocco di dati, la funzione di elaborazione input prepara il blocco successivo di dati sulla CPU. Se la funzione di input richiede più tempo della funzione del modello, la TPU rimane inattiva mentre la funzione di input recupera i dati.

Come sapere se il tuo modello è interessato

Segui le istruzioni riportate in Cloud TPU Tools: Input Pipeline Analyzer per visualizzare l'analisi della pipeline di input in TensorBoard:

immagine

La pagina di analisi della pipeline di input mostra un riepilogo chiaro che indica se il tuo modello presenta un collo di bottiglia dovuto all'elaborazione dell'input. Nella stessa pagina viene inoltre visualizzato il tempo di esecuzione per operazione, che consente di individuare le operazioni problematiche.

Come mitigare il problema

Esistono diverse possibili soluzioni per ridurre il problema durante il caricamento dei dati con l'API Dataset:

  1. Memorizza i dati come raccolta di strutture tf.train.Example in file TFRecord e caricali con TFRecordDataset. Per esempi, consulta il tutorial sull'API Dataset o il tutorial su ResNet.
  2. Utilizza dataset.cache() o dataset.prefetch() per mettere in buffer i dati di input. In questo modo, i rallentamenti sporadici nell'accesso ai file non creano un collo di bottiglia.
  3. Specifica il parametro num_parallel_calls della funzione dataset.map() per attivare le operazioni map() multithread. Un'euristica per il valore di num_parallel_calls è utilizzare il numero di core della CPU disponibili.
  4. Esegui la pre-elaborazione dei dati di costo elevato offline come costo una tantum, anziché sostenere il costo in ogni epoca di ogni addestramento.

Tutta l'elaborazione dell'input viene eseguita sulle CPU situate sul server TPU, non sulla macchina locale, pertanto la velocità della macchina locale non è un fattore determinante.

Tempi di passaggio lenti e utilizzo ridotto dell'unità MXU

Descrizione del problema di rendimento

Cloud TPU può eseguire moltiplicazioni e convolute di matrici a velocità incredibilmente elevate. La maggior parte delle altre operazioni TensorFlow ha implementazioni efficienti su TPU, ma non sono il punto di forza principale della TPU rispetto ad altro hardware. Pertanto, un modello deve essere dominato da moltiplicazioni di matrici o convolute per sfruttare appieno la TPU.

Come sapere se il tuo modello è interessato

In questo caso, noterai tempi di passaggio lenti combinati con un utilizzo ridotto delle MXU quando esegui il profiling delle prestazioni.

Come mitigare il problema

Prova a ridurre il numero di operazioni che non sono moltiplicazioni di matrici. Dopo aver ridotto il numero di moltiplicazioni matriciali, esegui nuovamente il benchmark per verificare se le prestazioni sono accettabili sulle TPU.

Riempimento eccessivo dei tensori

Descrizione del problema di rendimento

La TPU aggiunge spazi ai tensori in memoria in modo da poter utilizzare le sue unità di calcolo in modo efficiente. Il padding può aumentare l'utilizzo sia della memoria sia della larghezza di banda della memoria. Consulta la sezione sul padding dei tensori per comprendere e risolvere i problemi relativi al padding dei tensori.

Velocità in uscita lenta e utilizzo ridotto della memoria

Descrizione del problema di rendimento

Come regola generale, l'utilizzo di dimensioni dei batch più grandi comporta una maggiore velocità di addestramento sulla TPU, in termini di campioni/secondo.

Come sapere se il tuo modello è interessato

La dimensione del batch di qualsiasi modello deve essere sempre di almeno 64 (8 per core TPU), poiché la TPU aggiunge sempre spaziatura ai tensori fino a questa dimensione. La dimensione del batch ideale per l'addestramento su TPU è 1024 (128 per core TPU), poiché elimina le inefficienze relative al trasferimento della memoria e al padding.

Come mitigare il problema

La best practice è utilizzare la dimensione del batch più grande che si adatta alla memoria ed è un múltiplo di 64. Il modo più semplice per farlo è iniziare con 1024 e, se questo causa un errore di esaurimento della memoria, prova a ridurre le dimensioni del batch fino a quando il modello non viene eseguito correttamente. La modifica della dimensione del batch di un modello potrebbe richiedere aggiustamenti di altri iperparametri per ottenere la stessa accuratezza del modello, ad esempio il tasso di apprendimento, ma questo deve essere valutato caso per caso.

Dimensioni dei livelli troppo piccole

Descrizione del problema di rendimento

Anche se un modello è dominato da convoluzioni o moltiplicazioni di matrici, la TPU potrebbe non funzionare a piena efficienza se i tensori di input sono piccoli. Rispetto ad altro hardware, la TPU funziona in modo più efficiente quando sia le dimensioni del batch sia quelle del livello sono grandi (ad esempio, dimensione >= 512).

Come sapere se il tuo modello è interessato

Come regola generale, le dimensioni dei livelli inferiori a 128 hanno scarsa efficienza sulla TPU, poiché 128 è la dimensione integrata dell'unità di moltiplicazione della matrice TPU. Per i livelli completamente connessi, è consigliata una dimensione nascosta minima di 512 per ottenere un'elevata efficienza. Tieni presente che i livelli con convoluzione in genere non devono essere grandi quanto i livelli completamente connessi per raggiungere lo stesso livello di efficienza.

Come mitigare il problema

Se la motivazione principale per le dimensioni ridotte dei livelli nel tuo modello è la velocità di addestramento, esegui nuovamente il benchmark dei modelli con livelli più grandi sulla TPU. Ad esempio, aumentare le dimensioni di output di un livello da 256 a 512 potrebbe aumentare il tempo di addestramento solo del 20%, anche se il modello esegue il doppio dei calcoli.

Profilazione del modello a livello di operazione

Spesso è utile misurare il tempo di esecuzione a livello di operazione e l'utilizzo della memoria per identificare i colli di bottiglia delle prestazioni. Per istruzioni su come eseguire questa operazione,
consulta la guida Cloud TPU Tools: Trace Viewer.

Il debug comporta cali di accuratezza del modello

Uno degli obiettivi dell'ecosistema Cloud TPU è che qualsiasi modello addestrato su una CPU o una GPU raggiunga un'accuratezza molto simile quando viene addestrato sulla TPU, con forse piccoli aggiustamenti agli iperparametri come la dimensione del batch e la frequenza di apprendimento. Tuttavia, a volte gli utenti possono osservare un peggioramento dell'accuratezza durante l'addestramento dei modelli su TPU. Il debug di questi problemi può essere estremamente frustrante a causa della natura casuale dell'addestramento delle reti neurali. Questa sezione fornisce indicazioni su come individuare la causa principale di eventuali cali di accuratezza del modello durante il trasferimento di un modello a TPU.

Informazioni sullo sharding dei dati (parallelismo dei dati)

Uno degli obiettivi principali di TensorFlow è che ogni operazione debba produrre risultati quasi identici indipendentemente dal fatto che venga eseguita su CPU, GPU o TPU. Esistono alcune eccezioni, come le operazioni casuali. In generale, se rilevi una differenza significativa tra l'output delle operazioni non casuali sulla TPU e sulla CPU, segnala il problema come bug.

Tuttavia, per la pipeline di addestramento nel suo complesso, esiste una differenza significativa tra l'addestramento su CPU/GPU e TPU. Durante l'addestramento su una TPU, TensorFlow esegue lo sharding dei dati, Ogni Cloud TPU contiene 8 core TPU che operano come unità di elaborazione indipendenti. Per ogni passaggio dell'addestramento, ogni core TPU riceve un batch di dati, calcola i gradienti dei pesi, scambia i gradienti con gli altri core TPU e poi calcola l'aggiornamento dei pesi. Per impostazione predefinita, la perdita viene mediata tra i core, ma può essere sommata modificando il parametro di CrossShardOptimizer.

Se la perdita totale del modello può essere calcolata come media (o somma) di perdite indipendenti per campione, questa procedura è matematicamente equivalente all'addestramento su un singolo batch di grandi dimensioni.

L'operazione più comune che non è indipendente per campione è la normalizzazione per batch, che viene eseguita su ogni batch per core separatamente. Ad esempio, se la dimensione del batch totale è 128, la dimensione del batch per core è 16 e ciascuno degli 8 core esegue la normalizzazione batch sui propri 16 campioni. In alcuni casi, è stato riscontrato che l'esecuzione della normalizzazione per batch su batch di piccole dimensioni (ad esempio meno di 32) comporta una riduzione dell'accuratezza. Nello scenario ideale, la dimensione totale del batch deve essere elevata (ad esempio da 256 a 1024). Se la dimensione del batch è troppo grande per essere contenuta nella memoria, l'effetto dello sharding deve essere valutato caso per caso.

Addestramento deterministico

Uno dei motivi per cui è difficile eseguire il debug delle differenze di accuratezza del modello è che, in diversi framework (TensorFlow, PyTorch, JAX), il software di addestramento utilizza inizializzazioni dei pesi e data shuffling diversi ogni volta che viene addestrato un modello. È consigliabile modificare la procedura di addestramento in modo che sia deterministica, in modo che più esecuzioni producano modelli quasi identici. Questa sezione illustra come eseguire il tutorial MNIST in modo deterministico:

  1. Genera un file di checkpoint iniziale eseguendo un singolo passaggio sulla CPU. Il passaggio viene utilizzato per ottenere l'inizializzazione deterministica del peso. Inoltre, assicurati di utilizzare un seed casuale fisso per qualsiasi funzione casuale nel modello.
# Run training for 1 step to create an initial checkpoint.
python mnist_tpu.py \
  --use_tpu=False \
  --data_dir=${STORAGE_BUCKET}/data/ \
  --model_dir=${STORAGE_BUCKET}/init_output \
  --random_seed=12345 \
  --iterations=1
  --train_steps=1
  1. Modifica le eventuali funzioni di data shuffling nella funzione di input per utilizzare un seed casuale. Questo è già stato fatto nel tutorial su MNIST. Questo funziona per le operazioni di elaborazione dei dati di input perché vengono sempre eseguite sulla CPU. Le operazioni casuali nella funzione del modello potrebbero non essere deterministiche tra la TPU e la CPU. Ogni volta che chiami un'operazione casuale, passa un seed fisso per garantire gli stessi risultati tra le esecuzioni. Ad esempio:
# In the flag definitions
tf.flags.DEFINE_integer("batch_size", None, "Random seed for training")

# In the input_fn
if FLAGS.random_seed is not None:
dataset = dataset.shuffle(seed=FLAGS.random_seed)
  1. Esegui lo stesso modello due volte sulla CPU per verificare che l'addestramento sia deterministico. Tieni presente che l'addestramento deve essere eseguito per un numero ragionevole di passaggi (ad esempio 1000), ma non deve essere eseguito fino alla convergenza.

    Poiché l'addestramento su CPU viene confrontato con un addestramento su TPU a un solo core, utilizza una dimensione del batch che possa essere inserita in un singolo core TPU (in genere, la dimensione del batch completa divisa per 8). TensorFlow non garantisce il determinismo bit per bit tra le esecuzioni, ma la perdita dovrebbe essere molto ridotta:

Copia i pesi iniziali

gcloud storage cp ${STORAGE_BUCKET}/init_output/* ${STORAGE_BUCKET}/cpu_output_1/ --continue-on-error
gcloud storage cp ${STORAGE_BUCKET}/init_output/* ${STORAGE_BUCKET}/cpu_output_2/ --continue-on-error

Corsa 1

python mnist_tpu.py \
  --use_tpu=False \
  --data_dir=${STORAGE_BUCKET}/data/ \
  --model_dir=${STORAGE_BUCKET}/cpu_output_1 \
  --batch_size=128 \
  --random_seed=12345 \
  --train_steps=2000 \
  --eval_steps=10

Output 1

accuracy = 0.9910644, global_step = 1000, loss = 0.025323588

Corsa 2

python mnist_tpu.py \
  --use_tpu=False \
  --data_dir=${STORAGE_BUCKET}/data/ \
  --model_dir=${STORAGE_BUCKET}/cpu_output_1 \
  --batch_size=128 \
  --random_seed=12345 \
  --train_steps=2000 \
  --eval_steps=10

Output 2

accuracy = 0.9910644, global_step = 1000, loss = 0.025323414

Addestramento con TPU a un core

Una volta che puoi eseguire il tutorial MNIST in modo deterministico, il passaggio successivo consiste nel riprodurre i risultati addestrati su CPU sulla TPU, utilizzando un singolo core TPU per individuare se il problema è correlato allo sharding dei dati o al motore di esecuzione della TPU stesso.

Ecco come eseguire l'addestramento e la valutazione a un core nel tutorial MNIST:

Utilizza la stessa inizializzazione del peso della CPU

gcloud storage cp ${STORAGE_BUCKET}/init_output/* ${STORAGE_BUCKET}/tpu_output --continue-on-error

Esegui l'addestramento per 1000 passi

python mnist.py \
    --use_tpu=True \
    --master=$GRPC_SERVER \
    --train_file=${STORAGE_BUCKET}/data/train.tfrecords \
    --model_dir=${STORAGE_BUCKET}/tpu_output \
    --random_seed=12345 \
    --num_shards=1 \
    --batch_size=128 \
    --train_steps=1000 \
    --eval_steps=10

Output

  accuracy = 0.9910644, global_step = 1000, loss = 0.02514153

La perdita non corrisponderà esattamente al modello addestrato su CPU, ma dovrebbe essere simile. Se non è così per il tuo modello, è possibile che tu abbia trovato un bug nel motore di esecuzione TPU. Prima di inviare una segnalazione di bug, controlla quanto segue:

  1. Stai passando num_shards=1 a TPUConfig.

  2. Non sono presenti operazioni casuali nella funzione del modello e le operazioni casuali nella funzione di input vengono avviate correttamente.

  3. Utilizzi lo stesso file di checkpoint iniziale per l'addestramento su CPU e TPU.

Debug dell'addestramento con TPU multicore

Se il tuo modello raggiunge la stessa perdita sulla CPU e sulla TPU single-core, il problema è probabilmente uno dei seguenti:

(a) Il degrado è dovuto alla varianza casuale naturale durante l'addestramento dei modelli neurali con inizializzazioni diverse.

(b) Il degrado è dovuto a un problema relativo allo sharding dei dati sulla TPU.

Per determinare se il problema è (a), addestra nuovamente il modello completo su CPU/GPU e TPU multi-core utilizzando la stessa inizializzazione dei pesi.

Se ritieni che il calo dell'accuratezza sia statisticamente significativo, i problemi più probabili relativi allo sharding dei dati sono:

  1. Se il modello utilizza la normalizzazione batch, una dimensione totale del batch inferiore a 256 (ad esempio meno di 32 per core) potrebbe ridurre l'accuratezza.
  2. Le funzioni di perdita per batch sono interessate dallo sharding. Queste funzioni di perdita sono in genere molto specializzate. Ad esempio, Karras et al. 2017 utilizza un discriminatore batch per l'addestramento di una rete di GAN.

gcloud Risoluzione dei problemi di configurazione

Problema
gcloud components update viene visualizzato il seguente messaggio di errore:
ERROR: (gcloud.components.update)
You cannot perform this action because the Cloud SDK component manager is
disabled for this installation.
Soluzione
Per utilizzare gcloud, devi utilizzare un'installazione di gcloud non gestita tramite un gestore dei pacchetti. Per installare gcloud dal codice sorgente:
  sudo apt-get remove google-cloud-sdk
  curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-311.0.0-linux-x86_64.tar.gz
  tar -xzf google-cloud-sdk-311.0.0-linux-x86_64.tar.gz
  ./google-cloud-sdk/install.sh
  source ~/.bashrc
Problema

Il comando gcloud compute tpus tpu-vm ssh ${TPU_NAME} --zone ${ZONE} visualizza il seguente messaggio di errore:

Waiting for SSH key to propagate.
ssh: connect to host 34.91.136.59 port 22: Connection timed out
ssh: connect to host 34.91.136.59 port 22: Connection timed out
ssh: connect to host 34.91.136.59 port 22: Connection timed out
ERROR: (gcloud.compute.tpus.tpu-vm.ssh) Could not SSH into the instance.  It is possible that your SSH key has not propagated to the instance yet. Try running this command again.  If you still cannot connect, verify that the firewall and instance are set to accept ssh traffic.
Soluzione

Potrebbe esserci un problema con la propagazione della chiave SSH. Prova a spostare le chiavi generate automaticamente in una posizione di backup per forzare gcloud a ricrearle:

mv ~/.ssh/google_compute_engine ~/.ssh/old-google_compute_engine
mv ~/.ssh/google_compute_engine.pub ~/.ssh/old-google_compute_engine.pub

Log di debug

I framework Cloud TPU supportati, JAX, PyTorch e TensorFlow, accedono alle TPU utilizzando una libreria condivisa chiamata libtpu presente su ogni VM TPU. Questa libreria include il compilatore XLA utilizzato per compilare i programmi TPU, il runtime TPU utilizzato per eseguire i programmi compilati e il driver TPU utilizzato dal runtime per l'accesso a basso livello alla TPU.

La libreria libtpu registra informazioni che possono essere utili per il debug. Per impostazione predefinita, questi log vengono scritti in /tmp/tpu_logs su ogni VM Cloud TPU. Prima di iniziare l'addestramento, puoi impostare le seguenti variabili di ambiente per modificare il comportamento di registrazione:

TPU_LOG_DIR: la directory in cui vengono scritti i log
Per impostazione predefinita, la posizione della directory è /tmp/tpu_logs. La directory viene creata se non esiste già, ma non vengono create directory principali. Se si verifica un errore durante la ricerca o la creazione della directory specificata, viene visualizzato un messaggio in stderr, ma il programma non viene interrotto e il logging viene disattivato. Imposta il nome della directory su "disabled" per disattivare del tutto il logging sul disco.
TPU_MIN_LOG_LEVEL: la gravità minima che verrà registrata sul disco
Le opzioni sono 0 (INFO), 1 (WARNING), 2 (ERROR) e 3 (FATAL). Il valore predefinito è 0.
TPU_STDERR_LOG_LEVEL: la gravità minima che verrà registrata in stderr, oltre che sul disco, se applicabile
Le opzioni sono le stesse di TPU_MIN_LOG_LEVEL. Il valore predefinito è 3.
TPU_MAX_LOG_SIZE_MB: la dimensione massima in megabyte di ogni file di log
Quando il file di log precedente raggiunge circa queste dimensioni, verrà avviato automaticamente un nuovo file di log. Il valore predefinito è 1024.