Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

TensorFlow-Diagrammoptimierung mit Grappler

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

Überblick

TensorFlow verwendet sowohl grafische als auch eifrige Ausführungen, um Berechnungen auszuführen. Ein tf.Graph enthält eine Reihe von tf.Operation Objekten (ops), die Recheneinheiten darstellen, und tf.Tensor Objekte, die die Dateneinheiten darstellen, die zwischen ops fließen.

Grappler ist das Standard-Grafikoptimierungssystem in der TensorFlow-Laufzeit. Grappler wendet Optimierungen im Diagrammmodus (innerhalb von tf.function ) an, um die Leistung Ihrer TensorFlow-Berechnungen durch Diagrammvereinfachungen und andere Optimierungen auf hoher Ebene wie Inlining-Funktionskörper zu verbessern, um prozedurale Optimierungen zu ermöglichen. Durch die Optimierung des tf.Graph auch die tf.Graph Speichernutzung des Geräts reduziert und die Hardwareauslastung verbessert, indem die Zuordnung von Diagrammknoten zur Berechnung von Ressourcen optimiert wird.

Verwenden Sie tf.config.optimizer.set_experimental_options() , um Ihre tf.Graph Optimierungen tf.Graph .

Verfügbare Grafikoptimierer

Grappler führt Diagrammoptimierungen über einen Top-Level-Treiber namens MetaOptimizer . Die folgenden Grafikoptimierer sind mit TensorFlow verfügbar:

  • Optimierer für konstante Faltung - Leitet den Wert von Tensoren nach Möglichkeit statisch ab, indem konstante Knoten im Diagramm gefaltet werden, und materialisiert das Ergebnis mithilfe von Konstanten.
  • Arithmetik-Optimierer - Vereinfacht arithmetische Operationen, indem allgemeine Unterausdrücke eliminiert und arithmetische Anweisungen vereinfacht werden.
  • Layout-Optimierer - Optimiert Tensor-Layouts, um datenformatabhängige Operationen wie Faltungen effizienter auszuführen.
  • Remapper-Optimierer - Ordnet Subgraphen effizienteren Implementierungen zu, indem häufig vorkommende Subgraphen durch optimierte fusionierte monolithische Kernel ersetzt werden.
  • Speicheroptimierer - Analysiert das Diagramm, um die maximale Speicherauslastung für jede Operation zu überprüfen, und fügt CPU-GPU-Speicherkopiervorgänge zum Austauschen des GPU-Speichers in die CPU ein, um die maximale Speicherauslastung zu verringern.
  • Abhängigkeitsoptimierer - Entfernt Steuerungsabhängigkeiten oder ordnet sie neu an, um den kritischen Pfad für einen Modellschritt zu verkürzen oder andere Optimierungen zu aktivieren. Entfernt auch Knoten, die praktisch keine Operationen sind, wie z. B. Identität.
  • Bereinigungsoptimierer - Bereinigt Knoten, die keinen Einfluss auf die Ausgabe des Diagramms haben. Es wird normalerweise zuerst ausgeführt, um die Größe des Diagramms zu verringern und die Verarbeitung in anderen Grappler-Durchläufen zu beschleunigen.
  • Funktionsoptimierer - Optimiert die Funktionsbibliothek eines TensorFlow-Programms und integriert Funktionskörper, um andere prozedurale Optimierungen zu ermöglichen.
  • Formoptimierer - Optimiert Untergraphen, die mit Form und formbezogenen Informationen arbeiten.
  • Autoparalleler Optimierer - Parallelisiert Diagramme automatisch durch Aufteilen entlang der Stapeldimension. Dieser Optimierer ist standardmäßig deaktiviert.
  • Schleifenoptimierer - Optimiert den Diagrammsteuerungsfluss, indem schleifeninvariante Untergraphen aus Schleifen gehoben und redundante Stapeloperationen in Schleifen entfernt werden. Optimiert auch Schleifen mit statisch bekannten Auslösezahlen und entfernt statisch bekannte tote Zweige unter Bedingungen.
  • Scoped Allocator Optimizer - Einführung von Scoped Allocators zur Reduzierung der Datenbewegung und zur Konsolidierung einiger Vorgänge.
  • Pin to Host Optimizer - Tauscht kleine Operationen auf die CPU aus. Dieser Optimierer ist standardmäßig deaktiviert.
  • Auto Mixed Precision Optimizer - Konvertiert Datentypen gegebenenfalls in float16, um die Leistung zu verbessern. Gilt derzeit nur für GPUs.
  • Debug-Stripper - Entfernt Knoten, die sich auf Debugging-Vorgänge wie tf.debugging.Assert , tf.debugging.check_numerics und tf.print tf.debugging.check_numerics , aus dem Diagramm. Dieser Optimierer ist standardmäßig deaktiviert.

Konfiguration

 import numpy as np
import timeit
import traceback
import contextlib


import tensorflow as tf
 

Erstellen Sie einen Kontextmanager, um den Optimierungsstatus 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 höher wird standardmäßig eifrig ausgeführt . Verwenden Sie tf.function , um die Standardausführung in den tf.function zu schalten. 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 an 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 Optimierer für konstante Faltung aus und führen Sie die folgende 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.004905937999865273 s

Aktivieren Sie den Optimierer für die konstante Faltung 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.0005699149999145448 s

Debug Stripper Optimizer

Stellen Sie sich eine einfache Funktion vor, 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 zunächst die Funktion bei 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)
 
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 löst aufgrund des Inf Arguments für test_func einen ungültigen Argumentfehler aus.

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)
 

Der Debug-Stripper-Optimierer entfernt den Knoten tf.debug.check_numerics aus dem Diagramm und führt die Funktion aus, ohne Fehler tf.debug.check_numerics .

Zusammenfassung

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

Weitere Informationen zu Grappler finden Sie unter TensorFlow-Diagrammoptimierungen .