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 dei problemi di addestramento PyTorch o JAX, puoi fare riferimento ai documenti per la risoluzione dei problemi relativi a tali framework:

Per guide più generali sull'utilizzo di Cloud TPU, vedi:

Panoramica

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

  1. Problemi di connessione alla TPU

  2. Debug di errori comuni

  3. Riduzione della memoria utilizzata

  4. Migliorare la velocità di addestramento

  5. Debug dei cali nell'accuratezza del modello

Problemi di connessione al server TPU

Questa sezione descrive come risolvere i problemi nelle situazioni in cui TensorFlow smette di rispondere o restituisce un errore durante la connessione alla TPU. Il passaggio di compilazione del grafico TPU può richiedere molto tempo per i modelli di grandi dimensioni, quindi attendi 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 TensorFlow. A questo scopo, esegui il tutorial MNIST utilizzando l'URL del server TPU e verifica che funzioni correttamente. Se esistono ancora problemi di connessione con il tutorial MNIST, ciò conferma che si tratta di un problema con il server TPU. In questo caso:

  1. Esegui questo comando per elencare le TPU disponibili. Sostituzione di zone e project-id con la tua zona e l'ID progetto.

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

    Verrà 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 tua TPU non è elencata come READY o i problemi di connessione persistono, riavvia manualmente il server con:

    (vm)$ gcloud compute tpus stop $TPU_SERVER_NAME && gcloud compute tpus 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 si trovi nello stato READY. L'operazione potrebbe richiedere alcuni minuti.

  5. Prova a eseguire di nuovo il tutorial MNIST.

  6. Se continui ad avere problemi con l'esecuzione del tutorial MNIST, chiedi aiuto utilizzando uno dei meccanismi descritti in Ottenere assistenza.

Se l'esempio MNIST viene eseguito correttamente, ma il modello continua a rispondere, è probabile che il problema riguardi la pipeline di addestramento. Per eseguire il debug, inizia sostituendo la 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 GPU, se presente) anziché sulla TPU. Se il modello viene eseguito sulla 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'addestramento

La connessione ssh a Cloud TPU potrebbe scadere durante un addestramento a lunga esecuzione (soprattutto se utilizzi Cloud Shell). A quel punto, non c'è alcun output nella console TPU e potrebbe sembrare che la TPU abbia interrotto l'addestramento. Per evitare che questo accada, esegui la sessione di addestramento con un multiplexer di terminale o uno strumento di gestione delle sessioni come tmux o screen. In questo modo la connessione ssh resti attiva a prescindere dalla durata dell'addestramento.

Debug di errori comuni

Questa sezione descrive come risolvere gli errori comuni che si potrebbero verificare 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 relativo alle autorizzazioni e può essere risolto eseguendo questo comando:

gcloud auth login --update-adc

Questo comando aggiorna le tue 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 viene visualizzato solo durante la compilazione XLA con TensorFlow.

Dettagli

Per eseguire un modello sulla TPU, Cloud TPU compila il modello utilizzando il compilatore XL. Sebbene questo passaggio di compilazione migliori significativamente la velocità di addestramento e l'utilizzo della memoria, è necessario conoscere le forme (dimensioni delle dimensioni) di tutti i tensori nel grafico al momento della compilazione del grafico. Se non è possibile determinare alcuna forma al momento della compilazione, la compilazione delle TPU non riesce con un errore come quello mostrato in precedenza.

Un'operazione comune che restituisce una forma dinamica è dataset.batch(batch_size), poiché il numero di campioni rimanenti in un flusso potrebbe essere inferiore alla dimensione del batch. Di conseguenza, durante l'addestramento sulla TPU, imposta drop remainder=True per dataset.batch. Questa operazione può eliminare gli ultimi campioni da 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ò essere visualizzato durante l'addestramento con TensorFlow.

Dettagli

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

Per un elenco delle operazioni disponibili sulla TPU, oltre ai piani per il supporto futuro e ai suggerimenti per soluzioni alternative, consulta la guida alle operazioni TensorFlow disponibili.

Messaggio di errore di esaurimento memoria

Messaggio di errore

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

Framework e configurazioni interessati

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

Dettagli

