TensorFlow-Graphenoptimierung mit Grappler

Auf TensorFlow.org ansehen In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

Überblick

TensorFlow verwendet sowohl Graph- als auch Eager-Ausführungen, um Berechnungen auszuführen. A tf.Graph enthält einen Satz von tf.Operation Objekte (OPs) , die Einheiten der Berechnung und repräsentieren tf.Tensor Objekte , die die Dateneinheiten darstellen , die zwischen ops fließen.

Grappler ist das Standard-Graphenoptimierungssystem in der TensorFlow-Laufzeit. Grappler gilt Optimierungen im Graph - Modus (innerhalb tf.function ) die Leistung Ihrer TensorFlow Berechnungen durch Graph Vereinfachungen und andere High-Level - Optimierungen wie inlining Funktionsrümpfe zur Verbesserung der inter-Verfahrensoptimierungen zu ermöglichen. Die Optimierung der tf.Graph reduziert auch die Gerät maximale Speichernutzung und die Hardware - Auslastung verbessert , indem die Zuordnung von Graph - Knoten Rechenressourcen zu optimieren.

Verwenden tf.config.optimizer.set_experimental_options() für eine feinere Kontrolle über Ihre tf.Graph Optimierungen.

Verfügbare Grafikoptimierer

Grappler führt Graph Optimierungen durch eine Top-Level - Treiber der angerufene MetaOptimizer . Die folgenden Grafikoptimierer sind mit TensorFlow verfügbar:

  • Konstantenfaltung Optimierung - Statisch folgert den Wert von Tensoren , wenn möglich , durch ständigen Knoten in den Graphen Falten und materialisiert das Ergebnis Konstanten verwenden.
  • Arithmetic Optimierer - Vereinfacht die arithmetischen Operationen durch gemeinsamen Teilausdrücke zu beseitigen und arithmetische Aussagen zu vereinfachen.
  • Layout - Optimierer - Optimierung der Tensor - Layouts Datenformat abhängige Operationen auszuführen, wie Faltungen effizienter zu gestalten .
  • Remapper Optimierer - Ordnet Subgraphen auf effizientere Implementierungen mit optimierten fusionierten monolithischen Kernel häufig vorkommenden Subgraphen zu ersetzen.
  • Speicher - Optimierer - Analysiert die Kurve , die die maximale Speichernutzung für jeden Betrieb und Einsätze CPU-GPU - Speicher Kopiervorgänge für das Swap - GPU - Speicher an die CPU überprüfen Sie die maximale Speichernutzung zu reduzieren.
  • Dependency - Optimierer - Beseitigt oder reorganisiert steuern Abhängigkeiten den kritischen Pfad für ein Modell Schritt zu verkürzen oder ermöglicht andere Optimierungen. Entfernt auch Knoten, die effektiv No-Ops sind, wie z. B. Identity.
  • Pruning Optimierer - Prunes Knoten , die keine Auswirkung auf den Ausgang aus der Kurve haben. Es wird normalerweise zuerst ausgeführt, um die Größe des Graphen zu reduzieren und die Verarbeitung in anderen Grappler-Durchgängen zu beschleunigen.
  • Funktion Optimierer - Optimierung der Funktionsbibliothek eines TensorFlow Programm und inlines Körper funktionieren andere zwischenVerfahrensOptimierungen zu ermöglichen.
  • Form - Optimierer - Optimierung der Untergraphen , die auf Form arbeiten und dazugehörige Informationen prägen.
  • Autoparallel Optimierer - automatisch parallelisiert Graphen durch Spaltung entlang der Batch - Dimension. Dieser Optimierer ist standardmäßig deaktiviert.
  • Loop Optimierung - optimiert den Graph Steuerfluß durch schlaufen invariant Subgraphen aus Schlaufen und durch Entfernen redundanter Stapeloperationen in Schleifen Hissen. Optimiert auch Schleifen mit statisch bekannten Auslösezahlen und entfernt statisch bekannte tote Verzweigungen in Bedingungen.
  • Scoped allocator Optimierer - stellt scoped Verteilern Datenbewegung zu reduzieren und einige Operationen zu konsolidieren.
  • Pin zu Host - Optimierer - Swaps kleine Operationen auf die CPU. Dieser Optimierer ist standardmäßig deaktiviert.
  • Auto Misch Präzision Optimierer - Wandeln Datentypen float16 gegebenenfalls zu verbessern. Gilt derzeit nur für GPUs.
  • Debug Stripper - Strips Knoten im Zusammenhang mit Debug - Operationen wie tf.debugging.Assert , tf.debugging.check_numerics und tf.print aus dem Diagramm. Dieser Optimierer ist standardmäßig deaktiviert.

Aufstellen

import numpy as np
import timeit
import traceback
import contextlib


import tensorflow as tf

Erstellen Sie einen Kontextmanager, um den Optimiererstatus einfach umzuschalten.

@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)

Vergleichen Sie die Ausführungsleistung mit und ohne Grappler

TensorFlow 2 und darüber hinaus führt eine Spannung voreingestellt. Verwenden Sie tf.function die Standardausführung Graph - Modus zu wechseln. Grappler wird automatisch im Hintergrund ausgeführt, um die oben genannten Diagrammoptimierungen anzuwenden und die Ausführungsleistung zu verbessern.

Konstanter Faltoptimierer

Betrachten Sie als vorläufiges Beispiel eine Funktion, die Operationen mit Konstanten ausführt und eine Ausgabe zurückgibt.

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

Schalten Sie den Konstantfaltungsoptimierer aus und führen Sie die Funktion aus:

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.0018649740000000747 s

Aktivieren Sie den Konstantfaltungsoptimierer und führen Sie die Funktion erneut aus, um eine Beschleunigung der Funktionsausführung zu beobachten.

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.0004272599999808335 s

Debug-Stripper-Optimierer

Betrachten Sie eine einfache Funktion, die den numerischen Wert ihres Eingabearguments überprüft und zurückgibt.

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

Führen Sie zuerst die Funktion mit deaktiviertem Debug-Stripper-Optimierer aus.

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-08-28 01:24:41.080416: E tensorflow/core/kernels/check_numerics_op.cc:292] abnormal_detected_host @0x7fc850e00100 = {0, 1} Bad!
Traceback (most recent call last):
  File "/tmp/ipykernel_26762/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_26762/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_26762/3616845043.py:4)

Function call stack:
simple_func

tf.debugging.check_numerics wirft ein ungültiges Argument Fehler wegen der Inf Argument test_func .

Aktivieren Sie den Debug-Stripper-Optimierer und führen Sie die Funktion erneut aus.

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)

Die Debug - Stripper - Optimierer streift den tf.debug.check_numerics Knoten aus dem Graphen und führt die Funktion ohne Fehler erhöht.

Zusammenfassung

Die TensorFlow-Laufzeit verwendet Grappler, um Grafiken vor der Ausführung automatisch zu optimieren. Verwenden tf.config.optimizer.set_experimental_options die verschiedenen Graphen Optimizern aktivieren oder deaktivieren.

Weitere Informationen zu den Grappler finden TensorFlow Graph Optimizations .