Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Optymalizacja wykresów TensorFlow za pomocą Grapplera

Zobacz na TensorFlow.org Uruchom w Google Colab Wyświetl źródło na GitHub Pobierz notatnik

Przegląd

TensorFlow wykorzystuje do wykonywania obliczeń zarówno wykresy, jak i gwałtowne wykonania. tf.Graph zawiera zestaw obiektów tf.Operation (ops), które reprezentują jednostki obliczeniowe, oraz obiekty tf.Tensor które reprezentują jednostki danych przepływające między operacjami.

Grappler to domyślny system optymalizacji wykresów w środowisku wykonawczym TensorFlow. Grappler stosuje optymalizacje w trybie graficznym (w ramach funkcji tf.function ), aby poprawić wydajność obliczeń TensorFlow poprzez uproszczenia wykresów i inne optymalizacje wysokiego poziomu, takie jak wstawianie elementów funkcji, aby umożliwić optymalizacje międzyprocedurowe. Optymalizacja tf.Graph zmniejsza również szczytowe wykorzystanie pamięci urządzenia i poprawia wykorzystanie sprzętu poprzez optymalizację mapowania węzłów grafów na zasoby obliczeniowe.

Użyj tf.config.optimizer.set_experimental_options() dla dokładniejszej kontroli nad optymalizacjami tf.Graph .

Dostępne optymalizatory wykresów

Grappler przeprowadza optymalizacje wykresów za pomocą sterownika najwyższego poziomu o nazwie MetaOptimizer . Z TensorFlow dostępne są następujące optymalizatory wykresów:

  • Stały optymalizator składania - statycznie określa wartość tensorów, gdy jest to możliwe, poprzez zaginanie stałych węzłów na wykresie i materializuje wynik przy użyciu stałych.
  • Optymalizator arytmetyczny - upraszcza operacje arytmetyczne, eliminując typowe wyrażenia podrzędne i upraszczając instrukcje arytmetyczne.
  • Optymalizator układu - optymalizuje układy tensorów w celu wydajniejszego wykonywania operacji zależnych od formatu danych, takich jak konwertowanie.
  • Optymalizator remapowania - Ponownie mapuje podgrafy na bardziej wydajne implementacje, zastępując często występujące podgrafy zoptymalizowanymi, połączonymi jądrem monolitycznym.
  • Optymalizator pamięci - analizuje wykres w celu sprawdzenia szczytowego wykorzystania pamięci dla każdej operacji i wstawia operacje kopiowania pamięci CPU-GPU w celu wymiany pamięci GPU na CPU w celu zmniejszenia szczytowego wykorzystania pamięci.
  • Optymalizator zależności - usuwa lub przestawia zależności sterujące, aby skrócić ścieżkę krytyczną dla kroku modelu lub włączyć inne optymalizacje. Usuwa również węzły, które faktycznie nie działają, takie jak tożsamość.
  • Optymalizator przycinania - węzły śliwek, które nie mają wpływu na dane wyjściowe z wykresu. Zwykle jest uruchamiany jako pierwszy, aby zmniejszyć rozmiar wykresu i przyspieszyć przetwarzanie w innych przebiegach Grapplera.
  • Optymalizator funkcji - optymalizuje bibliotekę funkcji programu TensorFlow i wstawia elementy funkcji w celu umożliwienia innych optymalizacji międzyprocedurowych.
  • Optymalizator kształtu - optymalizuje podgrafy działające na informacjach związanych z kształtem i kształtem.
  • Optymalizator Autoparallel - automatycznie równolegle wykresy poprzez podział wzdłuż wymiaru wsadu. Ten optymalizator jest domyślnie wyłączony.
  • Optymalizator pętli - optymalizuje przepływ sterowania wykresem przez wyprowadzanie niezmiennych w pętli podgrafów z pętli i usuwanie nadmiarowych operacji stosu w pętlach. Optymalizuje również pętle ze znanymi statycznie liczbami podróży i usuwa statycznie znane martwe gałęzie w warunkach warunkowych.
  • Optymalizator alokatorów o określonym zakresie - wprowadza alokatory o określonym zakresie w celu ograniczenia przenoszenia danych i konsolidacji niektórych operacji.
  • Optymalizator przypinania do hosta - zamienia małe operacje na procesor. Ten optymalizator jest domyślnie wyłączony.
  • Automatyczny optymalizator precyzji mieszanej - w stosownych przypadkach konwertuje typy danych na zmiennoprzecinkowe 16, aby poprawić wydajność. Obecnie dotyczy tylko GPU.
  • Narzędzie do usuwania debugowania - tf.print z wykresu węzły związane z operacjami debugowania, takie jak tf.debugging.Assert , tf.debugging.check_numerics i tf.print . Ten optymalizator jest domyślnie wyłączony.

Ustawiać

 import numpy as np
import timeit
import traceback
import contextlib


import tensorflow as tf
 

Utwórz menedżera kontekstu, aby łatwo przełączać stany optymalizatora.

 @contextlib.contextmanager
