Благодарим за настройку Google I/O. Посмотреть все сеансы по запросу Смотреть по запросу

Оптимизируйте производительность TensorFlow с помощью Profiler

В этом руководстве показано, как использовать инструменты, доступные с TensorFlow Profiler, для отслеживания производительности ваших моделей TensorFlow. Вы узнаете, как понять, как ваша модель работает на хосте (ЦП), устройстве (ГП) или на комбинации хоста и устройства (устройств).

Профилирование помогает понять потребление аппаратных ресурсов (время и память) различными операциями TensorFlow (ops) в вашей модели и устранить узкие места в производительности и, в конечном счете, ускорить выполнение модели.

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

Если вы хотите профилировать производительность вашей модели на Cloud TPU, обратитесь к руководству Cloud TPU .

Установите необходимые компоненты Profiler и GPU

Установите плагин Profiler для TensorBoard с помощью pip. Обратите внимание, что для профайлера требуются последние версии TensorFlow и TensorBoard (>=2.2).

pip install -U tensorboard_plugin_profile

Для профилирования на GPU необходимо:

  1. Соблюдайте требования к драйверам графического процессора NVIDIA® и набору инструментов CUDA®, перечисленные в требованиях к программному обеспечению для поддержки графического процессора TensorFlow.
  2. Убедитесь, что интерфейс средств профилирования NVIDIA® CUDA® (CUPTI) существует по пути:

    /sbin/ldconfig -N -v $(sed 's/:/ /g' <<< $LD_LIBRARY_PATH) | \
    grep libcupti
    

Если у вас нет CUPTI в пути, добавьте его каталог установки в переменную среды $LD_LIBRARY_PATH , выполнив:

export LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH

Затем снова запустите приведенную выше команду ldconfig , чтобы убедиться, что библиотека CUPTI найдена.

Устранение проблем с привилегиями

Когда вы запускаете профилирование с помощью CUDA® Toolkit в среде Docker или в Linux, вы можете столкнуться с проблемами, связанными с недостаточными привилегиями CUPTI ( CUPTI_ERROR_INSUFFICIENT_PRIVILEGES ). Перейдите в документацию для разработчиков NVIDIA , чтобы узнать больше о том, как решить эти проблемы в Linux.

Чтобы решить проблемы с привилегиями CUPTI в среде Docker, запустите

docker run option '--privileged=true'

Инструменты профилировщика

Получите доступ к профилировщику на вкладке « Профиль » в TensorBoard, которая появляется только после того, как вы захватили некоторые данные модели.

В Profiler есть набор инструментов, помогающих в анализе производительности:

  • Обзорная страница
  • Анализатор входного конвейера
  • Статистика TensorFlow
  • Средство просмотра трассировки
  • Статистика ядра графического процессора
  • Инструмент профиля памяти
  • Средство просмотра модуля

Обзорная страница

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

На обзорной странице отображаются данные следующим образом:

изображение

  • Сводка по производительности : отображает сводную информацию высокого уровня о производительности вашей модели. Сводка производительности состоит из двух частей:

    1. Разбивка времени шага: разбивает среднее время шага на несколько категорий, на которые тратится время:

      • Компиляция: время, потраченное на компиляцию ядер.
      • Ввод: время, потраченное на чтение входных данных.
      • Вывод: время, потраченное на чтение выходных данных.
      • Запуск ядра: время, затрачиваемое хостом на запуск ядер.
      • Время вычислений хоста..
      • Время связи между устройствами.
      • Время вычислений на устройстве.
      • Все остальные, включая накладные расходы Python.
    2. Точность вычислений устройства. Отображает процент времени вычислений устройства, в котором используются 16- и 32-разрядные вычисления.

  • Диаграмма времени шага : отображает график времени шага устройства (в миллисекундах) по всем выбранным шагам. Каждый шаг разбит на несколько категорий (с разными цветами), на которые тратится время. Красная область соответствует части времени, в течение которого устройства бездействовали, ожидая ввода данных от хоста. Зеленая область показывает, сколько времени устройство фактически работало.

  • 10 основных операций TensorFlow на устройстве (например, GPU) : отображаются операции на устройстве, которые выполнялись дольше всего.

    В каждой строке отображается собственное время операции (в процентах от времени, затраченного всеми операциями), совокупное время, категория и имя.

  • Среда запуска : отображает общую сводку среды запуска модели, включая:

    • Количество используемых хостов.
    • Тип устройства (GPU/TPU).
    • Количество ядер устройства.
  • Рекомендация для следующего шага : сообщает, когда модель привязана к входным данным, и рекомендует инструменты, которые можно использовать для обнаружения и устранения узких мест в производительности модели.

Анализатор входного конвейера

