Formazione distribuita con TensorFlow

Visualizza su TensorFlow.org Esegui in Google Colab Visualizza la fonte su GitHub Scarica taccuino

Panoramica

tf.distribute.Strategy è un'API tensorflow formazione di distribuire su più GPU, macchine multiple o TPU. Utilizzando questa API, puoi distribuire i tuoi modelli esistenti e il codice di addestramento con modifiche minime al codice.

tf.distribute.Strategy è stata progettata con questi obiettivi chiave in mente:

  • Facile da usare e supporta più segmenti di utenti, inclusi ricercatori, ingegneri di machine learning, ecc.
  • Fornire buone prestazioni fuori dagli schemi.
  • Facile passaggio da una strategia all'altra.

È possibile distribuire formazione utilizzando tf.distribute.Strategy con un'API di alto livello come Keras Model.fit , così come i cicli di formazione personalizzati (e, in generale, qualsiasi calcolo utilizzando tensorflow).

In tensorflow 2.x, è possibile eseguire i programmi con entusiasmo, o in un grafico utilizzando tf.function . tf.distribute.Strategy intende sostenere entrambe queste modalità di esecuzione, ma funziona meglio con tf.function . Modalità Eager è consigliato solo per scopi di debug e non supportato per tf.distribute.TPUStrategy . Sebbene la formazione sia al centro di questa guida, questa API può essere utilizzata anche per distribuire valutazioni e previsioni su piattaforme diverse.

È possibile utilizzare tf.distribute.Strategy con pochissime modifiche al codice, perché i componenti sottostanti di tensorflow sono stati cambiati per diventare la strategia-aware. Ciò include variabili, livelli, modelli, ottimizzatori, metriche, riepiloghi e punti di controllo.

In questa guida imparerai a conoscere vari tipi di strategie e come usarle in diverse situazioni. Per informazioni su come eseguire il debug problemi di prestazioni, controllare le prestazioni Ottimizzare tensorflow GPU guida.

Configura TensorFlow

import tensorflow as tf

Tipi di strategie

tf.distribute.Strategy intende coprire un numero di casi d'uso lungo assi differenti. Alcune di queste combinazioni sono attualmente supportate e altre verranno aggiunte in futuro. Alcuni di questi assi sono:

  • Sincrona vs formazione asincrona: Si tratta di due modi comuni di distribuzione di allenamento con il parallelismo dei dati. Nella formazione sincronizzata, tutti i lavoratori si addestrano su diverse sezioni di dati di input in sincronia e aggregando i gradienti a ogni passaggio. Nell'addestramento asincrono, tutti i lavoratori si addestrano in modo indipendente sui dati di input e aggiornano le variabili in modo asincrono. In genere, l'addestramento alla sincronizzazione è supportato tramite all-reduce e async tramite l'architettura del server dei parametri.
  • Piattaforma hardware: Si consiglia di scalare la vostra formazione su più GPU su una macchina, o più macchine in rete (con 0 o più GPU ciascuno), o su Cloud TPU.

Al fine di sostenere questi casi d'uso, tensorflow ha MirroredStrategy , TPUStrategy , MultiWorkerMirroredStrategy , ParameterServerStrategy , CentralStorageStrategy , così come altre strategie disponibili. La sezione successiva spiega quali di questi sono supportati in quali scenari in TensorFlow. Ecco una rapida panoramica:

API di formazione MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Keras Model.fit Supportato Supportato Supportato Supporto sperimentale Supporto sperimentale
Ciclo di allenamento personalizzato Supportato Supportato Supportato Supporto sperimentale Supporto sperimentale
Stima API Supporto limitato Non supportato Supporto limitato Supporto limitato Supporto limitato

Strategia speculare

tf.distribute.MirroredStrategy supporti sincronismo distribuito formazione su più GPU su una macchina. Crea una replica per dispositivo GPU. Ogni variabile nel modello viene rispecchiata in tutte le repliche. Insieme, queste variabili formano un'unica variabile concettuale chiamato MirroredVariable . Queste variabili vengono mantenute sincronizzate tra loro applicando aggiornamenti identici.

