Делегаты графического процессора для LiteRT

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

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

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

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

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

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGICAL_AND
  • 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.

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

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

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

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

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

Следующие примеры моделей созданы для использования возможностей ускорения GPU с помощью LiteRT и предоставлены для справки и тестирования:

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

Следующие методы помогут вам повысить производительность при запуске моделей на оборудовании GPU с использованием делегата LiteRT GPU:

  • Операции изменения формы — некоторые операции, быстро выполняемые центральным процессором, могут иметь высокую нагрузку на графический процессор мобильных устройств. Операции изменения формы особенно затратны, включая 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-битные квантованные модели, включая следующее:

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

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

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

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

  • Входные и выходные данные программы GPU, если они квантованы 8-битно, деквантуются и квантуются (соответственно) для каждого вывода. Эта операция выполняется на центральном процессоре с использованием оптимизированных ядер LiteRT.

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

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

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

Функция делегата GPU позволяет загружать данные из предварительно скомпилированного кода ядра и модели, сериализованные и сохранённые на диске из предыдущих запусков. Такой подход позволяет избежать повторной компиляции и может сократить время запуска до 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 .