Когда программа TensorFlow считывает данные из файла, она начинается с верхней части графа TensorFlow конвейерным способом. Процесс чтения делится на несколько последовательно соединенных этапов обработки данных, где выход одного этапа является входом для следующего. Эта система чтения данных называется входным конвейером .

Типичный конвейер чтения записей из файлов состоит из следующих этапов:

  1. Чтение файла.
  2. Предварительная обработка файлов (необязательно).
  3. Передача файлов с хоста на устройство.

Неэффективный конвейер ввода может сильно замедлить работу вашего приложения. Приложение считается связанным с вводом, если оно проводит значительную часть времени во входном конвейере. Используйте информацию, полученную с помощью анализатора входного конвейера, чтобы понять, где входной конвейер неэффективен.

Анализатор входного конвейера немедленно сообщит вам, привязана ли ваша программа к вводу, и проведет вас через анализ устройства и хоста для устранения узких мест производительности на любом этапе входного конвейера.

Ознакомьтесь с руководством по производительности конвейера ввода, чтобы узнать о рекомендуемых передовых методах оптимизации конвейеров ввода данных.

Панель управления конвейером ввода

Чтобы открыть анализатор входного конвейера, выберите « Профиль », затем выберите input_pipeline_analyzer в раскрывающемся списке « Инструменты ».

изображение

Панель инструментов содержит три раздела:

  1. Сводка : обобщает общий конвейер ввода с информацией о том, привязано ли ваше приложение к вводу, и если да, то насколько.
  2. Анализ на стороне устройства . Отображает подробные результаты анализа на стороне устройства, включая время шага устройства и диапазон времени, затрачиваемого устройством на ожидание входных данных между ядрами на каждом этапе.
  3. Анализ на стороне хоста : показывает подробный анализ на стороне хоста, включая разбивку времени обработки ввода на хосте.

Сводка входного конвейера

Сводка сообщает, привязана ли ваша программа к вводу, представляя процент времени, потраченного устройством на ожидание ввода от хоста. Если вы используете стандартный конвейер ввода, который был инструментирован, инструмент сообщает, где тратится большая часть времени обработки ввода.

Анализ на стороне устройства

Анализ на стороне устройства дает представление о времени, затраченном на устройстве по сравнению с хостом, а также о том, сколько времени устройство потратило на ожидание входных данных с хоста.

  1. Время шага в зависимости от номера шага : отображает график времени шага устройства (в миллисекундах) по всем выбранным шагам. Каждый шаг разбит на несколько категорий (с разными цветами), на которые тратится время. Красная область соответствует части времени, в течение которого устройства бездействовали, ожидая ввода данных от хоста. Зеленая область показывает, сколько времени устройство действительно работало.
  2. Статистика времени шага : сообщает среднее значение, стандартное отклонение и диапазон ([минимум, максимум]) времени шага устройства.

Анализ на стороне хоста

Анализ на стороне хоста сообщает о разбивке времени обработки ввода (время, затрачиваемое на операции API tf.data ) на хосте по нескольким категориям:

  • Чтение данных из файлов по требованию : время, затрачиваемое на чтение данных из файлов без кэширования, предварительной выборки и чередования.
  • Предварительное чтение данных из файлов: время, затраченное на чтение файлов, включая кэширование, предварительную выборку и чередование.
  • Предварительная обработка данных : время, затрачиваемое на операции предварительной обработки, такие как распаковка изображений.
  • Постановка данных в очередь для передачи на устройство : время, затрачиваемое на помещение данных в очередь подачи перед передачей данных на устройство.

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

изображение

Появится таблица исходных данных с каждой записью, содержащей следующую информацию:

  1. Входная операция : показывает имя операции TensorFlow для входной операции.
  2. Счетчик : показывает общее количество экземпляров выполнения операции в течение периода профилирования.
  3. Общее время (в мс) : показывает совокупную сумму времени, затраченного на каждый из этих экземпляров.
  4. Общее время % : показывает общее время, затраченное на операцию, как часть общего времени, затраченного на обработку ввода.
  5. Общее время на себя (в мс) : показывает совокупную сумму времени на себя, затраченного на каждый из этих случаев. Само время здесь измеряет время, проведенное внутри тела функции, исключая время, проведенное в вызываемой функции.
  6. Общее время на себя % . Показывает общее время, затраченное на обработку ввода, как долю общего времени, затраченного на обработку ввода.
  7. Категория . Показывает категорию обработки входной операции.

Статистика TensorFlow

Инструмент TensorFlow Stats отображает производительность каждой операции TensorFlow, которая выполняется на хосте или устройстве во время сеанса профилирования.

изображение