Vengono utilizzati efficienti algoritmi all-reduce per comunicare gli aggiornamenti delle variabili tra i dispositivi. Riduci tutti i tensori aggregati su tutti i dispositivi sommandoli e rendendoli disponibili su ciascun dispositivo. È un algoritmo fuso che è molto efficiente e può ridurre significativamente il sovraccarico della sincronizzazione. Sono disponibili molti algoritmi e implementazioni all-reduce, a seconda del tipo di comunicazione disponibile tra i dispositivi. Per impostazione predefinita, utilizza il NVIDIA Collettivo Biblioteca Comunicazione ( NCCL ) l'attuazione all-ridurre. Puoi scegliere tra alcune altre opzioni o scriverne di tue.

Ecco il modo più semplice di creare MirroredStrategy :

mirrored_strategy = tf.distribute.MirroredStrategy()
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

Ciò creerà una MirroredStrategy esempio, che utilizzerà tutte le GPU che sono visibili a tensorflow e NCCL, come la comunicazione tra dispositivi.

Se desideri utilizzare solo alcune delle GPU sulla tua macchina, puoi farlo in questo modo:

mirrored_strategy = tf.distribute.MirroredStrategy(devices=["/gpu:0", "/gpu:1"])
WARNING:tensorflow:Some requested devices in `tf.distribute.Strategy` are not visible to TensorFlow: /job:localhost/replica:0/task:0/device:GPU:1,/job:localhost/replica:0/task:0/device:GPU:0
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0', '/job:localhost/replica:0/task:0/device:GPU:1')

Se si vuole modificare il dispositivo di comunicazione trasversale, è possibile farlo utilizzando la cross_device_ops tesi fornendo un esempio di tf.distribute.CrossDeviceOps . Attualmente, tf.distribute.HierarchicalCopyAllReduce e tf.distribute.ReductionToOneDevice sono due opzioni diverse tf.distribute.NcclAllReduce , che è il default.

mirrored_strategy = tf.distribute.MirroredStrategy(
    cross_device_ops=tf.distribute.HierarchicalCopyAllReduce())
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

TPUStrategia

tf.distribute.TPUStrategy consente di eseguire il tuo allenamento tensorflow sul Tensor Processing Unit (TPU) . I TPU sono ASIC specializzati di Google progettati per accelerare notevolmente i carichi di lavoro di machine learning. Sono disponibili sul Google Colab , la ricerca Nuvola TPU , e cloud TPU .

In termini di architettura distribuita formazione, TPUStrategy è lo stesso MirroredStrategy -è attrezzi sincroni formazione distribuita. TPU forniscono una propria implementazione di operazioni collettive efficienti all ridurre e altri su più core TPU, che vengono utilizzati in TPUStrategy .

Ecco come si potrebbe istanziare TPUStrategy :

cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver(
    tpu=tpu_address)
tf.config.experimental_connect_to_cluster(cluster_resolver)
tf.tpu.experimental.initialize_tpu_system(cluster_resolver)
tpu_strategy = tf.distribute.TPUStrategy(cluster_resolver)

Il TPUClusterResolver esempio aiuta a localizzare il TPU. In Colab, non è necessario specificare alcun argomento.

Se desideri utilizzarlo per le Cloud TPU:

  • È necessario specificare il nome della risorsa TPU in tpu argomento.
  • È necessario inizializzare il sistema TPU esplicitamente all'inizio del programma. Ciò è necessario prima che le TPU possano essere utilizzate per il calcolo. L'inizializzazione del sistema tpu cancella anche la memoria TPU, quindi è importante completare prima questo passaggio per evitare di perdere lo stato.

MultiWorkerMirroredStrategy

tf.distribute.MultiWorkerMirroredStrategy è molto simile a MirroredStrategy . Implementa la formazione distribuita sincrona su più lavoratori, ciascuno con potenzialmente più GPU. Simile a tf.distribute.MirroredStrategy , crea copie di tutte le variabili del modello su ogni dispositivo su tutti i lavoratori.

