Condividi tramite


HorovodRunner: Deep Learning distribuito con Horovod

Informazioni su come eseguire il training distribuito dei modelli di Machine Learning usando HorovodRunner per avviare processi di training Horovod come processi Spark in Azure Databricks.

Che cos'è HorovodRunner?

HorovodRunner è un'API generale per eseguire carichi di lavoro di Deep Learning distribuiti in Azure Databricks usando il framework Horovod . Integrando Horovod con la modalità barriera di Spark, Azure Databricks è in grado di garantire una maggiore stabilità per i processi di training di Deep Learning a esecuzione prolungata in Spark. HorovodRunner accetta un metodo Python che contiene codice di training di Deep Learning con hook Horovod. HorovodRunner seleziona il metodo sul driver e lo distribuisce ai ruoli di lavoro Spark. Un processo MPI Horovod viene incorporato come processo Spark usando la modalità di esecuzione della barriera. Il primo executor raccoglie gli indirizzi IP di tutti gli executor di attività usando BarrierTaskContext e attiva un processo Horovod usando mpirun. Ogni processo MPI python carica il programma utente selezionato, lo deserializza ed esegue il programma.

HorovodRunner

Training distribuito con HorovodRunner

HorovodRunner consente di avviare processi di training Horovod come processi Spark. L'API HorovodRunner supporta i metodi illustrati nella tabella. Per informazioni dettagliate, vedere la documentazione dell'API HorovodRunner.

Metodo e firma Descrizione
init(self, np) Creare un'istanza di HorovodRunner.
run(self, main, **kwargs) Eseguire un processo di training Horovod richiamando main(**kwargs). La funzione principale e gli argomenti della parola chiave vengono serializzati usando cloudpickle e distribuiti ai ruoli di lavoro del cluster.

L'approccio generale allo sviluppo di un programma di training distribuito con HorovodRunner è:

  1. Creare un'istanza HorovodRunner inizializzata con il numero di nodi.
  2. Definire un metodo di training Horovod in base ai metodi descritti in Uso horovod, assicurandosi di aggiungere eventuali istruzioni import all'interno del metodo .
  3. Passare il metodo di training all'istanza HorovodRunner di .

Ad esempio:

hr = HorovodRunner(np=2)

def train():
  import tensorflow as tf
  hvd.init()

hr.run(train)

Per eseguire HorovodRunner sul driver solo con n sottoprocessi, usare hr = HorovodRunner(np=-n). Ad esempio, se nel nodo driver sono presenti 4 GPU, è possibile scegliere n fino a 4. Per informazioni dettagliate sul parametro np, vedere la documentazione dell'API HorovodRunner. Per informazioni dettagliate su come aggiungere una GPU per ogni sottoprocesso, vedere la guida all'utilizzo di Horovod.

Un errore comune è che gli oggetti TensorFlow non possono essere trovati o prelevati. Ciò si verifica quando le istruzioni di importazione della libreria non vengono distribuite ad altri executor. Per evitare questo problema, includere tutte le istruzioni import ,ad esempio , import tensorflow as tfsia all'inizio del metodo di training Horovod che all'interno di qualsiasi altra funzione definita dall'utente chiamata nel metodo di training Horovod.

Registrare il training di Horovod con Horovod Timeline

Horovod ha la possibilità di registrare la sequenza temporale della sua attività, chiamata Horovod Timeline.

Importante

Horovod Timeline ha un impatto significativo sulle prestazioni. La velocità effettiva di Inception3 può diminuire di circa il 40% quando la sequenza temporale horovod è abilitata. Per velocizzare i processi HorovodRunner, non usare Horovod Timeline.

Non è possibile visualizzare la sequenza temporale horovod mentre il training è in corso.

Per registrare una sequenza temporale horovod, impostare la HOROVOD_TIMELINE variabile di ambiente sul percorso in cui si desidera salvare il file della sequenza temporale. Databricks consiglia di usare un percorso nell'archiviazione condivisa in modo che il file della sequenza temporale possa essere facilmente recuperato. Ad esempio, è possibile usare le API del file locale DBFS, come illustrato di seguito:

timeline_dir = "/dbfs/ml/horovod-timeline/%s" % uuid.uuid4()
os.makedirs(timeline_dir)
os.environ['HOROVOD_TIMELINE'] = timeline_dir + "/horovod_timeline.json"
hr = HorovodRunner(np=4)
hr.run(run_training_horovod, params=params)

Aggiungere quindi codice specifico della sequenza temporale all'inizio e alla fine della funzione di training. Il notebook di esempio seguente include codice di esempio che è possibile usare come soluzione alternativa per visualizzare lo stato di avanzamento del training.

Notebook di esempio di sequenza temporale horovod

Ottenere il notebook

