it-swarm.com.de

Kann ich die Ausführungszeit einzelner Operationen mit TensorFlow messen?

Ich weiß, dass ich die Ausführungszeit eines Aufrufs an sess.run() messen kann, aber ist es möglich, eine feinere Granularität zu erhalten und die Ausführungszeit einzelner Operationen zu messen?

60
user3559888

Es gibt noch keine Möglichkeit, dies in der öffentlichen Veröffentlichung zu tun. Wir sind uns dessen bewusst, dass dies eine wichtige Funktion ist und wir arbeiten daran.

21
Ian Goodfellow

Ich habe das Objekt Timeline verwendet, um den Ausführungszeitpunkt für jeden Knoten im Diagramm zu erhalten:

  • sie verwenden eine klassische sess.run(), geben jedoch auch die optionalen Argumente options und run_metadata an.
  • sie erstellen dann ein Timeline-Objekt mit den run_metadata.step_stats-Daten

Hier ist ein Beispielprogramm, das die Leistung einer Matrixmultiplikation misst:

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)

Sie können dann Google Chrome öffnen, zur Seite chrome://tracing gehen und die timeline.json-Datei laden . Sie sollten etwa Folgendes sehen:

 timeline

91

Da dies beim Googeln nach "Tensorflow Profiling" hoch ist, beachten Sie, dass die aktuelle (Ende 2017, TensorFlow 1.4) Methode, die Timeline zu erhalten, einen ProfilerHook verwendet. Dies funktioniert mit den MonitoredSessions in tf.Estimator, wo tf.RunOptions nicht verfügbar sind.

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

Sie können diese Informationen mit Laufzeitstatistiken extrahieren. Sie müssen so etwas tun (überprüfen Sie das vollständige Beispiel in dem oben genannten Link):

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)

Besser als nur drucken, können Sie es in Tensorboard sehen:

Wenn Sie auf einen Knoten klicken, wird außerdem der genaue Gesamtspeicher angezeigt Rechenzeit und Tensorausgabegrößen.

 [Example from link

11
Salvador Dali

Um diese Antwort zu aktualisieren, verfügen wir über einige Funktionen zum CPU-Profiling, die auf Inferenz ausgerichtet sind. Wenn Sie unter https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/benchmark - nachschlagen, sehen Sie ein Programm, das Sie auf einem Modell ausführen können, um Zeitvorgaben für die einzelnen Operationen zu erhalten.

10
Pete Warden

Für die Kommentare von fat-lobyte under Olivier Moindrot können Sie, wenn Sie die Zeitleiste über alle Sitzungen erfassen möchten, "open('timeline.json', 'w')" in "open('timeline.json', 'a')" ändern. 

2
Cheney

Seit Tensorflow 1.8 gibt es ein wirklich gutes Beispiel für die Verwendung von tf.profile.Profilerhier .

2
nitred

Zum automatischen Profilieren von TensorFlow-Sitzungen können Sie den StackImpact-Profiler verwenden. Es ist nicht erforderlich, Sitzungen zu instrumentieren oder Optionen hinzuzufügen. Sie müssen lediglich den Profiler initialisieren:

import stackimpact

agent = stackimpact.start(
    agent_key = 'agent key here',
    app_name = 'MyApp')

Sowohl die Ausführungszeit als auch die Speicherprofile sind im Dashboard verfügbar.

Ausführliche Informationen in diesem Artikel: TensorFlow Profiling in Entwicklungs- und Produktionsumgebungen .

Haftungsausschluss: Ich arbeite für StackImpact.

0
logix

Vor kurzem von Uber SBNet Custom Op Library ( http://www.github.com/uber/sbnet ) veröffentlicht, verfügt es über eine Implementierung von cuda-ereignisbasierten Timern, die auf folgende Weise verwendet werden können:

with tf.control_dependencies([input1, input2]):
    dt0 = sbnet_module.cuda_timer_start()
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_timer_end(dt0)
with tf.control_dependencies([cuda_time]):
    result1 = tf.identity(result1)
    result2 = tf.identity(result2)

py_result1, py_result2, dt = session.run([result1, result2, cuda_time])
print "Milliseconds elapsed=", dt

Beachten Sie, dass jeder Teil des Untergraphen asynchron sein kann. Sie sollten sehr vorsichtig sein, wenn Sie alle Eingabe- und Ausgabeabhängigkeiten für die Zeitgeberoperationen angeben. Andernfalls kann es vorkommen, dass der Timer nicht in der richtigen Reihenfolge in den Graphen eingefügt wird. Ich fand sowohl die Timeline als auch das time.time () - Timing von sehr eingeschränktem Nutzen für das Profilieren von Tensorflow-Diagrammen. Beachten Sie auch, dass die cuda_timer-APIs mit dem Standardstream synchronisiert werden. Dies ist derzeit vorgesehen, da TF mehrere Streams verwendet.

Trotzdem empfehle ich persönlich, zu PyTorch zu wechseln :) Die Iteration in der Entwicklung ist schneller, der Code läuft schneller und alles ist weniger schmerzhaft.

Ein anderer etwas hackiger und geheimnisvoller Ansatz, um den Overhead von tf.Session abzuziehen (das kann enorm sein), besteht darin, den Graphen N-mal zu replizieren und für eine Variable N auszuführen, wobei nach einer Gleichung mit einem unbekannten festen Overhead gesucht wird. Das heißt Sie messen rund um session.run () mit N1 = 10 und N2 = 20 und wissen, dass Ihre Zeit t ist und der Overhead x ist. So etwas wie

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

Löse nach x und t. Ein Nachteil ist, dass dies möglicherweise viel Speicher erfordert und nicht unbedingt genau ist. :) Stellen Sie außerdem sicher, dass Ihre Eingaben völlig unterschiedlich/zufällig/unabhängig sind. Andernfalls faltet TF den gesamten Subgraph und führt ihn nicht N-mal aus. Viel Spaß mit TensorFlow: )

0