Ecco il modo più semplice di creare MultiWorkerMirroredStrategy :

strategy = tf.distribute.MultiWorkerMirroredStrategy()
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.AUTO

MultiWorkerMirroredStrategy ha due implementazioni per le comunicazioni cross-device. CommunicationImplementation.RING è RPC -based e supporta sia CPU e GPU. CommunicationImplementation.NCCL utilizza NCCL e fornisce allo stato dell'arte prestazioni su GPU ma non supporta CPU. CollectiveCommunication.AUTO rinvia la scelta di tensorflow. Puoi specificarli nel modo seguente:

communication_options = tf.distribute.experimental.CommunicationOptions(
    implementation=tf.distribute.experimental.CommunicationImplementation.NCCL)
strategy = tf.distribute.MultiWorkerMirroredStrategy(
    communication_options=communication_options)
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.NCCL

Una delle differenze chiave per ottenere la formazione multi-lavoratore, rispetto alla formazione multi-GPU, è la configurazione multi-lavoratore. Il 'TF_CONFIG' variabile d'ambiente è il modo standard in tensorflow per specificare la configurazione del cluster per ogni lavoratore che fa parte del cluster. Per saperne di più nella creazione sezione TF_CONFIG di questo documento.

Per maggiori dettagli su MultiWorkerMirroredStrategy , prendere in considerazione le seguenti esercitazioni:

ParametroServerStrategy

L'addestramento del server dei parametri è un metodo comune di parallelismo dei dati per aumentare l'addestramento del modello su più macchine. Un cluster di formazione del server dei parametri è costituito da worker e server dei parametri. Le variabili vengono create sui server dei parametri e vengono lette e aggiornate dai lavoratori in ogni passaggio. Controlla la formazione Server Parametro tutorial per i dettagli.

In tensorflow 2, la formazione di server parametro utilizza un'architettura centro coordinatore a base tramite il tf.distribute.experimental.coordinator.ClusterCoordinator di classe.

In questa implementazione, i worker e parameter server compiti eseguiti tf.distribute.Server s che ascoltano per le attività del coordinatore. Il coordinatore crea risorse, invia attività di formazione, scrive checkpoint e gestisce gli errori delle attività.

Nella programmazione in esecuzione sul coordinatore, si utilizzerà un ParameterServerStrategy oggetto per definire un passo di formazione e di utilizzare un ClusterCoordinator di spedire passi di formazione per i lavoratori remoti. Ecco il modo più semplice per crearli:

strategy = tf.distribute.experimental.ParameterServerStrategy(
    tf.distribute.cluster_resolver.TFConfigClusterResolver(),
    variable_partitioner=variable_partitioner)
coordinator = tf.distribute.experimental.coordinator.ClusterCoordinator(
    strategy)

Per ulteriori informazioni su ParameterServerStrategy , controlla la formazione server di parametri con Keras Model.fit e un ciclo di formazione personalizzato tutorial.

In tensorflow 1, ParameterServerStrategy è disponibile solo con uno stimatore tramite tf.compat.v1.distribute.experimental.ParameterServerStrategy simbolo.

Strategia di archiviazione centrale

tf.distribute.experimental.CentralStorageStrategy fa formazione sincrona pure. Le variabili non vengono rispecchiate, ma vengono posizionate sulla CPU e le operazioni vengono replicate su tutte le GPU locali. Se è presente una sola GPU, tutte le variabili e le operazioni verranno posizionate su quella GPU.

Creare un'istanza di CentralStorageStrategy da:

central_storage_strategy = tf.distribute.experimental.CentralStorageStrategy()
INFO:tensorflow:ParameterServerStrategy (CentralStorageStrategy if you are using a single machine) with compute_devices = ['/job:localhost/replica:0/task:0/device:GPU:0'], variable_device = '/job:localhost/replica:0/task:0/device:GPU:0'

