Делегаты GPU для TensorFlow Lite

Использование графических процессоров (GPU) для запуска моделей машинного обучения (ML) может значительно повысить производительность вашей модели и удобство работы пользователей с приложениями с поддержкой ML. TensorFlow Lite позволяет использовать графические процессоры и другие специализированные процессоры с помощью аппаратного драйвера, называемого делегатами . Включение использования графических процессоров с вашими приложениями машинного обучения TensorFlow Lite может дать следующие преимущества:

  • Скорость . Графические процессоры рассчитаны на высокую пропускную способность массовых параллельных рабочих нагрузок. Такой дизайн делает их хорошо подходящими для глубоких нейронных сетей, которые состоят из огромного количества операторов, каждый из которых работает с входными тензорами, которые могут обрабатываться параллельно, что обычно приводит к меньшей задержке. В лучшем случае запуск вашей модели на графическом процессоре может выполняться достаточно быстро, чтобы включить приложения в реальном времени, которые ранее были невозможны.
  • Энергоэффективность — графические процессоры выполняют вычисления машинного обучения очень эффективным и оптимизированным образом, обычно потребляя меньше энергии и выделяя меньше тепла, чем та же задача, выполняемая на ЦП.

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

Поддержка операций GPU ML

Существуют некоторые ограничения на то, какие операции TensorFlow ML, или ops , могут быть ускорены делегатом графического процессора TensorFlow Lite. Делегат поддерживает следующие операции с 16-битной и 32-битной точностью с плавающей запятой:

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGISTIC
  • LSTM v2 (Basic LSTM only)
  • MAX_POOL_2D
  • MAXIMUM
  • MINIMUM
  • MUL
  • PAD
  • PRELU
  • RELU
  • RELU6
  • RESHAPE
  • RESIZE_BILINEAR v1-3
  • SOFTMAX
  • STRIDED_SLICE
  • SUB
  • TRANSPOSE_CONV

По умолчанию все операции поддерживаются только в версии 1. Включение поддержки квантования включает соответствующие версии, например, ADD v2.

Устранение неполадок с поддержкой графического процессора

Если некоторые из операций не поддерживаются делегатом графического процессора, фреймворк будет запускать только часть графа на графическом процессоре, а оставшуюся часть — на ЦП. Из-за высокой стоимости синхронизации ЦП/ГП такой раздельный режим выполнения часто приводит к более низкой производительности, чем когда вся сеть работает только на ЦП. В этом случае приложение выдает предупреждение, например:

WARNING: op code #42 cannot be handled by this delegate.

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

Примеры моделей

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

Оптимизация для графических процессоров

Следующие методы могут помочь вам повысить производительность при запуске моделей на оборудовании графического процессора с использованием делегата графического процессора TensorFlow Lite:

  • Операции изменения формы . Некоторые операции, которые выполняются быстро на ЦП, могут иметь высокую стоимость для графического процессора на мобильных устройствах. Операции изменения формы особенно затратны для выполнения, включая BATCH_TO_SPACE , SPACE_TO_BATCH , SPACE_TO_DEPTH и так далее. Вы должны внимательно изучить использование операций изменения формы и учесть, что они могли применяться только для изучения данных или для ранних итераций вашей модели. Их удаление может значительно повысить производительность.

  • Каналы данных изображения . В графическом процессоре тензорные данные разбиваются на 4 канала, поэтому вычисление тензора формы [B,H,W,5] выполняется примерно так же для тензора формы [B,H,W,8] , но значительно хуже, чем [B,H,W,4] . Если аппаратное обеспечение камеры, которое вы используете, поддерживает кадры изображения в формате RGBA, подача на этот 4-канальный вход будет значительно быстрее, поскольку при этом не будет копироваться память из 3-канального RGB в 4-канальный RGBX.

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

Расширенная поддержка графического процессора

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

Использование квантованных моделей

В этом разделе объясняется, как делегат GPU ускоряет 8-битные квантованные модели, включая следующие:

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

Как это работает?

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

  • Постоянные тензоры (такие как веса/смещения) деквантуются один раз в память графического процессора. Эта операция происходит, когда делегат включен для TensorFlow Lite.

  • Входные и выходные данные для программы графического процессора, если они квантуются 8 битами, деквантуются и квантуются (соответственно) для каждого вывода. Эта операция выполняется на ЦП с использованием оптимизированных ядер TensorFlow Lite.

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

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

Сокращение времени инициализации с сериализацией

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

С++

    TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
    options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
    options.serialization_dir = kTmpDir;
    options.model_token = kModelToken;

    auto* delegate = TfLiteGpuDelegateV2Create(options);
    if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

Ява

    GpuDelegate delegate = new GpuDelegate(
      new GpuDelegate.Options().setSerializationParams(
        /* serializationDir= */ serializationDir,
        /* modelToken= */ modelToken));

    Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
      

При использовании функции сериализации убедитесь, что ваш код соответствует этим правилам реализации:

  • Храните данные сериализации в каталоге, недоступном для других приложений. На устройствах Android используйте getCodeCacheDir() , который указывает на расположение, которое является частным для текущего приложения.
  • Маркер модели должен быть уникальным для устройства конкретной модели. Вы можете вычислить токен модели, сгенерировав отпечаток пальца из данных модели, используя такие библиотеки, как farmhash::Fingerprint64 .