Инструмент отображает информацию о производительности на двух панелях:

  • На верхней панели отображается до четырех круговых диаграмм:

    1. Распределение времени самовыполнения каждой операции на хосте.
    2. Распределение времени самовыполнения каждого типа операции на хосте.
    3. Распределение времени самовыполнения каждой операции на устройстве.
    4. Распределение времени самовыполнения каждого типа операции на устройстве.
  • На нижней панели показана таблица с данными об операциях TensorFlow с одной строкой для каждой операции и одним столбцом для каждого типа данных (столбцы можно отсортировать, щелкнув заголовок столбца). Нажмите кнопку « Экспортировать как CSV » в правой части верхней панели, чтобы экспортировать данные из этой таблицы в виде файла CSV.

    Обратите внимание, что:

    • Если какие-либо операции имеют дочерние операции:

      • Общее «накопленное» время операции включает время, проведенное внутри дочерних операций.
      • Общее «само» время операции не включает время, проведенное внутри дочерних операций.
    • Если операция выполняется на хосте:

      • Процент от общего времени нахождения на устройстве, понесенного опцией, будет равен 0.
      • Совокупный процент от общего времени нахождения на устройстве до этой операции включительно будет равен 0.
    • Если операция выполняется на устройстве:

      • Процент общего времени нахождения на хосте, понесенного этой операцией, будет равен 0.
      • Совокупный процент общего времени на хосте до этой операции включительно будет равен 0.

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

Средство просмотра трассировки

Средство просмотра трассировки отображает временную шкалу, которая показывает:

  • Длительность операций, выполненных вашей моделью TensorFlow.
  • Какая часть системы (хост или устройство) выполнила операцию. Как правило, хост выполняет операции ввода, предварительно обрабатывает обучающие данные и передает их на устройство, в то время как устройство выполняет фактическое обучение модели.

Средство просмотра трассировки позволяет выявить проблемы с производительностью в вашей модели, а затем принять меры для их устранения. Например, на высоком уровне вы можете определить, что занимает большую часть времени — ввод данных или обучение модели. Детализируя информацию, вы можете определить, какие операции выполняются дольше всего. Обратите внимание, что средство просмотра трассировки ограничено 1 миллионом событий на устройство.

Интерфейс просмотра трасс

Когда вы открываете средство просмотра трассировки, оно показывает ваш последний запуск:

изображение

Этот экран содержит следующие основные элементы:

  1. Панель временной шкалы: показывает операции, которые устройство и хост выполняли с течением времени.
  2. Панель сведений: показывает дополнительную информацию об операциях, выбранных на панели временной шкалы.

Панель временной шкалы содержит следующие элементы:

  1. Верхняя панель : содержит различные вспомогательные элементы управления.
  2. Ось времени : показывает время относительно начала кривой.
  3. Метки разделов и дорожек . Каждый раздел содержит несколько дорожек и имеет треугольник слева, который можно щелкнуть, чтобы развернуть или свернуть раздел. Для каждого обрабатывающего элемента в системе имеется по одному разделу.
  4. Селектор инструментов : содержит различные инструменты для взаимодействия со средством просмотра трасс, такие как масштабирование, панорамирование, выбор и синхронизация. Используйте инструмент синхронизации, чтобы отметить временной интервал.
  5. События : они показывают время, в течение которого выполнялась операция, или продолжительность метасобытий, таких как этапы обучения.
Разделы и треки

Средство просмотра трассировки содержит следующие разделы:

  • Один раздел для каждого узла устройства , помеченный номером микросхемы устройства и узлом устройства внутри микросхемы (например, /device:GPU:0 (pid 0) ). Каждый раздел узла устройства содержит следующие дорожки:
    • Шаг : показывает продолжительность шагов обучения, которые выполнялись на устройстве.
    • TensorFlow Ops : показывает операции, выполненные на устройстве.
    • XLA Ops : показывает операции XLA (ops), которые выполнялись на устройстве, если XLA используется в качестве компилятора (каждая операция TensorFlow транслируется в одну или несколько операций XLA. Компилятор XLA переводит операции XLA в код, который выполняется на устройстве).
  • Один раздел для потоков, работающих на ЦП хост-компьютера, помеченный как «Host Threads» . Раздел содержит по одной дорожке для каждого потока ЦП. Обратите внимание, что вы можете игнорировать информацию, отображаемую рядом с метками разделов.
События

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

Средство просмотра трассировки также может отображать трассировки вызовов функций Python в вашей программе TensorFlow. Если вы используете API tf.profiler.experimental.start , вы можете включить трассировку Python с помощью именованного кортежа ProfilerOptions при запуске профилирования. В качестве альтернативы, если вы используете режим выборки для профилирования, вы можете выбрать уровень трассировки, используя параметры раскрывающегося списка в диалоговом окне « Захват профиля ».

изображение

Статистика ядра графического процессора

