2015-12-15 10 views

risposta

18

Non c'è ancora un modo per farlo nella versione pubblica. Siamo consapevoli che è una caratteristica importante e ci stiamo lavorando.

+7

È possibile che vi sia un aggiornamento per questa risposta? Perché https://github.com/tensorflow/tensorflow/issues/899 sembra come se si potesse probabilmente calcolare i FLOP per le singole operazioni che potrebbero fornire informazioni sul tempo di esecuzione. –

65

Ho usato il Timeline object per ottenere il tempo di esecuzione per ogni nodo del grafo:

  • si utilizza un classico sess.run() ma anche specificare gli argomenti opzionali options e run_metadata
  • si quindi si crea un Timeline oggetto con i dati run_metadata.step_stats

Lui Re è un esempio di programma che misura le prestazioni di una moltiplicazione di matrici:

import tensorflow as tf 
from tensorflow.python.client import timeline 

x = tf.random_normal([1000, 1000]) 
y = tf.random_normal([1000, 1000]) 
res = tf.matmul(x, y) 

# Run the graph with full trace option 
with tf.Session() as sess: 
    run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE) 
    run_metadata = tf.RunMetadata() 
    sess.run(res, options=run_options, run_metadata=run_metadata) 

    # Create the Timeline object, and write it to a json 
    tl = timeline.Timeline(run_metadata.step_stats) 
    ctf = tl.generate_chrome_trace_format() 
    with open('timeline.json', 'w') as f: 
     f.write(ctf) 

È quindi possibile aprire Google Chrome, vai alla pagina chrome://tracing e caricare il file timeline.json. Si dovrebbe vedere qualcosa di simile:

timeline

+1

Ciao! Ho provato a creare una linea temporale per la mia formazione sulla rete, ma sfortunatamente facendolo come hai mostrato produce solo una linea temporale per l'ultima chiamata di session.run. C'è un modo per aggregare la timeline su tutte le sessioni? –

+1

Utilizzando TensorFlow 0.12.0-rc0, ho scoperto che dovevo assicurarmi che libcupti.so/libcupti.dylib si trovasse nel percorso della libreria in modo che funzionasse. Per me (su Mac), ho aggiunto '/ usr/local/cuda/extras/CUPTI/lib' a' DYLD_LIBRARY_PATH'. –

8

È possibile estrarre queste informazioni utilizzando runtime statistics. Avrete bisogno di fare qualcosa di simile (controllare l'esempio completo nel link di cui sopra):

run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE) 
run_metadata = tf.RunMetadata() 
sess.run(<values_you_want_to_execute>, options=run_options, run_metadata=run_metadata) 
your_writer.add_run_metadata(run_metadata, 'step%d' % i) 

meglio che solo la stampa che si può vedere in tensorboard:

Inoltre , facendo clic su un nodo verrà visualizzata la memoria totale esatta, il tempo di calcolo e le dimensioni di uscita del tensore.

[1]: https://www.tensorflow.org/get_started/graph_viz#

+1

Il link "statistiche di runtime" è errato; punta solo all'immagine mostrata. – SuperElectric

1

Per i commenti di grasso-LOBYTE sotto risposta Olivier Moindrot s', se si vuole raccogliere la linea temporale su tutte le sessioni, è possibile cambiare "open('timeline.json', 'w')" a "open('timeline.json', 'a')" .

2

Poiché questo è alto quando si cerca su google "Profilo di Tensorflow", si noti che il modo corrente (fine 2017, TensorFlow 1.4) di ottenere la linea temporale utilizza un ProfilerHook. Funziona con MonitoredSession in tf.Estimator dove tf.RunOptions non è disponibile.

estimator = tf.estimator.Estimator(model_fn=...) 
hook = tf.train.ProfilerHook(save_steps=10, output_dir='.') 
estimator.train(input_fn=..., steps=..., hooks=[hook]) 
0

recentemente pubblicato da Uber SBNet libreria op personalizzato (http://www.github.com/uber/sbnet) ha un'implementazione di cuda_op_timer, che può essere utilizzato nel modo seguente:

with tf.control_dependencies([input1, input2]): 
    dt0 = sbnet_module.cuda_op_timer(timer_name="section_1", 
is_start=True) 
with tf.control_dependencies([dt0]): 
    input1 = tf.identity(input1) 
    input2 = tf.identity(input2) 

### portion of subgraph to time goes in here 

with tf.control_dependencies([result1, result2, dt0]): 
    cuda_time = sbnet_module.cuda_op_timer(timer_name="section_1", 
is_start=False) 
with tf.control_dependencies([cuda_time]): 
    result1 = tf.identity(result1) 
    result2 = tf.identity(result2) 

Si noti che qualsiasi parte del sottografo può essere asincrono voi dovrebbe essere molto attento a specificare tutte le dipendenze di input e output per le operazioni del timer. In caso contrario, il timer potrebbe essere inserito nel grafico fuori servizio e si può ottenere un tempo errato. Ho trovato sia la timeline che il time.time() timing di un'utilità molto limitata per la profilazione di grafici Tensorflow.

Detto questo personalmente raccomando di passare a PyTorch :) L'iterazione di sviluppo è più veloce, il codice scorre più veloce e tutto è molto meno doloroso.

Un altro approccio un po 'hacky e arcano per sottrarre l'overhead da tf.Session (che può essere enorme) è replicare il grafico N volte ed eseguirlo per una variabile N, risolvendo un'equazione di overhead fisso sconosciuto. Cioè misureresti attorno a session.run() con N1 = 10 e N2 = 20 e saprai che il tuo tempo è t e il sovraccarico è x. Quindi qualcosa come

N1*x+t = t1 
N2*x+t = t2 

Risolvere per xe t. Il rovescio della medaglia è che potrebbe richiedere molta memoria e non è necessariamente accurato :) Assicurati inoltre che i tuoi input siano completamente diversi/casuali/indipendenti altrimenti TF ripiegherà l'intero sottotitolo e non lo eseguirà N volte ... Divertiti con Tensorflow:)

Problemi correlati