Per scaricare il file della sequenza temporale, usare l'interfaccia della riga di comando di Databricks e quindi usare la funzionalità del chrome://tracing browser Chrome per visualizzarla. Ad esempio:

Sequenza temporale horovod

Flusso di lavoro per lo sviluppo

Questi sono i passaggi generali della migrazione del codice di Deep Learning a nodo singolo al training distribuito. Gli esempi: Eseguire la migrazione all'apprendimento avanzato distribuito con HorovodRunner in questa sezione illustrano questi passaggi.

  1. Preparare il codice a nodo singolo: preparare e testare il codice a nodo singolo con TensorFlow, Keras o PyTorch.
  2. Eseguire la migrazione a Horovod: seguire le istruzioni dall'utilizzodi Horovod per eseguire la migrazione del codice con Horovod e testarlo sul driver:
    1. Aggiungere hvd.init() per inizializzare Horovod.
    2. Aggiungere una GPU del server da usare da questo processo usando config.gpu_options.visible_device_list. Con la configurazione tipica di una GPU per processo, questa impostazione può essere impostata sulla classificazione locale. In tal caso, il primo processo nel server verrà allocato alla prima GPU, il secondo processo verrà allocato alla seconda GPU e così via.
    3. Includere una partizione del set di dati. Questo operatore del set di dati è molto utile quando si esegue il training distribuito, in quanto consente a ogni ruolo di lavoro di leggere un subset univoco.
    4. Ridimensionare la frequenza di apprendimento in base al numero di ruoli di lavoro. Le dimensioni effettive del batch nel training distribuito sincrono vengono ridimensionate in base al numero di ruoli di lavoro. L'aumento della velocità di apprendimento consente di compensare l'aumento delle dimensioni del batch.
    5. Eseguire il wrapping dell'utilità di ottimizzazione in hvd.DistributedOptimizer. L'ottimizzatore distribuito delega il calcolo delle sfumature all'ottimizzatore originale, calcola le sfumature medie usando allreduce o allgather e quindi applica le sfumature medie.
    6. Aggiungere hvd.BroadcastGlobalVariablesHook(0) per trasmettere gli stati iniziali delle variabili dal rango 0 a tutti gli altri processi. Ciò è necessario per garantire un'inizializzazione coerente di tutti i lavoratori quando il training viene avviato con pesi casuali o ripristinato da un checkpoint. In alternativa, se non si usa MonitoredTrainingSession, è possibile eseguire l'operazione dopo l'inizializzazione hvd.broadcast_global_variables delle variabili globali.
    7. Modificare il codice per salvare i checkpoint solo sul ruolo di lavoro 0 per impedire ad altri ruoli di lavoro di danneggiarli.
  3. Eseguire la migrazione a HorovodRunner: HorovodRunner esegue il processo di training Horovod richiamando una funzione Python. È necessario eseguire il wrapping della procedura di training principale in una singola funzione Python. È quindi possibile testare HorovodRunner in modalità locale e distribuita.

Aggiornare le librerie di Deep Learning

Nota

Questo articolo contiene riferimenti al termine slave, un termine che Azure Databricks non usa. Quando il termine verrà rimosso dal software, verrà rimosso anche dall'articolo.

Se si esegue l'aggiornamento o il downgrade di TensorFlow, Keras o PyTorch, è necessario reinstallare Horovod in modo che venga compilato nella libreria appena installata. Ad esempio, se si vuole aggiornare TensorFlow, Databricks consiglia di usare lo script init dalle istruzioni di installazione di TensorFlow e aggiungere il codice di installazione horovod specifico di TensorFlow seguente alla fine di esso. Vedere Le istruzioni di installazione di Horovod per usare combinazioni diverse, ad esempio l'aggiornamento o il downgrade di PyTorch e altre librerie.

add-apt-repository -y ppa:ubuntu-toolchain-r/test
apt update
# Using the same compiler that TensorFlow was built to compile Horovod
apt install g++-7 -y
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60 --slave /usr/bin/g++ g++ /usr/bin/g++-7

HOROVOD_GPU_ALLREDUCE=NCCL HOROVOD_CUDA_HOME=/usr/local/cuda pip install horovod==0.18.1 --force-reinstall --no-deps --no-cache-dir

Esempi: Eseguire la migrazione all'apprendimento avanzato distribuito con HorovodRunner

Gli esempi seguenti, basati sul set di dati MNIST , illustrano come eseguire la migrazione di un programma di Deep Learning a nodo singolo all'apprendimento avanzato distribuito con HorovodRunner.

Limiti

  • Quando si usano i file dell'area di lavoro, HorovodRunner non funzionerà se np è impostato su maggiore di 1 e il notebook importa da altri file relativi. Prendere in considerazione l'uso di horovod.spark invece di HorovodRunner.