Этот инструмент показывает статистику производительности и исходную операцию для каждого ядра с ускорением на GPU.

изображение

Инструмент отображает информацию в двух панелях:

  • На верхней панели отображается круговая диаграмма, на которой показаны ядра CUDA с наибольшим общим временем выполнения.

  • На нижней панели отображается таблица со следующими данными для каждой уникальной пары ядро-оператор:

    • Ранг в порядке убывания общей истекшей продолжительности GPU, сгруппированный по паре ядро-операция.
    • Имя запущенного ядра.
    • Количество регистров GPU, используемых ядром.
    • Общий размер используемой общей (статической + динамической) памяти в байтах.
    • Размер блока, выраженный как blockDim.x, blockDim.y, blockDim.z .
    • Размеры сетки, выраженные как gridDim.x, gridDim.y, gridDim.z .
    • Имеет ли оператор право использовать тензорные ядра .
    • Содержит ли ядро ​​инструкции Tensor Core.
    • Имя оператора, запустившего это ядро.
    • Количество вхождений этой пары ядро-оператор.
    • Общее затраченное время GPU в микросекундах.
    • Среднее затраченное время GPU в микросекундах.
    • Минимальное истекшее время GPU в микросекундах.
    • Максимальное истекшее время GPU в микросекундах.

Инструмент профиля памяти

Инструмент « Профиль памяти » отслеживает использование памяти вашего устройства в течение интервала профилирования. Вы можете использовать этот инструмент для:

  • Отладка проблем нехватки памяти (OOM) путем точного определения пикового использования памяти и соответствующего выделения памяти для операций TensorFlow. Вы также можете отлаживать проблемы OOM, которые могут возникнуть при выполнении логического вывода с несколькими арендаторами .
  • Отладка проблем с фрагментацией памяти.

Инструмент профиля памяти отображает данные в трех разделах:

  1. Сводка профиля памяти
  2. График временной шкалы памяти
  3. Таблица распределения памяти

Сводка профиля памяти

В этом разделе отображается общая сводка профиля памяти вашей программы TensorFlow, как показано ниже:

Сводка профиля памяти состоит из шести полей:

  1. Идентификатор памяти : выпадающий список, в котором перечислены все доступные системы памяти устройства. Выберите систему памяти, которую вы хотите просмотреть, из раскрывающегося списка.
  2. #Allocation : количество выделений памяти, сделанных в течение интервала профилирования.
  3. #Deallocation : количество освобождений памяти в интервале профилирования.
  4. Емкость памяти : общая емкость (в гигабайтах) выбранной вами системы памяти.
  5. Пиковое использование кучи : пиковое использование памяти (в гигабайтах) с момента запуска модели.
  6. Пиковое использование памяти : пиковое использование памяти (в гигабайтах) в интервале профилирования. Это поле содержит следующие подполя:
    1. Отметка времени : отметка времени пикового использования памяти на графике временной шкалы.
    2. Резервирование стека : объем памяти, зарезервированный в стеке (в гигабайтах).
    3. Распределение кучи : объем памяти, выделенный в куче (в гигабайтах).
    4. Свободная память : объем свободной памяти (в гигабайтах). Емкость памяти — это сумма резервирования стека, распределения кучи и свободной памяти.
    5. Фрагментация : процент фрагментации (чем меньше, тем лучше). Он рассчитывается в процентах от (1 - Size of the largest chunk of free memory / Total free memory) .

График временной шкалы памяти

В этом разделе отображается график использования памяти (в гигабайтах) и процента фрагментации в зависимости от времени (в мс).

изображение

Ось X представляет временную шкалу (в мс) интервала профилирования. Ось Y слева представляет использование памяти (в гигабайтах), а ось Y справа представляет процент фрагментации. В каждый момент времени по оси X общий объем памяти разбивается на три категории: стек (красный), куча (оранжевый) и свободный (зеленый). Наведите указатель мыши на определенную отметку времени, чтобы просмотреть сведения о событиях выделения/освобождения памяти в этот момент, как показано ниже:

изображение

Во всплывающем окне отображается следующая информация:

  • метка времени (мс) : местоположение выбранного события на временной шкале.
  • event : Тип события (распределение или освобождение).
  • запрашиваемый_размер (ГиБ) : объем запрошенной памяти. Это будет отрицательное число для событий освобождения.
  • location_size(GiBs) : Фактический объем выделенной памяти. Это будет отрицательное число для событий освобождения.
  • tf_op : операция TensorFlow, которая запрашивает выделение/освобождение.
  • step_id : шаг обучения, на котором произошло это событие.
  • region_type : тип объекта данных, для которого предназначена эта выделенная память. Возможные значения: temp для временных значений, output для активаций и градиентов и persist / dynamic для весов и констант.
  • data_type : тип элемента тензора (например, uint8 для 8-битного целого числа без знака).
  • tensor_shape : форма выделяемого/освобождаемого тензора.
  • memory_in_use(GiBs) : общая память, которая используется в данный момент времени.