Questo creerà un CentralStorageStrategy grado che utilizzerà tutte le GPU visibili e CPU. L'aggiornamento alle variabili sulle repliche verrà aggregato prima di essere applicato alle variabili.

Altre strategie

In aggiunta alle strategie sopra, ci sono altri due strategie che possono essere utili per la prototipazione e debug utilizzando tf.distribute API.

Strategia predefinita

La strategia predefinita è una strategia di distribuzione presente quando non è prevista alcuna strategia di distribuzione esplicita. Implementa l' tf.distribute.Strategy interfaccia, ma è un pass-through e non fornisce alcuna effettiva distribuzione. Per esempio, strategy.run(fn) si limiterà a chiamare fn . Il codice scritto utilizzando questa strategia dovrebbe comportarsi esattamente come il codice scritto senza alcuna strategia. Puoi pensarla come una strategia "no-op".

La strategia predefinita è un singleton e non è possibile crearne più istanze. Essa può essere ottenuta utilizzando tf.distribute.get_strategy fuori portata di qualsiasi strategia esplicita (la stessa API che può essere utilizzato per ottenere la strategia di corrente all'interno portata di una strategia esplicita).

default_strategy = tf.distribute.get_strategy()

Questa strategia ha due scopi principali:

  • Consente di scrivere incondizionatamente codice di libreria in grado di riconoscere la distribuzione. Per esempio, in tf.optimizer s è possibile utilizzare tf.distribute.get_strategy e l'uso che la strategia per la riduzione delle pendenze, sarà sempre restituire un oggetto strategia su cui è possibile chiamare lo Strategy.reduce API.
# In optimizer or other library code
# Get currently active strategy
strategy = tf.distribute.get_strategy()
strategy.reduce("SUM", 1., axis=None)  # reduce some values
1.0
  • Simile al codice della libreria, può essere utilizzato per scrivere programmi degli utenti finali per lavorare con e senza strategia di distribuzione, senza richiedere logica condizionale. Ecco un frammento di codice di esempio che illustra questo:
if tf.config.list_physical_devices('GPU'):
  strategy = tf.distribute.MirroredStrategy()
else:  # Use the Default Strategy
  strategy = tf.distribute.get_strategy()

with strategy.scope():
  # Do something interesting
  print(tf.Variable(1.))
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
MirroredVariable:{
  0: <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>
}

OneDeviceStrategy

tf.distribute.OneDeviceStrategy è una strategia di posizionare tutte le variabili e calcolo su un singolo dispositivo specificato.

strategy = tf.distribute.OneDeviceStrategy(device="/gpu:0")

Questa strategia è diversa dalla strategia predefinita in diversi modi. Nella strategia predefinita, la logica di posizionamento variabile rimane invariata rispetto all'esecuzione di TensorFlow senza alcuna strategia di distribuzione. Ma quando si utilizza OneDeviceStrategy , tutte le variabili create nel suo ambito sono esplicitamente collocati sul dispositivo specificato. Inoltre, qualsiasi funzione chiamata tramite OneDeviceStrategy.run saranno posizionati sul dispositivo specificato.

L'input distribuito tramite questa strategia verrà precaricato sul dispositivo specificato. Nella strategia predefinita, non c'è distribuzione di input.

Simile alla strategia predefinita, questa strategia potrebbe essere utilizzata anche per testare il codice prima di passare ad altre strategie che effettivamente si distribuiscono su più dispositivi/macchine. Ciò eserciterà il macchinario strategia di distribuzione un po 'più rispetto alla strategia predefinita, ma non nella misura massima di utilizzo, ad esempio, MirroredStrategy o TPUStrategy . Se vuoi un codice che si comporti come se non ci fosse una strategia, usa la strategia predefinita.

Finora hai imparato a conoscere diverse strategie e come puoi istanziarle. Le prossime sezioni mostrano i diversi modi in cui puoi usarle per distribuire la tua formazione.

Usa tf.distribute.Strategy con Keras Model.fit

tf.distribute.Strategy è integrato in tf.keras , che è l'implementazione del tensorflow specifiche API Keras . tf.keras è un'API di alto livello ai modelli di generazione e dei treni. Integrando nel tf.keras backend, è senza soluzione di continuità per voi per distribuire il vostro allenamento scritto nel quadro di formazione Keras utilizzando Model.fit .

Ecco cosa devi modificare nel tuo codice:

  1. Creare un'istanza della appropriata tf.distribute.Strategy .
  2. Spostare la creazione di Keras modello, Optimizer e metriche all'interno strategy.scope .

Strategie di distribuzione tensorflow supportano tutti i tipi di Keras MODELLI sequenziale , funzionale , e sottoclasse .

Ecco un frammento di codice per fare questo per un modello molto semplice Keras con un Dense strato di:

mirrored_strategy = tf.distribute.MirroredStrategy()

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])