Ogni Cloud TPU è composto da otto core TPU, le TPU v2 hanno 8 GB e le TPU v3 hanno 16 GB di RAM (o HBM, memoria a larghezza di banda elevata). Questa memoria viene utilizzata per archiviare i tensori di ponderazione (variabile), nonché i tensori di risultati intermedi necessari per il calcolo del gradiente. Se il modello è troppo grande per essere inserito nella RAM TPU, l'inizializzazione non riesce e viene stampato il messaggio di errore. Per ulteriore assistenza, vedi 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 causa l'uscita immediata di Python.

Allo stesso modo, la pressione di CTRL+C durante l'esecuzione della TPU non comporta l'arresto immediato di TensorFlow, ma attende fino alla fine del loop di iterazione corrente per uscire in modo corretto.

Se si verificano nuovi errori quando ti riconnetti alla TPU dopo essere uscito in questo modo, reimposta manualmente il server TPU con i comandi:

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

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

Eccessiva spaziatura interna del tensore

Possibile causa di problemi di memoria

I tensori nella memoria TPU sono riempiti, ovvero la TPU arrotonda le dimensioni dei tensori archiviati in memoria per eseguire i calcoli in modo più efficiente. Questa spaziatura interna si verifica in modo trasparente a livello hardware e non influisce sui risultati. Tuttavia, in alcuni casi la spaziatura interna può comportare un aumento significativo dell'utilizzo della memoria e dei tempi di esecuzione.

Come ridurre la memoria utilizzata

Il software TPU tenta di disporre i tensori in memoria per massimizzare l'efficienza di calcolo e ridurre al minimo il padding. Questo processo di layout della memoria è complesso, ma per ottenere i migliori risultati 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 delle caratteristiche 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 delle caratteristiche devono essere un multiplo di 8.

L'utilizzo di dimensioni del batch di 1024 e di dimensioni delle caratteristiche che sono un multiplo di 128 garantisce la migliore efficienza, anche se ciò potrebbe non essere possibile per tutti i modelli. Per chiarezza, "dimensione della caratteristica" si riferisce alla dimensione nascosta di un livello completamente connesso o al numero di canali di output in una convoluzione. Non tutti i livelli possono essere conformi a questa regola, in particolare il primo e l'ultimo livello della rete. Questo va bene e si prevede che la maggior parte dei modelli richieda una certa spaziatura interna.

Riduzione della memoria utilizzata

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 la memoria utilizzata sono:

  • Riduci l'eccessiva spaziatura interna del tensore
  • Riduci le dimensioni del batch

Dimensione del batch o modello troppo grande

Possibile causa di problemi di memoria

Durante l'addestramento di una rete neurale su CPU, GPU o TPU, l'utilizzo della memoria proviene da due punti:

  1. L'utilizzo della memoria è proporzionale al numero di ponderazioni del modello.
  2. Archiviare le attivazioni intermedie dal passaggio in avanti necessario per calcolare il passaggio a ritroso. L'utilizzo della memoria è direttamente proporzionale alla dimensione del batch, alle dimensioni degli strati e al numero di strati.

Pertanto, la memoria richiesta da un modello dipende molto dalla dimensione del batch.

La memoria richiesta da un modello dipende dal numero di livelli nella rete.

Il runtime TPU tenta di ottimizzare gli operatori per adattare il modello alla memoria (chiamata rematerializzazione, simile al checkpoint del gradiente), ma non è sempre in grado di farlo.

Come ridurre la memoria utilizzata

Riduci lentamente la dimensione del batch fino a quando non rientra in memoria, assicurandoti che la dimensione totale del batch sia un multiplo di 64 (la dimensione del batch per core deve essere un multiplo di 8). Tieni presente che i batch di dimensioni maggiori sono più efficienti sulla TPU. Una dimensione totale del batch di 1024 (128 per core) è generalmente un buon punto di partenza.

Se il modello non può essere eseguito sulla TPU anche con un batch di dimensioni ridotte (ad esempio 64), prova a ridurre il numero o le dimensioni degli strati.

Migliorare la velocità di addestramento

Se il modello può essere eseguito correttamente sulla TPU, ma la velocità di addestramento è inferiore a quella prevista, questa sezione illustra i diversi modi possibili per migliorarla. Consulta la Guida al rendimento per altri suggerimenti su come migliorare le prestazioni della formazione.

