2015-12-15 22 views

Odpowiedz

18

Nie ma jeszcze sposobu, aby to zrobić w publicznej wersji. Zdajemy sobie sprawę, że jest to ważna cecha i pracujemy nad nią.

+7

Czy jest możliwa aktualizacja tej odpowiedzi? Ponieważ https://github.com/tensorflow/tensorflow/issues/899 wydaje się, że prawdopodobnie można obliczyć FLOP dla poszczególnych operacji, które mogą dać wgląd w czas realizacji. –

65

Użyłem Timeline object aby uzyskać czas wykonania dla każdego węzła na wykresie:

  • użyć klasycznych sess.run() ale również określić opcjonalne argumenty options i run_metadata
  • ty następnie utworzyć Timeline obiekt z danymi run_metadata.step_stats

On re jest przykładowy program, który mierzy wydajność mnożenie macierzy:

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) 

Następnie można otworzyć Google Chrome, przejdź do strony chrome://tracing i załadować plik timeline.json. Powinieneś zobaczyć coś takiego:

timeline

+1

Cześć! Próbowałem utworzyć oś czasu dla mojego szkolenia sieciowego, ale niestety robienie tego, jak pokazałeś, powoduje utworzenie linii czasu dla ostatniego wywołania session.run. Czy istnieje sposób na agregację osi czasu we wszystkich sesjach? –

+1

Korzystając z TensorFlow 0.12.0-rc0, stwierdziłem, że muszę się upewnić, że libcupti.so/libcupti.dylib było na ścieżce biblioteki, aby to działało. Dla mnie (na Macu) dodałem '/ usr/local/cuda/extras/CUPTI/lib' do' DYLD_LIBRARY_PATH'. –

8

Można wyodrębnić te informacje za pomocą runtime statistics. Trzeba będzie zrobić coś takiego (sprawdź pełną przykład w wyżej wymienionych 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) 

lepiej niż tylko drukowanie go można zobaczyć go w tensorboard:

Dodatkowo kliknięcie węzła wyświetli dokładną całkowitą pamięć, czas obliczeń i rozmiary wyjściowe tensora.

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

+1

Łącze "statystyki wykonania" jest błędne; po prostu wskazuje na pokazany obraz. – SuperElectric

1

Dla komentarzach tłuszczu-lobyte poniżej odpowiedź Olivier Moindrot „s, jeśli chcesz zbierać oś czasu na wszystkie sesje, można zmienić "open('timeline.json', 'w')" na "open('timeline.json', 'a')" .

2

Ponieważ podczas wyszukiwania w "Profilowaniu Tensorflow" jest to bardzo wysokie, należy pamiętać, że aktualny (koniec 2017 r., TensorFlow 1.4) sposób uzyskania Osi czasu wykorzystuje numer ProfilerHook. Działa to z MonitoredSessions w tf.Estimator, gdzie tf.RunOptions nie są dostępne.

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

Niedawno wydany przez Uber SBNet bibliotece zwyczaj op (http://www.github.com/uber/sbnet) posiada implementację cuda_op_timer, które mogą być używane w następujący sposób:

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) 

Należy pamiętać, że jakakolwiek część podgrafu może być asynchroniczny ci powinien być bardzo ostrożny przy określaniu wszystkich zależności wejściowych i wyjściowych dla liczników czasu. W przeciwnym razie licznik może zostać wstawiony do wykresu w kolejności i można uzyskać błędny czas. Znalazłem zarówno timeline, jak i time.time(), bardzo ograniczone narzędzie do profilowania wykresów Tensorflow.

Powiedziawszy to, osobiście polecam przejście na PyTorch :) Iteracja rozwoju jest szybsza, kod działa szybciej i wszystko jest o wiele mniej bolesne.

Innym nieco hackowskim i tajemniczym podejściem do odejmowania narzutu od tf.Session (który może być ogromny) jest replikowanie wykresu N razy i uruchamianie go dla zmiennej N, rozwiązywanie równania nieznanego utrwalonego narzutu. To znaczy. mierzysz wokół session.run() z N1 = 10 i N2 = 20 i wiesz, że twój czas to t, a narzut to x. Tak więc coś takiego jak

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

Rozwiąż dla x i t. Minusem jest to, że może to wymagać dużo pamięci i niekoniecznie jest poprawne :) Upewnij się również, że twoje dane wejściowe są całkowicie różne/losowe/niezależne, inaczej TF złoży cały podgraph i nie uruchomi go N razy ... Baw się z Tensorflow:)

Powiązane problemy