model.compile(loss='mse', optimizer='sgd')
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

Questo esempio utilizza MirroredStrategy , in modo da poter eseguire questo su una macchina con più GPU. strategy.scope() indica a Keras quale strategia da utilizzare per distribuire il training. La creazione di modelli/ottimizzatori/metriche all'interno di questo ambito consente di creare variabili distribuite anziché variabili regolari. Una volta impostato, puoi adattare il tuo modello come faresti normalmente. MirroredStrategy si prende cura di replicare la formazione del modello sulle GPU disponibili, aggregando gradienti, e altro ancora.

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(10)
model.fit(dataset, epochs=2)
model.evaluate(dataset)
2021-09-22 20:33:41.551842: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}
Epoch 1/2
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
10/10 [==============================] - 3s 2ms/step - loss: 2.4687
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 1.0912
2021-09-22 20:33:44.537154: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}
10/10 [==============================] - 1s 2ms/step - loss: 0.6776
0.6776412129402161

Ecco un tf.data.Dataset prevede la formazione e l'ingresso eval. Puoi anche usare gli array NumPy:

import numpy as np

inputs, targets = np.ones((100, 1)), np.ones((100, 1))
model.fit(inputs, targets, epochs=2, batch_size=10)
Epoch 1/2
2021-09-22 20:33:45.820303: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Did not find a shardable source, walked to a node which is not a dataset: name: "FlatMapDataset/_9"
op: "FlatMapDataset"
input: "PrefetchDataset/_8"
attr {
  key: "Targuments"
  value {
    list {
    }
  }
}
attr {
  key: "f"
  value {
    func {
      name: "__inference_Dataset_flat_map_slice_batch_indices_997"
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 10
        }
      }
    }
  }
}
attr {
  key: "output_types"
  value {
    list {
      type: DT_INT64
    }
  }
}
. Consider either turning off auto-sharding or switching the auto_shard_policy to DATA to shard this dataset. You can do this by creating a new `tf.data.Options()` object then setting `options.experimental_distribute.auto_shard_policy = AutoShardPolicy.DATA` before applying the options object to the dataset via `dataset.with_options(options)`.
10/10 [==============================] - 1s 2ms/step - loss: 0.4823
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.2132
<keras.callbacks.History at 0x7f12645690d0>

In entrambi i casi con- Dataset o NumPy-ciascun lotto di sollecitazione che è diviso equamente tra i più repliche. Ad esempio, se si utilizza il MirroredStrategy con 2 GPU, ogni lotto di dimensioni 10 otterrà diviso tra le GPU 2, con ogni esempi ingresso ricevente 5 in ogni passaggio. Ogni epoca si allenerà più velocemente man mano che aggiungi più GPU. In genere, si desidera aumentare le dimensioni del batch man mano che si aggiungono più acceleratori, in modo da utilizzare efficacemente la potenza di calcolo extra. Dovrai anche ricalibrare il tuo tasso di apprendimento, a seconda del modello. È possibile utilizzare strategy.num_replicas_in_sync per ottenere il numero di repliche.

# Compute a global batch size using a number of replicas.
BATCH_SIZE_PER_REPLICA = 5
global_batch_size = (BATCH_SIZE_PER_REPLICA *
                     mirrored_strategy.num_replicas_in_sync)
dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100)
dataset = dataset.batch(global_batch_size)

LEARNING_RATES_BY_BATCH_SIZE = {5: 0.1, 10: 0.15}
learning_rate = LEARNING_RATES_BY_BATCH_SIZE[global_batch_size]

Cosa è supportato ora?

API di formazione MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy ParameterServerStrategy CentralStorageStrategy
Keras Model.fit Supportato Supportato Supportato Supporto sperimentale Supporto sperimentale

Esempi e tutorial

Ecco un elenco di tutorial ed esempi che illustrano il sopra di integrazione end-to-end con Keras Model.fit :

  1. Tutorial : Allenamento con Model.fit e MirroredStrategy .
  2. Tutorial : Allenamento con Model.fit e MultiWorkerMirroredStrategy .
  3. Guida : contiene un esempio di utilizzo Model.fit e TPUStrategy .
  4. Tutorial : formazione Server Parametro con Model.fit e ParameterServerStrategy .
  5. Tutorial : Messa a punto BERT per molte attività dal benchmark colla con Model.fit e TPUStrategy .
  6. Tensorflow Modello Garden repository contenente collezioni di modelli state-of-the-art realizzate utilizzando varie strategie.

Usa tf.distribute.Strategy con loop di formazione personalizzati

Come dimostrato sopra, usando tf.distribute.Strategy con Keras Model.fit richiede la modifica solo un paio di righe di codice. Con un piccolo sforzo di più, è anche possibile utilizzare tf.distribute.Strategy con i cicli di formazione personalizzati .

Se hai bisogno di maggiore flessibilità e controllo sui tuoi cicli di allenamento rispetto a quanto è possibile con Estimator o Keras, puoi scrivere cicli di allenamento personalizzati. Ad esempio, quando si utilizza un GAN, è possibile eseguire un numero diverso di passaggi del generatore o del discriminatore per ogni round. Allo stesso modo, i framework di alto livello non sono molto adatti per la formazione di Reinforcement Learning.

I tf.distribute.Strategy classi forniscono un insieme di metodi per sostenere i cicli di formazione personalizzati. L'utilizzo di questi potrebbe richiedere inizialmente una ristrutturazione minore del codice, ma una volta fatto, dovresti essere in grado di passare da GPU, TPU e più macchine semplicemente cambiando l'istanza della strategia.

Di seguito è riportato un breve frammento che illustra questo caso d'uso per un semplice esempio di addestramento utilizzando lo stesso modello Keras di prima.

Innanzitutto, crea il modello e l'ottimizzatore all'interno dell'ambito della strategia. Ciò garantisce che tutte le variabili create con il modello e l'ottimizzatore siano variabili speculari.

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
  optimizer = tf.keras.optimizers.SGD()

Successivamente, creare il set di dati di ingresso e chiamare tf.distribute.Strategy.experimental_distribute_dataset per distribuire il set di dati in base alla strategia.

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(
    global_batch_size)
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)
2021-09-22 20:33:47.092428: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}

Quindi, definire una fase della formazione. Utilizzare tf.GradientTape ai gradienti di calcolo e ottimizzatore applicare tali pendenze per aggiornare le variabili del modello. Per distribuire questa fase di formazione, metterlo in una funzione train_step e passarlo a tf.distrbute.Strategy.run insieme con gli ingressi del set di dati avete ottenuto dal dist_dataset creata prima:

loss_object = tf.keras.losses.BinaryCrossentropy(
  from_logits=True,
  reduction=tf.keras.losses.Reduction.NONE)

def compute_loss(labels, predictions):
  per_example_loss = loss_object(labels, predictions)
  return tf.nn.compute_average_loss(per_example_loss, global_batch_size=global_batch_size)

def train_step(inputs):
  features, labels = inputs

  with tf.GradientTape() as tape:
    predictions = model(features, training=True)
    loss = compute_loss(labels, predictions)

  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  return loss

