2016-03-16 19 views
10

Mi chiedevo se qualcuno potesse fornire consigli su come ottenere prestazioni di picco da tensorflow in un'impostazione a 4 GPU.Massimizzare le prestazioni della multi gpu di tensorflow

Come test ho creato due della stessa rete (rete residua a 18 strati con piccoli banchi di filtri (compresi tra 16 e 128) su ingressi 32x32. Dimensione lotto 512, 128 per GPU.). Uno in MXNet e uno che ho modellato su the inception example.

La mia rete MXNet può allenarsi a circa 7k esempi al secondo in cui tensorflow è capace solo di 4,2k con dati dummy e 3,7 con dati reali.

(durante il funzionamento a 1 GPU numeri sono 1.2K esempi al secondo vs 2.1K)

Nel mio esperimento ho alcune domande nella speranza di accelerare le cose.

  1. L'utilizzo della GPU sembra piuttosto basso durante l'allenamento. Ho notato che nel white paper di tensorflow c'è il supporto per l'esecuzione di più stream sulla stessa GPU. Questo è possibile nella versione pubblica?

  2. Esiste comunque la possibilità di eseguire più operazioni di treno in un'unica esecuzione di session.run()? O hai un'esecuzione asincrona? Ciò consentirebbe di eseguire gli aggiornamenti del peso contemporaneamente alla successiva inoltro batch dei lotti? Ho provato a utilizzare 2 thread (sia di sistema che con QueueRunners), ma questo ha provocato solo un rallentamento. MXNet è in grado di aumentare la velocità eseguendo aggiornamenti di peso sulla CPU in modo che le GPU possano essere utilizzate per il lotto successivo.

  3. Il nuovo periodo di esecuzione distribuito risolverà alcuni di questi problemi consentendomi di eseguire più di un worker su una singola macchina?

  4. C'è qualcos'altro che può essere fatto?

So che ci sono un certo numero di domande simili qui in caso di overflow dello stack, ma se la mia ricerca non riuscivo a trovare una soluzione ai miei problemi che non ho già provato.

Edit:

ho fatto un po 'di CUDA profiling per vedere cosa i kernel costosi erano. Secondo la mia corsa, il 21,4% del tempo viene speso all'interno:

void Eigen::internal::EigenMetaKernel_NonVectorizable<Eigen::TensorEvaluator 
<Eigen::TensorAssignOp<Eigen::TensorMap<Eigen::Tensor<float, int=4, int=1, long>, int=16>, 
Eigen::TensorPaddingOp<Eigen::array<std::pair<int, int>, 
unsigned long=4> const, Eigen::TensorMap<Eigen::Tensor<float const, 
int=4, int=1, long>, int=16> const > const > const, Eigen::GpuDevice>, long>(float, int=4) 

e il 20,0% del tempo sono stati spesi in

void Eigen::internal::EigenMetaKernel_NonVectorizable<Eigen::TensorEvaluator 
<Eigen::TensorAssignOp<Eigen::TensorMap<Eigen::Tensor<float, int=4, int=1, long>, int=16>, 
Eigen::TensorBroadcastingOp<Eigen::array<int, unsigned long=4> 
const, Eigen::TensorMap<Eigen::Tensor<float const, int=4, int=1, long>, 
int=16> const > const > const, Eigen::GpuDevice>, long>(float, int=4) 

Fuori della firma non sono esattamente sicuro di cosa questi stanno facendo . Hanno senso?

In aggiunta a ciò, l'analisi segnala una bassa concorrenza del kernel, 0%, come previsto. e basso calcolo di utilizzo del 34,9% (concesso questo include il tempo di avvio e un po 'di pitone in loop treno. Circa 32 secondi totali di 91. Questo viene fuori a circa il 50% di utilizzo all'interno tensorflow.)

Modifica 2:

Ho allegato una copia del ridotto source code.In generale, tuttavia, sono più preoccupato per la domanda 1-3 e non voglio prendere troppo tempo per i corpi.

Inoltre sono in esecuzione su tensorflow costruito da: f07234db2f7b316b08f7df25417245274b63342a

Edit 3:

aggiornata ai più recenti tensorflow (63409bd23facad471973b110df998782c0e19c06) stesso codice, il formato dei dati di default (NHWC) e che sembrava accelera molto. Su dati falsi 6.7k-6.8k (dipendenza dalla dipendenza termica credo?) Esempi un secondo 4gpu. 1gpu - 2.0k esempi al secondo. La performance dei dati reali è di circa 4.9k esempi al secondo per 4gpu. 1gpu - 1.7k esempi al secondo.

Edit 4:

Inoltre ho provato commutazione formati di dati BCHW. Ho effettuato la conversione modellata su Soumith's benchmarks. Le parti della convoluzione erano effettivamente più veloci, ma la norma di serie sembra incasinare tutto. Con un naive implementation (fissando l'asse e facendo pesi [1, C, 1,1] invece di [C,]) sono in grado di ottenere solo 1.2k esempi al secondo su 4 gpu (dati falsi). Dove come con una trasposizione prima e dopo la norma di lotto op sono in grado di ottenere esempi di 6.2k al secondo (dati falsi). Ancora più lento del data_format NHWC.

risposta

1

È difficile diagnosticare il problema di prestazioni del programma senza visualizzare il codice. È possibile per noi leggere il codice di prova in qualche modo?

TensorPadding che mostra in alto è un po 'strano. Mi aspetto che le chiamate di Cudnn siano in cima al profilo. Ad ogni modo, mostrandoci il codice di prova sarà utile.

+0

Ho allegato un succo della sorgente. Grazie per l'aiuto. È sicuro assumere che il secondo argomento template di 'TensorMap' è il kernel applicato? Come sai che è 'TensorPadding' e non' TensorAssign' per esempio? – luke

+1

Alcuni suggerimenti: 1) Prova il reclonamento da HEAD - ci sono stati diversi miglioramenti al padding in Eigen da marzo che dovrebbero aiutare con la velocità. 2) Le conversioni sono attualmente più veloci quando si utilizza il layout supportato da CuDNN: NCHW è attualmente il miglior layout del tensore. https://github.com/soumith/convnet-benchmarks/blob/master/tensorflow/benchmark_alexnet.py#L18 per un esempio di come è possibile specificare l'ordine di formato dei dati per le convoluzioni, il pool massimo, ecc. – vrv

+0

@vrv Recloning from HEAD si traduce in un significativo miglioramento delle prestazioni. Grazie! Per quanto riguarda data_format ho aggiornato il mio post originale. Sto osservando il rallentamento. (abbastanza sicuro è la riduzione su diverse dimensioni.) – luke

Problemi correlati