Questo articolo è stato scritto da Rakshith Vasudev e John Lockman - HPC AI Innovation Lab, nell'ottobre 2019
Come introdotto in precedenza,CheXNet è un modello di assistente radilogo di intelligenza artificiale che utilizza DenseNet per identificare fino a 14 patologie da una determinata immagine di radiografia del toraco. Sono stati analizzati diversi approcci per scalare l'addestramento di un modello che potesse funzionare in modo ottimale o superiore rispetto al CheXNet-121 originale con ResNet-50 dimostrando la promessa sia in termini di scalabilità che di maggiore precisione dell'addestramento (AUROC positivo). Gli autori hanno dimostrato scalabilità sui sistemi cpu, tuttavia siamo interessati a sfruttare il parallelismo delle GPU per accelerare il processo di formazione. In questo articolo vengono descritte le best practice per ottenere massime prestazioni sulla formazione scale-out distribuita di CheXNet utilizzando le GPU NVIDIA V100 SXM2 nei server Dell EMC C4140. Dell EMC PowerEdge C4140 fornisce densità e prestazioni con quattro GPU NVIDIA V100 in configurazione SXM2.
Configurazione hardware: | Configurazione software: |
---|---|
|
|
Poiché i nuovi dispositivi di elaborazione (come GPU e TPU) consentono di addestrare le reti neurali a un ritmo sempre più veloce, l'elaborazione della CPU è incline a diventare il collo di bottiglia. L'API tf.data fornisce agli utenti elementi di base per progettare pipeline di input che utilizzano in modo efficace la CPU, ottimizzando ogni fase del processo ETL.
Per eseguire una fase di formazione, è innanzitutto necessario estrarre e trasformare i dati di formazione, quindi inviarli a un modello in esecuzione su un acceleratore. Tuttavia, in un'implementazione sincrona NAVE, mentre la CPU sta preparando i dati, l'acceleratore è inattivo. Al contrario, mentre l'accelerator sta addestrando il modello, la CPU è inattiva. La fase di formazione è quindi la somma del tempo di pre-elaborazione della CPU e del tempo di formazione dell'acceleratore
La pipelining si sovrappone alla pre-elaborazione e all'esecuzione del modello di una fase di addestramento. Mentre l'acceleratore esegue il passaggio di formazione N, la CPU sta preparando i dati per il passaggio N+1. In questo modo si riduce il tempo di passaggio al massimo (anziché la somma) della formazione e il tempo necessario per estrarre e trasformare i dati.
Senza pipelining, la CPU e la GPU/TPU restano inattive per la maggior parte del tempo:
Fig. 1: L'esecuzione sequenziale lascia spesso la GPU inattiva
Con la pipelining, il tempo di inattività diminuisce in modo significativo:
Fig. 2: La pipelining si sovrappone all'utilizzo di CPU e GPU, ottimizzando l'utilizzo della GPU
L'API tf.data fornisce un meccanismo di pipelining del software tramite la trasformazione tf.data.Dataset.prefetch, che può essere utilizzata per disaccoppiare il tempo di produzione dei dati dal momento in cui vengono utilizzati. In particolare, la trasformazione utilizza un thread in background e un buffer interno per eseguire il pre-fetch degli elementi dal dataset di input prima del momento in cui vengono richiesti.
Ulteriori informazioni qui: https://www.tensorflow.org/guide/performance/datasets
Quando si seguono le linee guida fornite da tensorflow, è possibile ottenere una pipeline di dati simile a questa (approccio precedente):
https://github.com/dellemc-hpc-ai/code-examples/blob/master/cheXNet-snippets/old_approach.py
In questo approccio definito anche come il vecchio approccio, la pipeline di dati tf fa quanto segue (supponendo che il dataset del tondo x ray sia una sequenza di TFRecords):
Tuttavia, questo non è il codice più performante. Provoca stalli e frequenti utilizzo di GPU dello 0%. Fondamentalmente, non utilizza gli acceleratori in modo efficace.
Per configurare correttamente la pipeline di dati tf, seguiamo l'approccio adottato specificamente dai modelli ufficiali tensorflow,quello per ResNet. La differenza tra il vecchio approccio e il nuovo approccio è il modo in cui viene configurata la pipeline di dati prima di passare al modello.
Ecco come si presenta il nuovo approccio:
https://github.com/dellemc-hpc-ai/code-examples/blob/master/cheXNet-snippets/new_approach.py
L'approccio ufficiale dei modelli TensorFlow, definito anche nuovo approccio, è il seguente:
Ecco un confronto delle prestazioni di entrambi gli approcci vecchi e nuovi, utilizzando i modelli ufficiali TF.
Fig. 3: Con il nuovo approccio, ci si potrebbe aspettare un dimensionamento quasi lineare.
Come si può vedere, c'è un significativo calo delle prestazioni e non vi è alcun dimensionamento con il vecchio approccio. Le GPU riscontrano spesso un utilizzo ridotto o nullo, con conseguente riduzione delle prestazioni. Rendere il calcolo più efficiente su una GPU significa rendere il calcolo più efficiente su più GPU su più nodi, se la comunicazione viene gestita correttamente.
Poiché le CPU eseguono la pre-elaborazione in parallelo, il pre-fetch dei dati elaborati in-memory e le GPU che eseguono il pesante sollevamento della moltiplicazione di matrice con una comunicazione rapida sono un altro aspetto che rende questo nuovo approccio più interessante da scalare per i nodi multipli.
L'ambiente che esegue i job è importante quanto quello dei job, perché avere le librerie/i moduli giusti è importante in quanto influirà sulle prestazioni di formazione. Inoltre, disporre delle librerie CUDA più recenti può contribuire a migliorare le prestazioni.
Seguire questa esercitazione per eseguire l'installazione, se non si dispone di un ambiente di lavoro configurato.
MPI è una libreria di comunicazioni che aiuta horovod a distribuire i lavori. Sono state analizzate diverse opzioni di parametro di binding e mapping e i parametri migliori per C4140 sono stati mappati per socket. L'impostazione consigliata è la seguente:mpirun --map-by socket -np x python pyfile.py --pyoptions
Se sono presenti più processi che funzionano una gPU, potrebbero essere molto efficaci nel combattere per le risorse GPU, consumando memoria GPU e non inserendo in modo efficace più immagini per batch, quindi responsabili di rendere le prestazioni della GPU un hit. Tensorflow 1.13.1 è stato esplorato, ma sembra che all'epoca avesse un bug. È stato avviato più di un processo per GPU.
In breve: