2017-01-05 3 views
0

Ich entwickle und profile ein neuronales Netzwerk in Tensorflow auf einer GTX 1070. Meine erste Implementierung erwies sich aufgrund einiger teurer FFT Ops als ziemlich ineffizient. Die obere Zeitleiste im entsprechenden Bild zeigt, dass ein Trainingsschritt etwa 115 ms dauert. Eine zweite (mathematisch äquivalente) Implementierung scheint viel weniger Zeit zu verbrauchen, ein Schritt dauert weniger als 10 ms.Tensorflow Profiling Timelines inkonsistent mit Wandzeit

timelines (Sorry, ich bin nicht Bilder posten noch erlaubt)

Überraschenderweise beiden Methoden ca. nehmen. die gleiche Zeit, wenn sie über in Python gemessen:

build model, get train_op... 
sess = tf.Session() 

import timeit 
t = timeit.default_timer() 
for i in range(100): 
    sess.run(train_op) 
dt = timeit.default_timer() - t 
print(dt) 

In beiden Fällen 100 Läufe nehmen ~ 17s> 100 * 115MS> 100 * 10ms, die mehr als ich ist, würde aus dem Python-Overhead zu erwarten. Das Netzwerk wird mit Warteschlangen gefüttert, aber die Ergebnisse sind die gleichen direkt numpy Arrays in den Graphen, so dass ich Schluss gezogen die Empyt-Warteschlangen kann nicht der Flaschenhals sein.

Die Fristen sind grundsätzlich mit dem Unterschied, aufgezeichnet, die ich messen zwei Läufe:

build model, get train_op... 
sess = tf.Session() 

def write_timeline(path): 
    from tensorflow.python.client import timeline 
    run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE) 
    run_metadata = tf.RunMetadata() 
    sess.run(train_op, 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(path, 'w') as f: 
     f.write(ctf) 

write_timeline('timeline_1st_run.json') 
write_timeline('timeline_2nd_run.json') 

Die ersten Läufe immer viel länger dauern als die entsprechenden folgenden Läufe wird tensorflow einige Optimierungen hier tun oder Speicher für die Zuteilung erstes Mal?

timelines_first_runs

Kann jemand diese inconistent Ergebnisse erklären? Warum dauert meine zweite Implementierung die gleiche Zeit, gemessen in Python, wenn die Zeitleiste der Profilerstellung zeigt, dass sie viel schneller laufen sollte?

Antwort

0

Der erste Lauf kann länger dauern, da der globale Speicherpool wächst, PTX-Kompilierung und Optimierungen.

Sie könnten einige der Optimierungen ausschalten als

sess = tf.Session(config=tf.ConfigProto(graph_options=tf.GraphOptions(optimizer_options=tf.OptimizerOptions(opt_level=tf.OptimizerOptions.L0))) 

PTX Compilation noch 1-2 Sekunden jedoch zu dem ersten Lauf hinzufügen können, folgt. Zu Profilierungszwecken enthalten die Benutzer normalerweise einen "Vorwärmlauf", um die gleiche Berechnung auszuführen, bevor sie profiliert wird.

Auch, wenn Ihr train_op ist so etwas wie assign oder assign_add, train_op laufen wird das Ergebnis wieder in Python holen. Python < -> TensorFlow-Speicherübertragungen werden nicht in der Zeitleiste wiedergegeben (grpc Übertragungen fehlen auch, Tracking issue). Für Profilierungszwecke können Sie das op ausführen und die Python-Übertragung wie folgt weglassen

sess.run(train_op.op) 
+0

Deaktivieren von Optimierungen tatsächlich beschleunigt den ersten Lauf ein wenig und macht das folgende läuft ein bisschen langsamer. Mein train_op wird von 'tf.train.Optimizer.minimize (loss)' erzeugt, was intern so etwas wie 'assign' macht. 'sess.run (train_op)' gibt 'None' zurück, habe ich Recht, dass dies die Python <-> TensorFlow Speicherübertragungen als Problem ausschließt? Der Aufruf von 'sess.run ([loss, train_op])' dauert etwas länger. Könnte es einen anderen Grund geben, warum die beiden Implementierungen die gleiche Wandzeit benötigen? – sejanDee

+0

Die Rückgabe von 'None' würde ausschließen, dass Python-Speicherübertragungen ein Problem darstellen.Ihre effiziente vs ineffiziente Implementierung scheint ähnliche Zeit auf der Zeitachse zu benötigen (500 vs 700 ms), wie viel Diskrepanz sehen Sie in der Wanduhrzeit nach dem Vorwärmen? –

+0

Die ersten Zeitlinien von oben sind eigentlich mit Vorwärmen (10ms vs 110ms). Vorgewärmte Wanduhrzeiten sind 160ms und 170ms, gemittelt über 1000 Läufe. – sejanDee