@tf.function
def distributed_train_step(dist_inputs):
  per_replica_losses = mirrored_strategy.run(train_step, args=(dist_inputs,))
  return mirrored_strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,
                         axis=None)

Alcune altre cose da notare nel codice sopra:

  1. Si è utilizzato tf.nn.compute_average_loss per calcolare la perdita. tf.nn.compute_average_loss riassume la perdita per esempio e divide la somma per il global_batch_size. Questo è importante perché più tardi, dopo i gradienti vengono calcolati in ogni replica, sono aggregati di tutti i repliche sommarli.
  2. È stato utilizzato anche il tf.distribute.Strategy.reduce API per aggregare i risultati restituiti da tf.distribute.Strategy.run . tf.distribute.Strategy.run restituisce i risultati da ogni replica locale nella strategia, e ci sono diversi modi per consumare questo risultato. È possibile reduce loro di ottenere un valore aggregato. È anche possibile fare tf.distribute.Strategy.experimental_local_results per ottenere l'elenco dei valori contenuti nel risultato, uno per ogni replica locale.
  3. Quando si chiama apply_gradients all'interno di un ambito strategia di distribuzione, il suo comportamento è stato modificato. In particolare, prima di applicare i gradienti su ogni istanza parallela durante l'addestramento sincrono, esegue una somma su tutte le repliche dei gradienti.

Infine, una volta che avete definito il passaggio di formazione, è possibile iterare dist_dataset ed eseguire il training in un ciclo:

for dist_inputs in dist_dataset:
  print(distributed_train_step(dist_inputs))
tf.Tensor(0.29786447, shape=(), dtype=float32)
tf.Tensor(0.29653987, shape=(), dtype=float32)
tf.Tensor(0.29522538, shape=(), dtype=float32)
tf.Tensor(0.29392087, shape=(), dtype=float32)
tf.Tensor(0.29262626, shape=(), dtype=float32)
tf.Tensor(0.29134142, shape=(), dtype=float32)
tf.Tensor(0.29006627, shape=(), dtype=float32)
tf.Tensor(0.28880078, shape=(), dtype=float32)
tf.Tensor(0.2875447, shape=(), dtype=float32)
tf.Tensor(0.28629807, shape=(), dtype=float32)
tf.Tensor(0.28506076, shape=(), dtype=float32)
tf.Tensor(0.2838327, shape=(), dtype=float32)
tf.Tensor(0.28261372, shape=(), dtype=float32)
tf.Tensor(0.28140378, shape=(), dtype=float32)
tf.Tensor(0.28020284, shape=(), dtype=float32)
tf.Tensor(0.27901068, shape=(), dtype=float32)
tf.Tensor(0.27782732, shape=(), dtype=float32)
tf.Tensor(0.27665266, shape=(), dtype=float32)
tf.Tensor(0.2754866, shape=(), dtype=float32)
tf.Tensor(0.274329, shape=(), dtype=float32)

Nell'esempio di cui sopra, si iterata sul dist_dataset di fornire un contributo alla vostra formazione. Si sono anche forniti con il tf.distribute.Strategy.make_experimental_numpy_dataset per supportare ingressi numpy. È possibile utilizzare questa API per creare un set di dati prima di chiamare tf.distribute.Strategy.experimental_distribute_dataset .

Un altro modo per eseguire l'iterazione sui dati consiste nell'utilizzare in modo esplicito gli iteratori. Potrebbe essere necessario eseguire questa operazione quando si desidera eseguire un determinato numero di passaggi anziché eseguire l'iterazione sull'intero set di dati. Quanto sopra iterazione sarebbe ora essere modificato per creare un iteratore prima e poi esplicitamente chiamare next su di esso per ottenere i dati di input.

iterator = iter(dist_dataset)
for _ in range(10):
  print(distributed_train_step(next(iterator)))
