Risoluzione dei problemi di TensorFlow - TPU
Questa guida, insieme alle Domande frequenti, fornisce una guida alla risoluzione dei problemi per gli utenti che stanno addestrando modelli TensorFlow su Cloud TPU. Se stai risolvendo problemi di addestramento Pytorch o JAX, puoi consultare i documenti per la risoluzione dei problemi relativi a tali framework:
Per guide più generali su come utilizzare Cloud TPU, vedi:
- Utilizza il colab di TPU
- Guide rapide di Cloud TPU
- Tutorial MNIST
- Addestramento di modelli di machine learning su unità di elaborazione (TPU) Cloud Tensor
Panoramica
I problemi comuni riscontrati con le Cloud TPU rientrano nelle seguenti categorie:
Errore di connessione al server TPU
Questa sezione descrive come risolvere i problemi relativi a casi in cui TensorFlow smette di rispondere o stampa un errore durante la connessione alla TPU. Il passaggio della compilazione del grafico TPU può richiedere molto tempo per i modelli di grandi dimensioni, quindi lascia che lo script venga eseguito per almeno cinque minuti prima di concludere che non risponde più.
Il primo passaggio consiste nel verificare se il problema riguarda il server stesso o la pipeline di addestramento TensorFlow. Per farlo, esegui il tutorial MNIST utilizzando l'URL del tuo server TPU e verifica che funzioni correttamente. Se i problemi di connessione con il tutorial MNIST persistono, questo conferma che si tratta di un problema con il server TPU. In questo caso:
Esegui il comando seguente per elencare le TPU disponibili. Sostituzione di zone e project-id con l'ID progetto e zona.
(vm)$ gcloud compute tpus list --zone zone --project project-id
L'output viene stampato, ad esempio:
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
Verifica di trasferire il valore corretto a
--tpu
(demo-tpu
nell'esempio riportato sopra) e che questa TPU sia indicata comeREADY
.Se la tua TPU non è elencata come
READY
o continui a riscontrare problemi di connessione, 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
. Potrebbero essere necessari diversi minuti.Esegui di nuovo il comando
... tpus list
sopra e attendi che lo stato della TPU sia nello statoREADY
. L'operazione potrebbe richiedere alcuni minuti.Prova a eseguire di nuovo il tutorial MNIST.
Se i problemi di esecuzione del tutorial MNIST persistono, chiedi aiuto utilizzando uno dei meccanismi descritti in Richiedere assistenza.
Se l'esempio MNIST viene eseguito correttamente, ma il modello continua a non rispondere, è probabile che il problema sia relativo alla pipeline di addestramento.
Per eseguire il debug, inizia sostituendo la TPUStrategia nel codice con la strategia predefinita. Quando utilizzi la strategia predefinita, ovunque utilizzi strategy.scope()
o strategy.run()
, il modello viene eseguito su CPU (o GPU se presente) anziché su TPU. Se il modello viene eseguito su CPU e non su TPU, deve esserci un problema specifico della TPU. Se il problema persiste, ti consigliamo di eseguire il debug del problema sulla CPU.
Perdita di connessione ssh
durante l'addestramento
La connessione ssh
a Cloud TPU potrebbe scadere durante un addestramento a lunga esecuzione (in particolare se utilizzi Cloud Shell).
A quel punto, non è presente alcun output sulla console TPU e potrebbe sembrare che la TPU abbia interrotto l'addestramento. Per evitare questo problema, esegui la sessione di addestramento con un multiplexer terminale o uno strumento di gestione delle sessioni come tmux
o screen
. Il collegamento ssh
rimarrà attivo indipendentemente dalla durata dell'addestramento.
Eseguire il debug degli errori comuni
Impossibile creare una TPU
Quando crei una Cloud TPU, potresti riscontrare 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."
Questo è un problema di autorizzazioni e può essere risolto eseguendo questo comando:
gcloud auth login --update-adc
Questo comando aggiorna le Credenziali predefinite dell'applicazione (ADC) e dovrebbe risolvere il problema. Per saperne di più, vedi gcloud auth login.
Impossibile utilizzare il file system locale
Messaggio di errore
InvalidArgumentError: Unimplemented: File system scheme '[local]' not implemented
Framework e configurazioni interessati
Questo messaggio può verificarsi durante l'addestramento con TensorFlow utilizzando l'architettura dei nodi TPU.
Dettagli
Tutti i file di input e la directory dei modelli devono utilizzare un percorso del bucket di spazio di archiviazione sul cloud (gs://bucket-name/...
) e questo bucket deve essere accessibile dal server TPU. Tieni presente che tutte le elaborazioni dei dati e il checkpoint dei modelli vengono eseguite sul server TPU, non sulla macchina locale. Per informazioni su come configurare correttamente spazio di archiviazione sul cloud per l'utilizzo con TPU, consulta la guida Connessione a bucket Cloud Storage.
Tipo di dati non supportato
Messaggio di errore
TypeError: DataType is not a supported TPU infeed type.
Framework e configurazioni interessati
Questo messaggio può verificarsi durante l'addestramento con TensorFlow utilizzando l'architettura dei nodi TPU.
Dettagli
Attualmente, solo i tipi di dati tf.float32
, tf.int32
, tf.bfloat16
e tf.bool
sono supportati sulla TPU. Altri tipi di dati comuni, come tf.uint8
,
tf.string
e tf.int64
, devono essere convertiti in uno dei tipi di dati supportati durante la pre-elaborazione dei dati (ovvero nella pipeline tf.data.Dataset).
Vedi un esempio di conversione nella funzione decode_image
utilizzata nell'addestramento MNIST.
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, TensorFlow lo compila utilizzando il compilatore XLA. Sebbene questo passaggio di compilazione migliori notevolmente la velocità di addestramento e l'utilizzo della memoria, le forme (dimensioni delle dimensioni) di tutti i tensori nel grafico devono essere note al momento della compilazione del grafico. Se non è possibile determinare alcuna forma al momento della compilazione, la compilazione TPU ha esito negativo con un errore come quello riportato sopra.
Un'operazione comune che restituisce una forma dinamica è dataset.batch(batch_size)
, poiché il numero di campioni rimanenti in un flusso potrebbe essere inferiore alle dimensioni del batch. Pertanto, durante l'addestramento sulla TPU, imposta drop remainder=True
per dataset.batch
.
Gli ultimi esempi di file potrebbero essere eliminati da un file per garantire che ogni batch abbia una forma statica batch_size. Ad esempio:
dataset = tf.data.Dataset.range(8)
dataset = dataset.batch(3, drop_remainder=True)
Operazioni TensorFlow non disponibili
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 che non è attualmente disponibile sulla TPU.
Per un elenco delle operazioni disponibili sulla TPU, insieme ai piani per l'assistenza futura e i suggerimenti per le soluzioni alternative, consulta la guida alle operazioni di TensorFlow disponibili.
Messaggio di errore per 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 memoria HBM ad alta larghezza di banda). Questa memoria viene utilizzata per archiviare i tensori di ponderazione (variabile), nonché i tensori di risultato intermedi necessari per il calcolo dei gradienti. Se il modello è troppo grande per essere inserito nella RAM TPU, l'inizializzazione non riesce e il messaggio di errore riportato sopra viene stampato. Per ulteriori informazioni, consulta la sezione sulla riduzione dell'utilizzo della memoria.
Suggerimenti per ridurre l'utilizzo della memoria:
- Verifica se è presente eccesso di spaziatura interna del tensore
- Usa il formato bfloating16
- Se le dimensioni di input o il modello sono troppo grandi, potresti utilizzare il parallelismo del modello sperimentale di TensorFlow per risolvere le dimensioni del modello.
Problemi con l'interruzione dell'esecuzione
Se TensorFlow riscontra un errore durante l'esecuzione di TPU, lo script a volte sembra smettere di rispondere anziché uscire dalla shell. In questo caso, premi CTRL+\
sulla tastiera per attivare SIGQUIT
, causando l'uscita immediata da parte di Python.
Allo stesso modo, la pressione di CTRL+C
durante l'esecuzione di TPU non comporta l'arresto immediato di TensorFlow, ma attende invece fino alla fine del loop di iterazione corrente per l'uscita pulita.
Se si verificano nuovi errori durante la riconnessione alla TPU dopo l'uscita in questo modo, ripristina 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 ricavato dalla prima colonna visualizzata dal comando gcloud compute tpus list
e zone è la zona mostrata nella seconda colonna.
Spaziatura interna eccessiva del tensore
Possibile causa di problema di memoria
I tensori in memoria TPU sono imbottiti, ovvero la TPU arrotonda le dimensioni dei tensori archiviati in memoria per eseguire i calcoli in modo più efficiente. Questa spaziatura interna avviene in modo trasparente a livello di hardware e non influisce sui risultati. In alcuni casi, tuttavia, la spaziatura interna può comportare un aumento significativo dell'utilizzo e dei tempi di esecuzione della memoria.
Come ridurre l'utilizzo di memoria
Il software TPU tenta di disporre i tensori in memoria per massimizzare l'efficienza di calcolo e ridurre al minimo la spaziatura interna. Questo processo di layout della memoria è tuttavia complesso, per ottenere risultati ottimali il modello deve rispettare la seguente regola generale. Per ridurre al minimo l'overhead di memoria e massimizzare l'efficienza di calcolo, è necessario che si verifichi una delle seguenti condizioni:
Le dimensioni totali del batch devono essere un multiplo di 64 (8 per core TPU) e le dimensioni della funzionalità 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 della funzionalità devono essere un multiplo di 8.
L'utilizzo di una dimensione batch di 1024 e dimensioni di funzionalità che sono un multiplo di 128 genera la migliore efficienza, anche se potrebbe non essere possibile per tutti i modelli. Per chiarezza, "dimensione della caratteristica" si riferisce alla dimensione nascosta di un livello connesso completamente 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 di rete. Non è un problema e si prevede che la maggior parte dei modelli richieda una certa spaziatura interna.
Riduzione dell'utilizzo della memoria
Se si verifica un errore di memoria esaurita durante l'esecuzione del modello sulla TPU, devi seguire alcuni passaggi per ridurre la memoria utilizzata dal modello.
I modi più efficaci per ridurre l'utilizzo di memoria sono:
- Riduci la spaziatura interna con tensore eccessivo
- Ridurre le dimensioni del batch
Dimensioni o modello del batch troppo grandi
Possibile causa di problema di memoria
Quando addestra una rete neurale su una CPU, GPU o TPU, l'utilizzo della memoria proviene da due punti:
- L'utilizzo della memoria è proporzionale al numero di ponderazioni del modello.
- Memorizzazione delle attivazioni intermedie dal passaggio in avanti necessario per calcolare il pass precedente. 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 livelli nella rete.
Il runtime TPU tenta di ottimizzare gli operatori per adattare il modello alla memoria (denominata rematerializzazione, simile al checkpoint di gradiente), ma non è sempre in grado di farlo.
Come ridurre l'utilizzo di memoria
Riduci lentamente le dimensioni del batch finché non entrano 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). Ricorda che i batch di dimensioni maggiori sono più efficienti sulla TPU. Una dimensione totale del batch pari a 1024 (128 per core) è in genere un buon punto di partenza.
Se il modello non può essere eseguito su TPU anche con una dimensione del batch di piccole dimensioni (ad esempio, 64), prova a ridurre il numero di livelli o le dimensioni del livello.
Migliorare la velocità di addestramento
Se il tuo modello è in grado di funzionare correttamente sulla TPU, ma la velocità di addestramento è inferiore al previsto, in questa sezione vengono descritti diversi modi per migliorare la velocità. Consulta la Guida al rendimento per altri suggerimenti su come migliorare il rendimento dell'addestramento.
Troppi pochi passaggi per esecuzione per ciclo di addestramento
Descrizione del problema di rendimento
Il trasferimento dell'argomento steps_per_execution
a Model.compile
determina il numero di passaggi di addestramento eseguiti tra i callback host.
Ogni callback 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 sapere se il tuo modello è interessato
Se un profilo TPU rivela callback di CPU host frequenti tra i passaggi del dispositivo TPU, l'addestramento può trarre vantaggio da un valore steps_per_execution
più elevato.
Come attenuare
Imposta steps_per_execution
su un valore 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 verificarsi solo dopo che è stato eseguito
il numero di passaggi specificato.
Collo di bottiglia nell'elaborazione dell'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 sulla CPU. Se la funzione di input richiede più tempo rispetto alla funzione di modello, la TPU viene lasciata inattiva mentre la funzione di input recupera i dati.
Come sapere se il tuo modello è interessato
Segui le istruzioni nell'articolo Cloud TPU Tools: Input Pipeline Analyzer per visualizzare l'analisi della pipeline di input in TensorBoard:
La pagina di analisi della pipeline di input mostra un riepilogo chiaro che mostra se il tuo modello è stato bloccato da un'elaborazione di input. La stessa pagina mostra inoltre i tempi di esecuzione per operazione, che ti consentono di individuare le operazioni problematiche.
Come attenuare
Esistono diverse possibili mitigazioni durante il caricamento dei dati con l'API Dataset
:
- Archivia i dati come una raccolta di strutture
tf.train.Example
inTFRecord
file e caricali conTFRecordDataset
. Consulta gli esempi di tutorial per set di dati o tutorial di ResNet. - Utilizza
dataset.cache()
e/odataset.prefetch()
per eseguire il buffering dei dati di input. In questo modo si impedisce una sporadica lentezza nell'accesso ai file e la conseguente creazione di un collo di bottiglia. - Specifica il parametro
num_parallel_calls
della funzionedataset.map()
per abilitare le operazionimap()
con più thread. Una semplice euristica per il valore dinum_parallel_calls
consiste nell'utilizzare il numero di core CPU disponibili. - Esegui pre-elaborazione dei dati costosi offline come costo una tantum, invece di incorrere in costi in ogni periodo di addestramento.
L'intera elaborazione di input viene eseguita sulle CPU situate sul server TPU, non sulla macchina locale, quindi la velocità della macchina locale non è un fattore determinante.
Tempi di passo lenti e basso utilizzo di MXU
Descrizione del problema di rendimento
Cloud TPU è in grado di eseguire moltiplicazioni delle matrici e convoluzioni a velocità incredibilmente elevate. La maggior parte delle altre operazioni TensorFlow ha implementazioni efficienti sulla TPU, ma non sono la forza principale di TPU rispetto ad altri hardware. Pertanto, un modello dovrebbe essere dominato da moltiplicazioni delle matrici o convoluzioni per sfruttare appieno la TPU.
Come sapere se il tuo modello è interessato
I sintomi che troverai in questo caso sono tempi di passaggio lenti associati a un utilizzo ridotto dei record MXU mostrato quando imposti il profilo delle prestazioni.
Come attenuare
Prova a ridurre il numero di operazioni che non sono moltiplicazioni di matrici. Dopo aver ridotto il numero di moltiplicazioni delle matrici, ri-benchmark per verificare se le prestazioni sono accettabili sulle TPU.
Spaziatura interna eccessiva del tensore
Descrizione del problema di rendimento
I cuscinetti TPU si muovono in memoria in modo che la TPU possa utilizzare le sue unità di calcolo in modo efficiente. La spaziatura interna può aumentare l'utilizzo di memoria e larghezza di banda della memoria. Consulta la sezione Spaziatura interna tensore per comprendere e risolvere i problemi relativi alla spaziatura interna dei tensori.
Velocità effettiva lenta e utilizzo ridotto della memoria
Descrizione del problema di rendimento
Come regola generale, l'utilizzo di dimensioni batch più grandi determina una maggiore velocità di addestramento sulla TPU, in termini di esempi/secondo.
Come sapere se il tuo modello è interessato
La dimensione del batch di qualsiasi modello deve essere sempre almeno 64 (8 per core TPU), poiché la TPU riduce sempre i tensori a questa dimensione. Le dimensioni batch ideali per l'addestramento su TPU sono 1024 (128 per core TPU), poiché eliminano le inefficienze relative al trasferimento e alla spaziatura interna della memoria.
Come attenuare
La best practice prevede l'utilizzo delle dimensioni batch più grandi che si adattano alla memoria ed è un multiplo di 64. Il modo più semplice per raggiungere questo obiettivo è iniziare con 1024 e, se questo causa un errore di esaurimento della memoria, prova a ridurre le dimensioni del batch finché il modello non viene eseguito correttamente. La modifica delle dimensioni del batch di un modello può richiedere la regolazione di altri iperparametri per ottenere la stessa precisione del modello, ad esempio il tasso di apprendimento, ma questo deve essere valutato caso per caso.
Dimensioni del livello troppo piccole
Descrizione del problema di rendimento
Anche quando un modello è dominato da moltiplicazioni o convoluzioni delle matrici, la TPU potrebbe non funzionare alla massima efficienza se i tensori di input sono piccoli. Rispetto ad altri hardware, il TPU è più efficiente se le dimensioni del batch e delle dimensioni sono grandi (ad esempio, dimensione >= 512).
Come sapere se il tuo modello è interessato
Come regola generale, le dimensioni dei livelli inferiori a 128 raggiungono una scarsa efficienza sulla TPU, dato che 128 è la dimensione nativa dell'unità di moltiplicazione della matrice TPU. Per ottenere livelli ad alta efficienza per i livelli completamente connessi, si consiglia una dimensione nascosta minima 512. Ricorda che i livelli convoluzionali in genere non devono essere grandi quanto quelli completamente collegati per raggiungere lo stesso livello di efficienza.
Come attenuare
Se la motivazione principale per le taglie di strato piccole nel tuo modello è la velocità di addestramento, esegui nuovamente il benchmark dei tuoi modelli con strati più grandi sulla TPU. Ad esempio, aumentare le dimensioni dell'output di un livello da 256 a 512 può solo aumentare il tempo di addestramento del 20% anche se il modello esegue il doppio dei calcoli.
Profilazione di modelli a livello di opera d'arte
Spesso è utile misurare il tempo di esecuzione a livello di op e l'utilizzo della memoria per identificare i colli di bottiglia delle prestazioni. Per istruzioni su come eseguire questa operazione,
consulta la guida Strumenti di Cloud TPU: Visualizzatore tracce.
Eseguire il debug di cali dell'accuratezza del modello
Uno degli obiettivi dell'ecosistema Cloud TPU è che qualsiasi modello attualmente in fase di addestramento su una CPU o GPU ottiene una precisione molto simile quando viene addestrato sulla TPU, con forse piccoli aggiustamenti agli iperparametri come la dimensione del batch e la velocità di apprendimento. A volte, tuttavia, gli utenti possono notare un degrado di accuratezza durante l'addestramento dei modelli sulla TPU. Il debug di questi problemi può essere estremamente frustrante a causa della natura casuale dell'addestramento della rete neurale. Questa sezione fornisce indicazioni su come individuare la causa principale di eventuali cali di accuratezza del modello quando trasferisci un modello alla TPU.
Informazioni sullo sharding dei dati (parallelism dei dati)
Uno degli obiettivi principali di TensorFlow è che ogni operazione deve produrre risultati quasi identici, indipendentemente dal fatto che venga eseguita su CPU, GPU o TPU. Esistono alcune eccezioni a questa regola, ad esempio le operazioni casuali. In generale, se rilevi una differenza significativa tra l'output delle operazioni non casuali sulla TPU e sulla CPU, segnalalo come bug.
Tuttavia, per la pipeline di addestramento nel suo insieme, esiste una significativa differenza tra l'addestramento su CPU/GPU e TPU. Quando si esegue 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 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 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'operatività più comune non indipendente per campione è la normalizzazione 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 è 16 e ciascuno degli 8 core esegue la normalizzazione sui propri 16 campioni. In alcuni casi, la normalizzazione dei batch su piccoli batch (ad esempio, meno di 32) ha riscontrato un peggioramento della precisione. Nello scenario ideale, le dimensioni totali del batch devono essere grandi (ad esempio, da 256 a 1024). Se la dimensione del batch è troppo grande per essere inserita in memoria, l'effetto dello sharding deve essere valutato caso per caso.
Addestramento determinazione
Un motivo per cui è difficile eseguire il debug delle differenze di accuratezza del modello è che in diversi framework (TensorFlow, PyTorch, JAX), il software di addestramento utilizza diverse inizializzazioni di peso e data shuffling ogni volta che un modello viene addestrato. È bene modificare la procedura di addestramento in modo che sia deterministica, in modo che più esecuzioni restituiscano modelli quasi identici. Questa sezione illustra come eseguire il tutorial MNIST in modo deterministico:
- Generare un file di checkpoint iniziale eseguendo un singolo passaggio sulla CPU. Il passaggio viene utilizzato per ottenere l'inizializzazione del peso deterministico. Inoltre, assicurati di utilizzare un seed casuale fisso per qualsiasi funzione casuale del 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
- Modifica le funzioni di data shuffling nella funzione di input per 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 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)
-
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 per raggiungere la convergenza.
Dato che l'addestramento della CPU viene confrontato con un addestramento di un singolo core TPU, utilizza una dimensione del batch che può adattarsi a un singolo core TPU (in genere, la dimensione intera del batch diviso per 8). TensorFlow non garantisce il determinismo bit per bit tra le esecuzioni, ma la perdita dovrebbe essere molto simile:
Copia le ponderazioni 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 TPU singolo core
Dopo aver eseguito il tutorial MNIST in modo deterministico, il passaggio successivo consiste nella replica dei risultati addestrati dalla CPU sulla TPU, utilizzando un singolo core TPU per indicare se il problema è legato allo sharding dei dati o al motore di esecuzione della TPU stesso.
Ecco come eseguire l'addestramento e la valutazione single-core sul tutorial MNIST:
Utilizza la stessa inizializzazione sulla ponderazione 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
Output
accuracy = 0.9910644, global_step = 1000, loss = 0.02514153
La perdita non corrisponderà esattamente al modello addestrato dalla CPU, ma dovrebbe essere vicina. Se non è simile al tuo modello, potrebbe significare che hai trovato un bug nel motore di esecuzione della TPU. Prima di inviare una segnalazione di bug, verifica quanto segue:
Stai passando
num_shards=1
aTPUConfig
.Non esistono operazioni casuali nella funzione del modello e le operazioni casuali nella funzione di input vengono sottoposte a seeding corretto.
Stai utilizzando lo stesso file di checkpoint iniziale per l'addestramento della CPU e della TPU.
Debug dell'addestramento della TPU multi-core
Se il tuo modello ottiene la stessa perdita sulla CPU e sul TPU single-core, il problema è probabilmente uno dei seguenti:
(a) Il degrado è dovuto alla varianza naturale naturale durante l'addestramento di 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 sul peso, come sopra.
Se hai la certezza che il calo di accuratezza sia statisticamente significativo, i problemi più probabili relativi allo sharding dei dati sono:
- Se il tuo modello utilizza la normalizzazione batch, una dimensione totale del batch inferiore a 256 (ad esempio, inferiore a 32 per core) potrebbe ridurre la precisione.
- Le funzioni di perdita in modalità batch sono interessate dallo sharding. Queste funzioni di perdita sono in genere piuttosto specializzate. Ad esempio, Karras et al.2017 utilizza un discriminatore batch durante l'addestramento di una rete generativa di contraddizione.
Risoluzione dei problemi delle VM TPU
I seguenti problemi e soluzioni sono applicabili solo alle configurazioni di VM TPU.
Risoluzione dei problemi di configurazione di gcloud
- Problema
gcloud components update
visualizza 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
con una VM TPU, devi utilizzare un'installazionegcloud
non gestita tramite un gestore di pacchetti. Per installaregcloud
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 essersi verificato un problema di 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 tramite una libreria condivisa denominata libtpu
presente in 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.
Puoi impostare le seguenti variabili di ambiente prima di iniziare l'addestramento per modificare il comportamento di logging:
- TPU_LOG_DIR: la directory in cui vengono scritti i log
- Il percorso predefinito della directory è
/tmp/tpu_logs
. La directory viene creata se non esiste già, ma non vengono create directory padre. Se si verifica un errore durante la ricerca o la creazione della directory specificata, un messaggio viene stampato su stderr, ma non interrompe il programma e il logging viene disabilitato. Imposta il nome della directory su "disattivato" per disabilitare del tutto il logging sul disco. - TPU_MIN_LOG_LEVEL: la gravità minima che verrà registrata sul disco
- Le opzioni sono 0 (INFO), 1 (AVVISO), 2 (ERRORE) e 3 (FATALE). Il valore predefinito è 0.
- TPU_STDERR_LOG_LEVEL: la gravità minima che verrà registrata su stderr, oltre al disco, se applicabile
- Le opzioni disponibili 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
- Un nuovo file di log verrà avviato automaticamente quando quello precedente raggiungerà approssimativamente le dimensioni. Il valore predefinito è 1024.