def options(options):
  old_opts = tf.config.optimizer.get_experimental_options()
  tf.config.optimizer.set_experimental_options(options)
  try:
    yield
  finally:
    tf.config.optimizer.set_experimental_options(old_opts)
 

Porównaj wydajność wykonania z grapplerem i bez niego

Domyślnie TensorFlow 2 i kolejne wersje są wykonywane chętnie . Użyj tf.function aby przełączyć domyślne wykonanie na tryb wykresu. Grappler działa automatycznie w tle, aby zastosować powyższe optymalizacje wykresu i poprawić wydajność wykonywania.

Stały optymalizator składania

Jako wstępny przykład rozważmy funkcję, która wykonuje operacje na stałych i zwraca wynik.

 def test_function_1():
  @tf.function
  def simple_function(input_arg):
    print('Tracing!')
    a = tf.constant(np.random.randn(2000,2000), dtype = tf.float32)
    c = a
    for n in range(50):
      c = c@a
    return tf.reduce_mean(c+input_arg)

  return simple_function
 

Wyłącz stały optymalizator składania i wykonaj funkcję:

 with options({'constant_folding': False}):
  print(tf.config.optimizer.get_experimental_options())
  simple_function = test_function_1()
  # Trace once
  x = tf.constant(2.2)
  simple_function(x)
  print("Vanilla execution:", timeit.timeit(lambda: simple_function(x), number = 1), "s")
 
{'constant_folding': False, 'disable_model_pruning': False, 'disable_meta_optimizer': False}
Tracing!
Vanilla execution: 0.004905937999865273 s

Włącz stały optymalizator składania i wykonaj ponownie funkcję, aby obserwować przyspieszenie wykonywania funkcji.

 with options({'constant_folding': True}):
  print(tf.config.optimizer.get_experimental_options())
  simple_function = test_function_1()
  # Trace once
  x = tf.constant(2.2)
  simple_function(x)
  print("Constant folded execution:", timeit.timeit(lambda: simple_function(x), number = 1), "s")
 
{'constant_folding': True, 'disable_model_pruning': False, 'disable_meta_optimizer': False}
Tracing!
Constant folded execution: 0.0005699149999145448 s

Optymalizator usuwania debugowania

Rozważmy prostą funkcję, która sprawdza wartość liczbową swojego argumentu wejściowego i zwraca ją.

 def test_function_2():
  @tf.function
  def simple_func(input_arg):
    output = input_arg
    tf.debugging.check_numerics(output, "Bad!")
    return output
  return simple_func
 

Najpierw wykonaj funkcję z wyłączonym optymalizatorem usuwania debugowania.

 test_func = test_function_2()
p1 = tf.constant(float('inf'))
try:
  test_func(p1)
except tf.errors.InvalidArgumentError as e:
  traceback.print_exc(limit=2)
 
Traceback (most recent call last):
  File "<ipython-input-8-1ac473fdfbab>", line 4, in <module>
    test_func(p1)
  File "/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 580, in __call__
    result = self._call(*args, **kwds)
tensorflow.python.framework.errors_impl.InvalidArgumentError: 2 root error(s) found.
  (0) Invalid argument:  Bad! : Tensor had Inf values
     [[node CheckNumerics (defined at <ipython-input-7-cbee1561c83e>:5) ]]
     [[Identity/_4]]
  (1) Invalid argument:  Bad! : Tensor had Inf values
     [[node CheckNumerics (defined at <ipython-input-7-cbee1561c83e>:5) ]]
0 successful operations.
0 derived errors ignored. [Op:__inference_simple_func_131]

Errors may have originated from an input operation.
Input Source operations connected to node CheckNumerics:
 input_arg (defined at <ipython-input-8-1ac473fdfbab>:4)

Input Source operations connected to node CheckNumerics:
 input_arg (defined at <ipython-input-8-1ac473fdfbab>:4)

Function call stack:
simple_func -> simple_func


tf.debugging.check_numerics błąd nieprawidłowego argumentu z powodu argumentu Inf test_func .

Włącz optymalizator usuwania debugowania i ponownie wykonaj funkcję.

 with options({'debug_stripper': True}):
  test_func2 = test_function_2()
  p1 = tf.constant(float('inf'))
  try:
    test_func2(p1)
  except tf.errors.InvalidArgumentError as e:
    traceback.print_exc(limit=2)
 

Optymalizator usuwania debugowania usuwa węzeł tf.debug.check_numerics z wykresu i wykonuje funkcję bez zgłaszania żadnych błędów.

Podsumowanie

Środowisko wykonawcze TensorFlow używa Grapplera do automatycznej optymalizacji wykresów przed wykonaniem. Użyj tf.config.optimizer.set_experimental_options aby włączyć lub wyłączyć różne optymalizatory wykresów.

Aby uzyskać więcej informacji na temat Grapplera, zobacz Optymalizacje wykresów TensorFlow .