Numero insufficiente di passaggi per esecuzione per loop di addestramento

Descrizione del problema di rendimento

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

Come capire se il tuo modello è interessato

Se un profilo TPU rivela frequenti callback della CPU host tra i passaggi del dispositivo TPU, il tuo addestramento può trarre vantaggio da un valore steps_per_execution più grande.

Come attenuare

Imposta un valore maggiore per steps_per_execution. 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 l'esecuzione del numero di passaggi specificato.

Collo di bottiglia dell'elaborazione degli input

Descrizione del problema di rendimento

Durante l'addestramento della TPU su un particolare blocco di dati, la funzione di elaborazione di input prepara il blocco di dati successivo nella CPU. Se la funzione di input richiede più tempo della funzione di modello, la TPU viene lasciata inattiva durante il recupero dei dati da parte della funzione di input.

Come capire se il tuo modello è interessato

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

immagine

La pagina Analisi della pipeline di input mostra un chiaro riepilogo che mostra se il modello ha colli di bottiglia nell'elaborazione dell'input. La stessa pagina mostra anche il tempo di esecuzione per operazione, che consente di individuare le operazioni problematiche.

Come attenuare

Esistono diverse possibili mitigazioni per il caricamento dei dati con l'API Dataset:

  1. Archivia i dati come raccolta di strutture tf.train.Example in file TFRecord e caricali con TFRecordDataset. Consulta il tutorial sull'API Dataset o il tutorial su ResNet per gli esempi.
  2. Utilizza dataset.cache() o dataset.prefetch() per eseguire il buffering dei dati di input. In questo modo si impedisce che i rallentamenti sporadici nell'accesso ai file creino un collo di bottiglia.
  3. Specifica il parametro num_parallel_calls della funzione dataset.map() per abilitare le operazioni map() con multi-thread. Un'euristica per il valore di num_parallel_calls consiste nell'utilizzare il numero di core CPU disponibili.
  4. Esegui costose pre-elaborazione dei dati offline come costo una tantum, anziché dover sostenere il costo in ogni epoca di ogni addestramento.

Tutte le elaborazioni di input vengono eseguite su CPU situate sul server TPU, non sulla macchina locale, per cui non viene presa in considerazione la velocità della macchina locale.

Tempi di passaggio lenti e basso utilizzo di MXU

Descrizione del problema di rendimento

La Cloud TPU può eseguire moltiplicazioni e convoluzioni delle matrici a velocità incredibilmente elevate. La maggior parte delle altre operazioni TensorFlow ha implementazioni efficienti sulla TPU, ma non sono la forza principale della TPU rispetto ad altro hardware. Per sfruttare appieno la TPU, il modello dovrebbe essere dominato da moltiplicazioni o convoluzioni matriciali.

Come capire se il tuo modello è interessato

I sintomi che vedrai in questo caso sono tempi di passo lenti associati a un basso utilizzo di MXU, mostrato quando profili le prestazioni.

Come attenuare

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

Eccessiva spaziatura interna del tensore

Descrizione del problema di rendimento

La TPU protegge i tensori della memoria in modo che la TPU possa utilizzare le unità di calcolo in modo efficiente. La spaziatura interna può aumentare l'utilizzo di memoria e larghezza di banda della memoria. Consulta la sezione sulla spaziatura interna dei tensori per informazioni sulla comprensione e sulla risoluzione dei problemi relativi al riempimento del tensore.

Velocità effettiva lenta e utilizzo ridotto della memoria

Descrizione del problema di rendimento

Come regola generale, l'utilizzo di batch di dimensioni maggiori si traduce in una maggiore velocità di addestramento sulla TPU, in termini di campioni al secondo.

Come capire 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 copre sempre i tensori a questa dimensione. La dimensione ideale del batch durante l'addestramento sulla TPU è 1024 (128 per core TPU), poiché ciò elimina le inefficienze relative al trasferimento della memoria e al padding.

Come attenuare

La best practice prevede di utilizzare la dimensione del batch più grande che rientra nella memoria ed è un multiplo di 64. Il modo più semplice per raggiungere questo obiettivo è iniziare con 1024 e, se ciò causa un errore di esaurimento della memoria, prova a ridurre la dimensione del batch finché il modello non viene eseguito correttamente. Modificare la dimensione del batch di un modello può richiedere la modifica di altri iperparametri per ottenere la stessa accuratezza del modello, ad esempio il tasso di apprendimento, ma questo aspetto deve essere valutato caso per caso.

Dimensioni dei livelli troppo piccole

Descrizione del problema di rendimento

Anche quando un modello è dominato da moltiplicazioni o convoluzioni matriciali, la TPU potrebbe non funzionare alla massima efficienza se i tensori di input sono piccoli. Rispetto con altri hardware, la TPU funziona in modo più efficiente quando sia la dimensione del batch che la dimensione dei livelli sono elevate (ad esempio, dimensione >= 512).

Come capire se il tuo modello è interessato

Come regola generale, le dimensioni degli strati inferiori a 128 ottengono una scarsa efficienza sulla TPU, poiché 128 è la dimensione integrata dell'unità di moltiplicazione della matrice TPU. Per gli strati completamente connessi, è consigliata una dimensione nascosta minima di 512 al fine di ottenere un'efficienza elevata. Tieni presente che, in genere, gli strati convoluzionali non devono essere grandi quanto quelli completamente connessi per raggiungere lo stesso livello di efficienza.

Come attenuare

Se il motivo principale per gli strati di piccole dimensioni nel tuo modello è la velocità di addestramento, esegui nuovamente il benchmark dei tuoi modelli con strati più grandi sulla TPU. Ad esempio, l'aumento della dimensione dell'output di uno strato da 256 a 512 può solo aumentare il tempo di addestramento del 20% anche se il modello esegue il doppio dei calcoli.

Profilazione del modello a livello di operatore

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 Strumenti Cloud TPU: Visualizzatore tracce.

Debug dei cali nell'accuratezza del modello

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

Informazioni sullo sharding dei dati (parallelismo dei dati)

Uno degli obiettivi principali di TensorFlow è che ciascuna operazione produca risultati quasi identici, a prescindere dal fatto che venga eseguita su CPU, GPU o TPU. Esistono alcune eccezioni, come operazioni casuali. In generale, se rilevi una differenza significativa tra l'output di operazioni non casuali sulla TPU e sulla CPU, segnalala come bug.

Tuttavia, per la pipeline di addestramento nel suo insieme, esiste una differenza significativa tra l'addestramento su CPU/GPU e TPU. Durante l'addestramento su una TPU, TensorFlow esegue lo 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 di peso, scambia i gradienti con gli altri core TPU, quindi calcola l'aggiornamento del peso. Per impostazione predefinita, la perdita viene calcolata in media tra i core, ma può essere sommata modificando il parametro di CrossShardOptimizer.

