2016-03-03 34 views
8

Mi piacerebbe sapere cosa è considerato "best practice" per sistemi multi-GPU quando si allena reti con TensorFlow.TensorFlow: configurazione Multi-GPU (prestazioni)

ad esempio uno dei miei reti si presenta così:

      input 
          | 
         (...) <-- convolutional layers 
          | 
         _________ 
    fully-connected |  | fully-connected 
    output stream 1 -> |  | <- output stream 2 

Does tensorflow allocare in modo efficiente più GPU? O dovrei specificare me stesso quale GPU TensorFlow dovrebbe usare per un'operazione specifica?

Non l'ho ancora analizzato, ho appena iniziato alcuni esperimenti di GPU oggi. Tuttavia, al momento non ho non specificato il dispositivo da utilizzare sugli strati convoluzionali ma ho specificato che per gli strati completamente collegati:

# flattened information of the last convolutional layer 
h_pooln_flat = tf.reshape(...) 

with tf.device("/gpu:0"): 
    # stream 1 stuff 

with tf.device("/gpu:1"): 
    # stream 2 stuff 

È questo una buona idea? O dovrebbe lasciare l'allocazione delle risorse aperta a TensorFlow?

Immagino che un singolo "flusso" di strati convoluzionali non possa essere calcolato in parallelo ?! Quindi non importa quale dispositivo comporti la parte della convoluzione, della messa in comune, ... parte ?!

Qualche consiglio per ottenere le migliori prestazioni?

Attualmente mi sto allenando su un nodo di un cluster Slurm con 2 GPU ma potenzialmente potrei allenarmi su più nodi, quindi 4, 6 o addirittura 8 GPU. Tuttavia, immagino ci sarebbe un sovraccarico con più di 2 GPU?


EDIT (rallentare le prestazioni multi-GPU): Dopo alcuni test sono abbastanza stupito ... se lascio tensorflow decidere cosa assegnare e rimuovere le normative specifiche del dispositivo alla rete allena considerevolmente più veloce . Questo è stato davvero sorprendente per me ... cosa potrebbe essere più efficace di avere ogni flusso di output su una GPU quando ci sono due GPU in totale? Inoltre sembra (secondo l'output) che Tensorflow stia usando solo una GPU ?!


EDIT2 (valori NaN): Dopo qualche test ho sperimentato che la mia configurazione manuale di gpu:0 per il flusso 1 e gpu:1 per il flusso 2 non solo è più lento di lasciare tensorflow decidere cosa usare (e secondo l'output di script in pipe TensorFlow utilizza solo una GPU ma anche a volte il mio (non so perché) il mio "gpu:0 per lo streaming 1" e lo standard gpu:1 per lo streaming 2 "genera solo valori NaN. Come direttamente o poco dopo l'init. Molto strano.

TensorFlow necessita di qualche tipo di blocco del thread o copia manuale dei dati di input per più GPU?

+1

Non riesco a rispondere alla tua domanda, ma posso sottolineare che nella documentazione di Tensorflow, menzionano che l'allocazione dei processori (GPU e CPU) viene eseguita in un metodo avido dopo l'assegnazione dei vincoli di posizionamento definiti dall'utente. Ecco il white paper: http://download.tensorflow.org/paper/whitepaper2015.pdf. Vedere le sezioni 3.2 e 4.3. Sarò curioso di vedere qualsiasi risposta alle migliori pratiche pure. – nfmcclure

+0

Tutti i trasferimenti di dati sono fatti per te, e non è necessario bloccare i dati di input per prevenire i NaN. Ma puoi anche ottenere NaN se la tua ottimizzazione diverge –

+0

Sì, ma non ho mai avuto il problema NaN con la mia rete su una singola GPU. Intendo dire che in 5 su 5 esperimenti converge normalmente su una singola GPU ma in 3 su 5 multi GPU ho ottenuto i valori NaN. Inoltre: perché le GPU multiple dovrebbero essere più lente? Voglio dire a causa del trasferimento di dati tra le GPU non mi aspettavo il doppio della velocità, ma più lento? – daniel451

risposta

5

La logica per il posizionamento predefinito dei dispositivi sta nel simple_placer.cc

io possa mancare qualcosa nella logica, ma da this line sembra che metterà tutti i ops GPU su gpu: 0

Si può vedere dall'implementazione, la strategia di posizionamento non tiene conto del trasferimento dei dati o dei costi di calcolo, quindi il posizionamento manuale è spesso migliore di quello automatico. Ad esempio, se si sta eseguendo una sorta di pipeline di input, il posizionamento predefinito di solito posiziona alcune operazioni di elaborazione dati su GPU, il che rende le cose più lente in generale.

Per quanto la tua implementazione sia lenta ... forse la copia gpu0-> gpu1 sta succedendo da qualche parte?

L'utilizzo di configurazioni multi-GPU per il lavoro è molto aperto, facci sapere cosa trovi!