Таблица разбивки памяти

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

изображение

Для каждой операции TensorFlow существует одна строка, и каждая строка имеет следующие столбцы:

  • Имя операции: имя операции TensorFlow.
  • Размер выделения (ГиБ) : общий объем памяти, выделенный для этой операции.
  • Запрошенный размер (ГиБ) : общий объем памяти, запрошенный для этой операции.
  • Вхождения : количество выделений для этой операции.
  • Тип региона: тип объекта данных, для которого предназначена эта выделенная память. Возможные значения: temp для временных значений, output для активаций и градиентов и persist / dynamic для весов и констант.
  • Тип данных: тип элемента тензора.
  • Shape : Форма выделенных тензоров.

Средство просмотра модуля

Инструмент Pod Viewer показывает разбивку шага обучения по всем воркерам.

изображение

  • На верхней панели есть ползунок для выбора номера шага.
  • На нижней панели отображается столбчатая диаграмма с накоплением. Это высокоуровневое представление разбитых категорий времени шага, расположенных друг над другом. Каждый сложенный столбец представляет собой уникального рабочего.
  • Когда вы наводите курсор на столбец с накоплением, карточка с левой стороны показывает более подробную информацию о разбивке по шагам.

Анализ узких мест tf.data

Инструмент анализа узких мест tf.data автоматически обнаруживает узкие места во входных конвейерах tf.data в вашей программе и предоставляет рекомендации по их устранению. Он работает с любой программой, использующей tf.data независимо от платформы (CPU/GPU/TPU). Его анализ и рекомендации основаны на этом руководстве .

Он обнаруживает узкое место, выполнив следующие действия:

  1. Найдите хост с наибольшим количеством входных данных.
  2. Найдите самое медленное выполнение входного конвейера tf.data .
  3. Восстановите график входного конвейера из трассировки профилировщика.
  4. Найдите критический путь во входном графе конвейера.
  5. Определите самое медленное преобразование на критическом пути как узкое место.

Пользовательский интерфейс разделен на три раздела: «Сводка анализа производительности» , «Сводка всех входных конвейеров» и « График входного конвейера» .

Сводка анализа производительности

изображение

В этом разделе приводится краткое изложение анализа. Он сообщает о медленных входных конвейерах tf.data , обнаруженных в профиле. В этом разделе также показан хост с наибольшей привязкой ввода и его самый медленный конвейер ввода с максимальной задержкой. Самое главное, он определяет, какая часть входного конвейера является узким местом и как это исправить. Информация об узком месте представлена ​​типом итератора и его длинным именем.

Как прочитать длинное имя итератора tf.data

Длинное имя имеет формат Iterator::<Dataset_1>::...::<Dataset_n> . В длинном имени <Dataset_n> соответствует типу итератора, а другие наборы данных в длинном имени представляют последующие преобразования.

Например, рассмотрим следующий набор данных входного конвейера:

dataset = tf.data.Dataset.range(10).map(lambda x: x).repeat(2).batch(5)

Длинные имена итераторов из приведенного выше набора данных будут такими:

Тип итератора Длинное имя
Диапазон Iterator::Batch::Repeat::Map::Range
карта Iterator::Batch::Repeat::Map
Повторение Итератор::Пакетный::Повторить
Партия Итератор:: Пакет

Сводка всех входных конвейеров

изображение

В этом разделе представлена ​​сводка всех входных конвейеров на всех хостах. Обычно имеется один входной конвейер. При использовании стратегии распространения имеется один конвейер ввода хоста, на котором выполняется код программы tf.data , и конвейеры ввода нескольких устройств, извлекающие данные из конвейера ввода хоста и передающие их на устройства.

Для каждого входного конвейера показывает статистику времени его выполнения. Вызов считается медленным, если он длится более 50 мкс.

Граф входного конвейера

изображение

В этом разделе показан график входного конвейера с информацией о времени выполнения. Вы можете использовать «Хост» и «Входной конвейер», чтобы выбрать хост и входной конвейер для просмотра. Выполнения входного конвейера сортируются по времени выполнения в порядке убывания, которое вы можете выбрать в раскрывающемся списке Ранг .

изображение

Узлы критического пути обведены жирным шрифтом. Узел узкого места, который является узлом с наибольшим временем нахождения на критическом пути, имеет красный контур. Остальные некритические узлы имеют серые пунктирные контуры.

В каждом узле Start Time указывает время начала выполнения. Один и тот же узел может выполняться несколько раз, например, если во входном конвейере есть Batch операция. Если он выполняется несколько раз, это время начала первого выполнения.