Se la perdita totale del modello può essere calcolata come la media (o somma) delle 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 dei batch, che viene eseguita separatamente su ciascun batch per core. Ad esempio, se la dimensione totale del batch è 128, la dimensione del batch per core sarà 16 e ciascuno degli 8 core esegue la normalizzazione del batch su 16 campioni specifici. In alcuni casi, l'esecuzione della normalizzazione dei batch su batch di piccole dimensioni (ad esempio, meno di 32) ha ridotto l'accuratezza. Nello scenario ideale, la dimensione totale del batch dovrebbe essere grande (ad es. da 256 a 1024). Se una dimensione del batch è troppo grande per essere immessa 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 nell'accuratezza del modello è che nei diversi framework (TensorFlow, PyTorch, JAX), il software di addestramento utilizza un'inizializzazione dei pesi e data shuffling diversi ogni volta che viene addestrato un modello. È utile modificare la procedura di addestramento in modo che sia deterministica, in modo che più esecuzioni producano modelli quasi identici. Questa sezione mostra come eseguire il tutorial MNIST in modo deterministico:

  1. Genera un file di checkpoint iniziale eseguendo un singolo passaggio sulla CPU. Questo passaggio viene utilizzato per ottenere un'inizializzazione deterministica delle ponderazioni. Assicurati inoltre 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 in modo da utilizzare un seed casuale. Questo è già stato fatto nel tutorial MNIST. Questo vale 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 TPU e 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 due volte lo stesso modello 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 è necessario per la convergenza.

    Poiché l'addestramento della CPU è confrontato con l'addestramento di una TPU single-core, utilizza una dimensione batch che possa adattarsi a un singolo core TPU (in genere la dimensione dell'intero batch divisa per 8). TensorFlow non garantisce il determinismo bit per bit tra le esecuzioni, ma la perdita dovrebbe essere molto simile:

Copia i pesi iniziali

gsutil mkdir ${STORAGE_BUCKET}/cpu_output_1
gsutil cp -f ${STORAGE_BUCKET}/init_output/* ${STORAGE_BUCKET}/cpu_output_1
gsutil mkdir ${STORAGE_BUCKET}/cpu_output_2
gsutil cp -f ${STORAGE_BUCKET}/init_output/* ${STORAGE_BUCKET}/cpu_output_2

Gara 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

Gara 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

Uscita 2

accuracy = 0.9910644, global_step = 1000, loss = 0.025323414

Addestramento con TPU single-core

Dopo aver eseguito il tutorial MNIST in modo deterministico, il passaggio successivo consiste nel replicare i risultati dell'addestramento della CPU sulla TPU, utilizzando un singolo core TPU per stabilire se il problema è relativo allo sharding dei dati o al motore di esecuzione della TPU.

Ecco come eseguire addestramento e valutazione single-core nel tutorial MNIST:

Usa la stessa inizializzazione delle ponderazioni della CPU

gsutil cp -f ${STORAGE_BUCKET}/init_output/* ${STORAGE_BUCKET}/tpu_output

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

Salvaguardie

  accuracy = 0.9910644, global_step = 1000, loss = 0.02514153

La perdita non corrisponderà esattamente al modello addestrato con CPU, ma dovrebbe essere simile. Se non è vicino per il tuo modello, ciò potrebbe indicare che hai trovato un bug nel motore di esecuzione della TPU. Prima di inviare una segnalazione di bug, verifica quanto segue:

  1. Stai passando num_shards=1 a TPUConfig.

  2. Non ci sono operazioni casuali nella funzione del modello e altre operazioni casuali nella funzione di input vengono sottoposte correttamente al seeding.

  3. Stai utilizzando lo stesso file di checkpoint iniziale per l'addestramento di CPU e TPU.

Debug dell'addestramento di TPU multi-core

Se il modello ha la stessa perdita sulla CPU e sulla TPU single-core, il problema potrebbe essere uno dei seguenti:

(a) La degradazione è dovuta 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 (a) è il problema, riaddestra il modello completo su CPU/GPU e TPU multi-core utilizzando la stessa inizializzazione di peso.

Se hai la certezza 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 del batch, una dimensione totale del batch inferiore a 256 (ad esempio, inferiore a 32 per core) potrebbe ridurre l'accuratezza.
  2. Le funzioni di perdita a livello di batch sono interessate dallo sharding. Queste funzioni di perdita sono in genere abbastanza specializzate. Ad esempio, Karras et al. 2017 utilizza un discriminatore batch durante l'addestramento di una rete avversaria generativa.

Risoluzione dei problemi di configurazione di gcloud

Problema
gcloud components update mostra 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 che non è gestita tramite un gestore di pacchetti. Segui questi passaggi 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} mostra 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 denominata 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 di 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 logging:

TPU_LOG_DIR: la directory in cui vengono scritti i log
La posizione della directory è /tmp/tpu_logs per impostazione predefinita. La directory viene creata se non esiste già, ma non vengono create directory padre. Se si verifica un errore durante il rilevamento o la creazione della directory specificata, viene stampato un messaggio a stderr, ma il programma non viene arrestato e il logging viene disabilitato. Imposta il nome della directory su "Disabled" per disabilitare completamente il logging su 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 al disco, se applicabile
Le opzioni sono le stesse per TPU_MIN_LOG_LEVEL. Il valore predefinito è 3.
TPU_MAX_LOG_SIZE_MB: le dimensioni massime in megabyte di ogni file di log
Quando il file precedente raggiungerà all'incirca queste dimensioni, verrà avviato automaticamente un nuovo file di log. Il valore predefinito è 1024.