tf.Tensor(0.2731799, shape=(), dtype=float32)
tf.Tensor(0.27203918, shape=(), dtype=float32)
tf.Tensor(0.27090666, shape=(), dtype=float32)
tf.Tensor(0.26978233, shape=(), dtype=float32)
tf.Tensor(0.26866615, shape=(), dtype=float32)
tf.Tensor(0.26755798, shape=(), dtype=float32)
tf.Tensor(0.2664578, shape=(), dtype=float32)
tf.Tensor(0.26536545, shape=(), dtype=float32)
tf.Tensor(0.2642809, shape=(), dtype=float32)
tf.Tensor(0.26320407, shape=(), dtype=float32)

Questo copre il caso più semplice di usare tf.distribute.Strategy API per distribuire i cicli di formazione personalizzati.

Cosa è supportato ora?

API di formazione MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy ParameterServerStrategy CentralStorageStrategy
Ciclo di allenamento personalizzato Supportato Supportato Supportato Supporto sperimentale Supporto sperimentale

Esempi e tutorial

Di seguito sono riportati alcuni esempi di utilizzo delle strategie di distribuzione con cicli di addestramento personalizzati:

  1. Tutorial : Allenamento con un ciclo di formazione personalizzata e MirroredStrategy .
  2. Tutorial : Allenamento con un ciclo di formazione personalizzata e MultiWorkerMirroredStrategy .
  3. Guida : contiene un esempio di un ciclo di formazione personalizzato con TPUStrategy .
  4. Tutorial : formazione Server Parametro con un ciclo di formazione personalizzata e ParameterServerStrategy .
  5. Tensorflow Modello Garden repository contenente collezioni di modelli state-of-the-art realizzate utilizzando varie strategie.

Altri argomenti

Questa sezione tratta alcuni argomenti rilevanti per più casi d'uso.

Configurazione della variabile d'ambiente TF_CONFIG

Per la formazione multi-lavoratore, come accennato prima, è necessario impostare il 'TF_CONFIG' variabile d'ambiente per ogni esecuzione binario nel cluster. Il 'TF_CONFIG' variabile d'ambiente è una stringa JSON che specifica quali attività costituiscono un cluster, i loro indirizzi e il ruolo di ogni attività nel cluster. Il tensorflow/ecosystem repo fornisce un modello kubernetes, che stabilisce 'TF_CONFIG' per le attività di formazione.

Ci sono due componenti di 'TF_CONFIG' : un cluster e un compito.

  • Un cluster fornisce informazioni sul cluster di formazione, che è un dict costituito da diversi tipi di lavori come i lavoratori. Nella formazione multi-lavoratore, di solito c'è un lavoratore che si assume un po' più di responsabilità come salvare il checkpoint e scrivere un file di riepilogo per TensorBoard oltre a ciò che fa un normale lavoratore. Tale lavoratore è indicato come il lavoratore "capo", ed è consuetudine che il lavoratore con indice 0 è nominato come il capo operaio (in realtà questo è il modo tf.distribute.Strategy è implementato).
  • Un'attività invece fornisce informazioni sull'attività corrente. Il primo cluster di componenti è lo stesso per tutti i lavoratori e l'attività del secondo componente è diversa per ogni lavoratore e specifica il tipo e l'indice di quel lavoratore.

Un esempio di 'TF_CONFIG' è:

os.environ["TF_CONFIG"] = json.dumps({
    "cluster": {
        "worker": ["host1:port", "host2:port", "host3:port"],
        "ps": ["host4:port", "host5:port"]
    },
   "task": {"type": "worker", "index": 1}
})

Questo 'TF_CONFIG' specifica che ci sono tre operai e due "ps" compiti nel "cluster" insieme con i loro ospiti e le porte. Il "task" parte specifica il ruolo del compito attuale nel "cluster" -worker 1 (il secondo operatore). Ruoli valide in un cluster sono "chief" , "worker" , "ps" e "evaluator" . Non ci dovrebbero essere "ps" lavoro tranne quando si utilizza tf.distribute.experimental.ParameterServerStrategy .

Qual è il prossimo?

tf.distribute.Strategy è attivamente in fase di sviluppo. Provalo e fornire i vostri commenti utilizzando problemi GitHub .