Общая продолжительность — это время исполнения. Если он выполняется несколько раз, это сумма времен стены всех выполнений.

Self Time — это Total Time без перекрытия времени с его непосредственными дочерними узлами.

«# Calls» — это количество раз, когда входной конвейер выполняется.

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

Профилировщик TensorFlow собирает действия хоста и трассировки графического процессора вашей модели TensorFlow. Вы можете настроить Profiler для сбора данных о производительности либо в программном режиме, либо в режиме выборки.

API-интерфейсы профилирования

Вы можете использовать следующие API для выполнения профилирования.

  • Программный режим с использованием обратного вызова TensorBoard Keras ( tf.keras.callbacks.TensorBoard )

    # Profile from batches 10 to 15
    tb_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir,
                                                 profile_batch='10, 15')
    
    # Train the model and use the TensorBoard Keras callback to collect
    # performance profiling data
    model.fit(train_data,
              steps_per_epoch=20,
              epochs=5,
              callbacks=[tb_callback])
    
  • Программный режим с использованием API функций tf.profiler

    tf.profiler.experimental.start('logdir')
    # Train the model here
    tf.profiler.experimental.stop()
    
  • Программный режим с использованием контекстного менеджера

    with tf.profiler.experimental.Profile('logdir'):
        # Train the model here
        pass
    

  • Режим выборки: выполните профилирование по требованию с помощью tf.profiler.experimental.server.start , чтобы запустить сервер gRPC с запущенной моделью TensorFlow. После запуска сервера gRPC и запуска модели вы можете захватить профиль с помощью кнопки « Захват профиля » в подключаемом модуле профиля TensorBoard. Используйте сценарий из раздела «Установка профилировщика» выше, чтобы запустить экземпляр TensorBoard, если он еще не запущен.

    В качестве примера,

    # Start a profiler server before your model runs.
    tf.profiler.experimental.server.start(6009)
    # (Model code goes here).
    #  Send a request to the profiler server to collect a trace of your model.
    tf.profiler.experimental.client.trace('grpc://localhost:6009',
                                          'gs://your_tb_logdir', 2000)
    

    Пример профилирования нескольких работников:

    # E.g. your worker IP addresses are 10.0.0.2, 10.0.0.3, 10.0.0.4, and you
    # would like to profile for a duration of 2 seconds.
    tf.profiler.experimental.client.trace(
        'grpc://10.0.0.2:8466,grpc://10.0.0.3:8466,grpc://10.0.0.4:8466',
        'gs://your_tb_logdir',
        2000)
    

Используйте диалоговое окно Capture Profile , чтобы указать:

  • Разделенный запятыми список URL-адресов службы профилей или имен TPU.
  • Продолжительность профилирования.
  • Уровень трассировки вызовов устройств, хостов и функций Python.
  • Сколько раз вы хотите, чтобы Profiler повторил попытку захвата профилей, если сначала не удалось.

Профилирование пользовательских циклов обучения

Чтобы профилировать пользовательские циклы обучения в коде TensorFlow, инструментируйте цикл обучения с помощью API tf.profiler.experimental.Trace , чтобы отметить границы шагов для профилировщика.

Аргумент name используется в качестве префикса для имен шагов, аргумент ключевого слова step_num добавляется к именам шагов, а аргумент ключевого слова _r позволяет профилировщику обрабатывать это событие трассировки как событие шага.

В качестве примера,

for step in range(NUM_STEPS):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_data = next(dataset)
        train_step(train_data)

Это активирует пошаговый анализ производительности Profiler и приведет к отображению событий шага в средстве просмотра трассировки.

Убедитесь, что вы включили итератор набора данных в контекст tf.profiler.experimental.Trace для точного анализа входного конвейера.

Фрагмент кода ниже является анти-шаблоном:

for step, train_data in enumerate(dataset):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_step(train_data)

Профилирование вариантов использования

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

  • Локальное и удаленное профилирование : это два распространенных способа настройки среды профилирования. При локальном профилировании API профилирования вызывается на том же компьютере, на котором выполняется ваша модель, например, на локальной рабочей станции с графическими процессорами. При удаленном профилировании API профилирования вызывается на компьютере, отличном от того, на котором выполняется ваша модель, например, на облачном TPU.
  • Профилирование нескольких рабочих : вы можете профилировать несколько машин при использовании возможностей распределенного обучения TensorFlow.
  • Аппаратная платформа : Профилируйте ЦП, ГП и ТПУ.

В таблице ниже представлен краткий обзор упомянутых выше вариантов использования с поддержкой TensorFlow:

