Эта страница была переведа с помощью Cloud Translation API.
Switch to English

Оптимизация графа TensorFlow с помощью Grappler

Посмотреть на TensorFlow.org Запустить в Google Colab Посмотреть источник на GitHub Скачать блокнот

обзор

TensorFlow использует как граф, так и энергичные исполнения для выполнения вычислений. tf.Graph содержит набор объектов tf.Operation (ops), которые представляют единицы вычислений, и объектов tf.Tensor которые представляют единицы данных, которые tf.Tensor между ops.

Grappler - это система оптимизации графиков по умолчанию во время выполнения TensorFlow. Grappler применяет оптимизации в графическом режиме (в tf.function ), чтобы повысить производительность вычислений TensorFlow посредством упрощений графиков и других высокоуровневых оптимизаций, таких как встроенные тела функций, для обеспечения межпроцедурной оптимизации. Оптимизация tf.Graph также уменьшает пиковое использование памяти устройства и улучшает использование оборудования, оптимизируя отображение узлов графа для вычисления ресурсов.

Используйте tf.config.optimizer.set_experimental_options() для более точного контроля над вашими оптимизациями tf.Graph .

Доступные оптимизаторы графиков

Grappler выполняет оптимизацию графиков с помощью драйвера верхнего уровня, который называется MetaOptimizer . Следующие графические оптимизаторы доступны с TensorFlow:

  • Оптимизатор свертывания констант - Статически выводит значение тензоров, когда это возможно, путем свертывания константных узлов на графике и материализует результат, используя константы.
  • Арифметический оптимизатор - упрощает арифметические операции за счет исключения общих подвыражений и упрощения арифметических операторов.
  • Оптимизатор макетов - оптимизирует тензорные макеты для более эффективного выполнения зависимых от формата данных операций, таких как свертки.
  • Оптимизатор Remapper - преобразовывает подграфы в более эффективные реализации, заменяя часто встречающиеся подграфы оптимизированными слитными монолитными ядрами.
  • Оптимизатор памяти - анализирует график для проверки пикового использования памяти для каждой операции и вставляет операции копирования памяти CPU-GPU для перестановки памяти GPU в CPU, чтобы уменьшить пиковое использование памяти.
  • Оптимизатор зависимостей - удаляет или реорганизует управляющие зависимости, чтобы сократить критический путь для шага модели или разрешить другие оптимизации. Также удаляет узлы, которые фактически не используются, такие как Identity.
  • Оптимизатор сокращения - удаляет узлы, которые не влияют на вывод графика. Обычно он запускается первым, чтобы уменьшить размер графика и ускорить обработку на других проходах Grappler.
  • Оптимизатор функций - Оптимизирует библиотеку функций программы TensorFlow и включает встроенные тела функций для обеспечения других межпроцедурных оптимизаций.
  • Оптимизатор формы - Оптимизирует подграфы, которые работают с информацией о форме и форме.
  • Автопараллельный оптимизатор - автоматическое распараллеливание графиков путем разделения по размеру пакета. По умолчанию этот оптимизатор выключен.
  • Оптимизатор цикла - Оптимизирует поток управления графиком, поднимая из циклов инвариантные в цикле подграфы и удаляя лишние операции стека в циклах. Также оптимизирует циклы со статически известными счетчиками отключений и удаляет статически известные мертвые ветви в условных выражениях.
  • Оптимизатор распределителя по объему - вводит распределители по объему, чтобы уменьшить перемещение данных и объединить некоторые операции.
  • Pin to host optimizer - Меняет небольшие операции на ЦП. По умолчанию этот оптимизатор выключен.
  • Автоматический оптимизатор смешанной точности - конвертирует типы данных в float16, где это применимо, для повышения производительности. В настоящее время относится только к графическим процессорам.
  • Отладки стриппер - Полоски узлы , связанные с отладкой таких операций, как tf.debugging.Assert , tf.debugging.check_numerics и tf.print от графика. По умолчанию этот оптимизатор выключен.

Настроить

 import numpy as np
import timeit
import traceback
import contextlib


import tensorflow as tf
 

Создайте менеджер контекста, чтобы легко переключать состояния оптимизатора.

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

Сравните производительность выполнения с и без Grappler

TensorFlow 2 и выше по умолчанию выполняется с нетерпением . Используйте tf.function чтобы переключить выполнение по умолчанию в режим графика. Grappler автоматически запускается в фоновом режиме, чтобы применить приведенные выше оптимизации графиков и повысить производительность выполнения.

Оптимизатор постоянного сворачивания

В качестве предварительного примера рассмотрим функцию, которая выполняет операции над константами и возвращает выходные данные.

 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
 

Отключите оптимизатор постоянного сворачивания и выполните функцию:

 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

Включите оптимизатор постоянного сворачивания и снова выполните функцию, чтобы наблюдать ускорение выполнения функции.

 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

Оптимизатор отладки отладки

Рассмотрим простую функцию, которая проверяет числовое значение своего входного аргумента и возвращает его.

 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
 

Сначала выполните функцию с выключенным оптимизатором стриппера отладки.

 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 вызывает ошибку неверного аргумента из-за аргумента Inf для test_func .

Включите оптимизатор стриппера отладки и снова запустите функцию.

 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)
 

Оптимизатор средства отладки удаляет узел tf.debug.check_numerics из графа и выполняет функцию без каких-либо ошибок.

Резюме

Среда выполнения TensorFlow использует Grappler для автоматической оптимизации графиков перед выполнением. Используйте tf.config.optimizer.set_experimental_options чтобы включить или отключить различные оптимизаторы графиков.

Для получения дополнительной информации о Grappler см. Оптимизация графиков TensorFlow .