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

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

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

Обзор

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

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

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

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

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

  • Оптимизатор сворачивания констант - статически определяет значение тензоров, когда это возможно, сворачивая константные узлы в графе и материализует результат с помощью констант.
  • Оптимизатор арифметических операций - упрощает арифметические операции за счет исключения общих подвыражений и упрощения арифметических операторов.
  • Оптимизатор макета - оптимизирует тензорные макеты для более эффективного выполнения операций, зависящих от формата данных, таких как свертки.
  • Оптимизатор Remapper - переназначает подграфы на более эффективные реализации, заменяя часто встречающиеся подграфы оптимизированными объединенными монолитными ядрами.
  • Оптимизатор памяти - анализирует график для проверки пикового использования памяти для каждой операции и вставляет операции копирования памяти CPU-GPU для замены памяти GPU на CPU для уменьшения пикового использования памяти.
  • Оптимизатор зависимостей - удаляет или переупорядочивает зависимости управления, чтобы сократить критический путь для шага модели или включает другие оптимизации. Также удаляет узлы, которые фактически не выполняются, такие как Identity.
  • Оптимизатор сокращения - удаляет узлы, которые не влияют на вывод графа. Обычно он запускается первым, чтобы уменьшить размер графика и ускорить обработку в других проходах Grappler.
  • Оптимизатор функций - оптимизирует библиотеку функций программы TensorFlow и встраивает тела функций для включения других межпроцедурных оптимизаций.
  • Оптимизатор формы - оптимизирует подграфы, которые работают с информацией, связанной с формой.
  • Автопараллельный оптимизатор - автоматически распараллеливает графики путем разделения по размерности партии. По умолчанию этот оптимизатор выключен.
  • Оптимизатор цикла - оптимизирует поток управления графом, поднимая инвариантные к циклам подграфы из циклов и удаляя избыточные операции стека в циклах. Также оптимизирует циклы со статически известным счетчиком отключений и удаляет статически известные мертвые ветви в условных выражениях.
  • Оптимизатор распределителя с заданной областью - вводит распределители с заданной областью для уменьшения перемещения данных и консолидации некоторых операций.
  • Закрепить на оптимизаторе хоста - переключает небольшие операции на ЦП. По умолчанию этот оптимизатор выключен.
  • Оптимизатор автоматической смешанной точности - преобразует типы данных в float16, где это применимо, для повышения производительности. В настоящее время относится только к графическим процессорам.
  • tf.debugging.Assert tf.debugging.check_numerics отладки - удаляет узлы, связанные с операциями отладки, такими как 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.0801323579999007 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.0006300529998952697 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 780, 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) ]]
  (1) Invalid argument:  Bad! : Tensor had Inf values
     [[node CheckNumerics (defined at <ipython-input-7-cbee1561c83e>:5) ]]
     [[Identity/_4]]
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 отладки удаляет узел tf.debug.check_numerics из графа и выполняет функцию, не вызывая ошибок.

Резюме

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

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