API профилирования Местный Удаленный Несколько рабочих Аппаратные платформы
Обратный вызов TensorBoard Keras Поддерживается Не поддерживается Не поддерживается ЦП, ГП
tf.profiler.experimental API запуска/остановки Поддерживается Не поддерживается Не поддерживается ЦП, ГП
API-интерфейс tf.profiler.experimental client.trace Поддерживается Поддерживается Поддерживается ЦП, ГП, ТПУ
API диспетчера контекста Поддерживается Не поддерживается Не поддерживается ЦП, ГП

Лучшие практики для оптимальной производительности модели

Используйте следующие рекомендации, применимые к вашим моделям TensorFlow, для достижения оптимальной производительности.

В общем, выполняйте все преобразования на устройстве и убедитесь, что вы используете последнюю совместимую версию библиотек, таких как cuDNN и Intel MKL, для вашей платформы.

Оптимизация конвейера входных данных

Используйте данные из [#input_pipeline_analyzer], чтобы оптимизировать конвейер ввода данных. Эффективный конвейер ввода данных может значительно повысить скорость выполнения вашей модели за счет сокращения времени простоя устройства. Попробуйте применить рекомендации, подробно описанные в руководстве по повышению производительности с помощью API tf.data и ниже, чтобы сделать конвейер ввода данных более эффективным.

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

  • Во многих случаях помогает изменить порядок некоторых вызовов или настроить аргументы так, чтобы они лучше всего работали для вашей модели. При оптимизации конвейера входных данных сравнивайте только загрузчик данных без этапов обучения и обратного распространения, чтобы независимо количественно оценить эффект оптимизации.

  • Попробуйте запустить модель с синтетическими данными, чтобы проверить, не является ли входной конвейер узким местом в производительности.

  • Используйте tf.data.Dataset.shard для обучения работе с несколькими GPU. Убедитесь, что вы выполняете сегментацию на самом раннем этапе цикла ввода, чтобы предотвратить снижение пропускной способности. При работе с TFRecords убедитесь, что вы разбиваете список TFRecords, а не содержимое TFRecords.

  • Распараллеливайте несколько операций, динамически устанавливая значение num_parallel_calls с помощью tf.data.AUTOTUNE .

  • Рассмотрите возможность ограничения использования tf.data.Dataset.from_generator , так как он медленнее по сравнению с чистыми операциями TensorFlow.

  • Рассмотрите возможность ограничения использования tf.py_function , так как она не может быть сериализована и не поддерживается для работы в распределенном TensorFlow.

  • Используйте tf.data.Options для управления статической оптимизацией входного конвейера.

Также прочтите руководство по анализу производительности tf.data , чтобы получить дополнительные рекомендации по оптимизации вашего конвейера ввода.

Оптимизация увеличения данных

При работе с данными изображения повысьте эффективность увеличения данных , приведя их к различным типам данных после применения пространственных преобразований, таких как отражение, обрезка, вращение и т. д.

Используйте NVIDIA® DALI

В некоторых случаях, например, когда у вас есть система с высоким соотношением GPU и CPU, всех вышеперечисленных оптимизаций может быть недостаточно для устранения узких мест в загрузчике данных, вызванных ограничениями циклов CPU.

Если вы используете графические процессоры NVIDIA® для приложений компьютерного зрения и глубокого обучения аудио, рассмотрите возможность использования библиотеки загрузки данных ( DALI ) для ускорения конвейера данных.

Ознакомьтесь с документацией NVIDIA® DALI: Operations для получения списка поддерживаемых операций DALI.

Используйте многопоточность и параллельное выполнение

Запускайте операции в нескольких потоках ЦП с помощью API tf.config.threading , чтобы выполнять их быстрее.

TensorFlow автоматически устанавливает количество потоков параллелизма по умолчанию. Пул потоков, доступный для выполнения операций TensorFlow, зависит от количества доступных потоков ЦП.

Управляйте максимальным параллельным ускорением для одной операции с помощью tf.config.threading.set_intra_op_parallelism_threads . Обратите внимание, что если вы запускаете несколько операций параллельно, все они будут совместно использовать доступный пул потоков.

Если у вас есть независимые неблокирующие операции (операции без направленного пути между ними на графе), используйте tf.config.threading.set_inter_op_parallelism_threads для их одновременного запуска с использованием доступного пула потоков.

Разнообразный

При работе с меньшими моделями на графических процессорах NVIDIA® вы можете установить tf.compat.v1.ConfigProto.force_gpu_compatible=True , чтобы принудительно выделить все тензоры ЦП с закрепленной памятью CUDA, чтобы значительно повысить производительность модели. Однако соблюдайте осторожность при использовании этого параметра для неизвестных/очень больших моделей, так как это может отрицательно сказаться на производительности хоста (ЦП).

Улучшить производительность устройства

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

Если вы используете графические процессоры NVIDIA, запишите использование графического процессора и памяти в файл CSV, выполнив:

nvidia-smi
--query-gpu=utilization.gpu,utilization.memory,memory.total,
memory.free,memory.used --format=csv

Настройка макета данных

При работе с данными, которые содержат информацию о канале (например, изображения), оптимизируйте формат макета данных, чтобы каналы отдавались последними (NHWC, а не NCHW).

Форматы данных последнего канала улучшают использование Tensor Core и обеспечивают значительное повышение производительности, особенно в сверточных моделях в сочетании с AMP. С макетами данных NCHW по-прежнему могут работать тензорные ядра, но они создают дополнительные накладные расходы из-за операций автоматического транспонирования.

Вы можете оптимизировать макет данных, чтобы предпочесть макеты NHWC, установив data_format="channels_last" для таких слоев, как tf.keras.layers.Conv2D , tf.keras.layers.Conv3D и tf.keras.layers.RandomRotation .

Используйте tf.keras.backend.set_image_data_format , чтобы установить формат макета данных по умолчанию для внутреннего API Keras.

Максимальное использование кеша L2

When working with NVIDIA® GPUs, execute the code snippet below before the training loop to max out the L2 fetch granularity to 128 bytes.

import ctypes

_libcudart = ctypes.CDLL('libcudart.so')
# Set device limit on the current device
# cudaLimitMaxL2FetchGranularity = 0x05
pValue = ctypes.cast((ctypes.c_int*1)(), ctypes.POINTER(ctypes.c_int))
_libcudart.cudaDeviceSetLimit(ctypes.c_int(0x05), ctypes.c_int(128))
_libcudart.cudaDeviceGetLimit(pValue, ctypes.c_int(0x05))
assert pValue.contents.value == 128

Configure GPU thread usage

The GPU thread mode decides how GPU threads are used.

Set the thread mode to gpu_private to make sure that preprocessing does not steal all the GPU threads. This will reduce the kernel launch delay during training. You can also set the number of threads per GPU. Set these values using environment variables.

import os

os.environ['TF_GPU_THREAD_MODE']='gpu_private'
os.environ['TF_GPU_THREAD_COUNT']='1'

Configure GPU memory options

In general, increase the batch size and scale the model to better utilize GPUs and get higher throughput. Note that increasing the batch size will change the model's accuracy so the model needs to be scaled by tuning hyperparameters like the learning rate to meet the target accuracy.

Also, use tf.config.experimental.set_memory_growth to allow GPU memory to grow to prevent all the available memory from being fully allocated to ops that require only a fraction of the memory. This allows other processes which consume GPU memory to run on the same device.

To learn more, check out the Limiting GPU memory growth guidance in the GPU guide to learn more.

Miscellaneous

  • Increase the training mini-batch size (number of training samples used per device in one iteration of the training loop) to the maximum amount that fits without an out of memory (OOM) error on the GPU. Increasing the batch size impacts the model's accuracy—so make sure you scale the model by tuning hyperparameters to meet the target accuracy.

  • Disable reporting OOM errors during tensor allocation in production code. Set report_tensor_allocations_upon_oom=False in tf.compat.v1.RunOptions .

  • For models with convolution layers, remove bias addition if using batch normalization. Batch normalization shifts values by their mean and this removes the need to have a constant bias term.

  • Use TF Stats to find out how efficiently on-device ops run.

  • Use tf.function to perform computations and optionally, enable the jit_compile=True flag ( tf.function(jit_compile=True ). To learn more, go to Use XLA tf.function .

  • Minimize host Python operations between steps and reduce callbacks. Calculate metrics every few steps instead of at every step.

  • Keep the device compute units busy.

  • Send data to multiple devices in parallel.

  • Consider using 16-bit numerical representations , such as fp16 —the half-precision floating point format specified by IEEE—or the Brain floating-point bfloat16 format.

Additional resources

Known limitations

Profiling multiple GPUs on TensorFlow 2.2 and TensorFlow 2.3

TensorFlow 2.2 and 2.3 support multiple GPU profiling for single host systems only; multiple GPU profiling for multi-host systems is not supported. To profile multi-worker GPU configurations, each worker has to be profiled independently. From TensorFlow 2.4 multiple workers can be profiled using the tf.profiler.experimental.client.trace API.

CUDA® Toolkit 10.2 or later is required to profile multiple GPUs. As TensorFlow 2.2 and 2.3 support CUDA® Toolkit versions only up to 10.1, you need to create symbolic links to libcudart.so.10.1 and libcupti.so.10.1 :

sudo ln -s /usr/local/cuda/lib64/libcudart.so.10.2 /usr/local/cuda/lib64/libcudart.so.10.1
sudo ln -s /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.2 /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.1