Optymalizacja wykresu TensorFlow za pomocą Grapplera

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

Przegląd

TensorFlow używa zarówno wykresów, jak i gorliwych wykonań do wykonywania obliczeń. tf.Graph zawiera zestaw obiektów tf.Operation (ops), które reprezentują jednostki obliczeń oraz obiekty tf.Tensor , które reprezentują jednostki danych przepływających między operacjami.

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

Użyj tf.config.optimizer.set_experimental_options() dla lepszej kontroli nad optymalizacjami tf.Graph .

Dostępne optymalizatory wykresów

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

  • Optymalizator stałego składania — w miarę możliwości statycznie określa wartość tensorów, składając stałe węzły na wykresie i materializuje wynik za pomocą stałych.
  • Optymalizator arytmetyczny — upraszcza operacje arytmetyczne poprzez eliminację typowych podwyrażeń i uproszczenie instrukcji arytmetycznych.
  • Optymalizator układu — optymalizuje układy tensorów w celu wydajniejszego wykonywania operacji zależnych od formatu danych, takich jak sploty.
  • Optymalizator remapowania — ponownie mapuje podgrafy na bardziej wydajne implementacje, zastępując często występujące podgrafy zoptymalizowanymi , scalonymi jądrami monolitycznymi.
  • Optymalizator pamięci — analizuje wykres w celu sprawdzenia szczytowego użycia 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 użycia pamięci.
  • Optymalizator zależności — usuwa lub zmienia kolejność zależności sterowania w celu skrócenia ścieżki krytycznej dla etapu modelu lub umożliwia inne optymalizacje. Usuwa również węzły, które skutecznie nie działają, takie jak Identity.
  • Optymalizator przycinania — przycina węzły, które nie mają wpływu na dane wyjściowe wykresu. Zwykle jest uruchamiany jako pierwszy, aby zmniejszyć rozmiar wykresu i przyspieszyć przetwarzanie w innych przejściach Grapplera.
  • Optymalizator funkcji — Optymalizuje bibliotekę funkcji programu TensorFlow i wstawia treść funkcji, aby umożliwić inne optymalizacje międzyproceduralne.
  • Optymalizator kształtu — optymalizuje podwykresy, które operują na informacjach związanych z kształtem i kształtem.
  • Optymalizator Autoparallel — Automatycznie zrównolegla wykresy, dzieląc je na wymiar wsadowy. Ten optymalizator jest domyślnie WYŁĄCZONY.
  • Optymalizator pętli — optymalizuje przepływ sterowania wykresem, wyciągając z pętli podgrafy niezmiennicze i usuwając nadmiarowe operacje na stosie w pętlach. Optymalizuje również pętle ze statystycznie znanymi licznikami podróży i usuwa statycznie znane martwe gałęzie w warunkach warunkowych.
  • Optymalizator alokatorów w zakresie — wprowadza alokatory z zakresami w celu ograniczenia przenoszenia danych i konsolidacji niektórych operacji.
  • Pin to host Optimizer — zamienia małe operacje na procesor. Ten optymalizator jest domyślnie WYŁĄCZONY.
  • Optymalizator automatycznej precyzji mieszanej — w stosownych przypadkach konwertuje typy danych na float16 w celu poprawy wydajności. Obecnie dotyczy tylko procesorów graficznych.
  • Debug stripper — usuwa z wykresu węzły związane z operacjami debugowania, takimi 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ść wykonywania z Grapplerem i bez niego

TensorFlow 2 i nowsze są domyślnie wykonywane chętnie . Użyj tf.function , aby przełączyć domyślne wykonanie w 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ż 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.0018392090000816097 s

Włącz optymalizator stałego składania i wykonaj funkcję ponownie, aby zaobserwować 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.0006749789999958011 s

Optymalizator usuwania debugowania

Rozważ 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)
2021-09-22 20:34:55.871238: E tensorflow/core/kernels/check_numerics_op.cc:292] abnormal_detected_host @0x7f4878e00100 = {0, 1} Bad!
Traceback (most recent call last):
  File "/tmp/ipykernel_22954/3616845043.py", line 4, in <module>
    test_func(p1)
  File "/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 885, in __call__
    result = self._call(*args, **kwds)
tensorflow.python.framework.errors_impl.InvalidArgumentError:  Bad! : Tensor had Inf values
     [[node CheckNumerics (defined at tmp/ipykernel_22954/2241890286.py:5) ]] [Op:__inference_simple_func_131]

Errors may have originated from an input operation.
Input Source operations connected to node CheckNumerics:
 input_arg (defined at tmp/ipykernel_22954/3616845043.py:4)

Function call stack:
simple_func

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

Włącz optymalizator usuwania błędów 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 debugowania strippera usuwa węzeł tf.debug.check_numerics z wykresu i wykonuje funkcję bez zgłaszania błędów.

Streszczenie

Ś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 .