TensorFlow Lite поддерживает несколько аппаратных ускорителей. В этом документе описывается, как использовать серверную часть графического процессора с помощью API-интерфейсов делегата TensorFlow Lite на Android и iOS.
Графические процессоры предназначены для обеспечения высокой пропускной способности для массово распараллеливаемых рабочих нагрузок. Таким образом, они хорошо подходят для глубоких нейронных сетей, которые состоят из огромного количества операторов, каждый из которых работает с некоторым входным тензором (-ами), которые можно легко разделить на меньшие рабочие нагрузки и выполнять параллельно, что обычно приводит к меньшей задержке. В лучшем случае логический вывод на графическом процессоре теперь может выполняться достаточно быстро для ранее недоступных приложений реального времени.
В отличие от ЦП, графические процессоры выполняют вычисления с 16-битными или 32-битными числами с плавающей запятой и не требуют квантования для оптимальной производительности. Делегат действительно принимает 8-битные квантованные модели, но вычисление будет выполняться в числах с плавающей запятой. Обратитесь к расширенному документации для деталей.
Еще одним преимуществом вывода графического процессора является его энергоэффективность. Графические процессоры выполняют вычисления очень эффективным и оптимизированным образом, поэтому они потребляют меньше энергии и выделяют меньше тепла, чем при выполнении той же задачи на процессорах.
Учебные пособия по демонстрационному приложению
Самый простой способ опробовать делегат GPU - это следовать приведенным ниже руководствам, в которых рассказывается о создании наших демонстрационных классификационных приложений с поддержкой GPU. Код GPU пока только двоичный; в ближайшее время он будет открыт с открытым исходным кодом. Как только вы поймете, как заставить наши демонстрации работать, вы можете попробовать это на своих собственных моделях.
Android (с Android Studio)
Для учебника шаг за шагом, смотреть GPU Делегат для Android видео.
Шаг 1. Клонируйте исходный код TensorFlow и откройте его в Android Studio.
git clone https://github.com/tensorflow/tensorflow
Шаг 2. Изменить app/build.gradle
использовать каждую ночь GPU AAR
Добавьте tensorflow-lite-gpu
пакет наряду с существующим tensorflow-lite
пакета в существующих dependencies
блока.
dependencies {
...
implementation 'org.tensorflow:tensorflow-lite:2.3.0'
implementation 'org.tensorflow:tensorflow-lite-gpu:2.3.0'
}
Шаг 3. Сборка и запуск
Выполнить → Запустить приложение. Когда вы запустите приложение, вы увидите кнопку для включения графического процессора. Измените квантованную модель на модель с плавающей запятой, а затем щелкните GPU, чтобы запустить на GPU.
iOS (с XCode)
Для учебника шаг за шагом, смотрите GPU делегатом для IOS видео.
Шаг 1. Получите исходный код демонстрации и убедитесь, что он компилируется.
Следуйте нашим IOS Demo App учебник . Это приведет вас к тому моменту, когда на вашем телефоне будет работать немодифицированная демоверсия камеры iOS.
Шаг 2. Измените Podfile, чтобы использовать CocoaPod с графическим процессором TensorFlow Lite.
Начиная с версии 2.3.0, по умолчанию делегат графического процессора исключается из модуля, чтобы уменьшить двоичный размер. Вы можете включить их, указав подспецификацию. Для TensorFlowLiteSwift
стручка:
pod 'TensorFlowLiteSwift/Metal', '~> 0.0.1-nightly',
ИЛИ
pod 'TensorFlowLiteSwift', '~> 0.0.1-nightly', :subspecs => ['Metal']
Вы можете сделать так же для TensorFlowLiteObjC
или TensorFlowLitC
, если вы хотите использовать Objective-C (от 2.4.0 выпуска) или C API.
До выпуска 2.3.0
До TensorFlow Lite 2.0.0
Мы создали двоичный CocoaPod, который включает делегат GPU. Чтобы переключить проект на его использование, измените файл `tensorflow / tensorflow / lite / examples / ios / camera / Podfile`, чтобы использовать модуль` TensorFlowLiteGpuExperimental` вместо `TensorFlowLite`.
target 'YourProjectName'
# pod 'TensorFlowLite', '1.12.0'
pod 'TensorFlowLiteGpuExperimental'
До версии TensorFlow Lite 2.2.0
Начиная с TensorFlow Lite 2.1.0 и до 2.2.0, делегат GPU включен в модуль TensorFlowLiteC. Вы можете выбирать между «TensorFlowLiteC» и «TensorFlowLiteSwift» в зависимости от языка.
Шаг 3. Включите делегат GPU
Для того, чтобы включить код , который будет использовать GPU делегата, вам нужно будет изменить TFLITE_USE_GPU_DELEGATE
от 0 до 1 в CameraExampleViewController.h
.
#define TFLITE_USE_GPU_DELEGATE 1
Шаг 4. Создайте и запустите демонстрационное приложение.
Выполнив предыдущий шаг, вы сможете запустить приложение.
Шаг 5. Режим выпуска
На шаге 4 вы работали в режиме отладки, чтобы повысить производительность, вам следует перейти на сборку выпуска с соответствующими оптимальными настройками Metal. В частности, изменить эти настройки перейдите к Product > Scheme > Edit Scheme...
. Выберите Run
. На Info
вкладке Изменение Build Configuration
с Debug
на Release
, снимите флажок Debug executable
.
Затем щелкните Options
вкладку и изменить GPU Frame Capture
для Disabled
и Metal API Validation
на Disabled
.
Наконец, не забудьте выбрать сборки только для выпуска на 64-разрядной архитектуре. Под Project navigator -> tflite_camera_example -> PROJECT -> tflite_camera_example -> Build Settings
набор Build Active Architecture Only > Release
Да.
Пробуем делегат графического процессора на вашей собственной модели
Android
Есть два способа запуска модели ускорения в зависимости от того, если вы используете Android Studio ML Model Binding или TensorFlow Lite интерпретатора.
Интерпретатор TensorFlow Lite
Посмотрите демонстрацию, чтобы узнать, как добавить делегата. В приложении, добавьте AAR , как указано выше, импорт org.tensorflow.lite.gpu.GpuDelegate
модуля и использовать addDelegate
функцию , чтобы зарегистрировать GPU делегатом на переводчика:
Котлин
import org.tensorflow.lite.Interpreter import org.tensorflow.lite.gpu.CompatibilityList import org.tensorflow.lite.gpu.GpuDelegate val compatList = CompatibilityList() val options = Interpreter.Options().apply{ if(compatList.isDelegateSupportedOnThisDevice){ // if the device has a supported GPU, add the GPU delegate val delegateOptions = compatList.bestOptionsForThisDevice this.addDelegate(GpuDelegate(delegateOptions)) } else { // if the GPU is not supported, run on 4 threads this.setNumThreads(4) } } val interpreter = Interpreter(model, options) // Run inference writeToInput(input) interpreter.run(input, output) readFromOutput(output)
Джава
import org.tensorflow.lite.Interpreter; import org.tensorflow.lite.gpu.CompatibilityList; import org.tensorflow.lite.gpu.GpuDelegate; // Initialize interpreter with GPU delegate Interpreter.Options options = new Interpreter.Options(); CompatibilityList compatList = CompatibilityList(); if(compatList.isDelegateSupportedOnThisDevice()){ // if the device has a supported GPU, add the GPU delegate GpuDelegate.Options delegateOptions = compatList.getBestOptionsForThisDevice(); GpuDelegate gpuDelegate = new GpuDelegate(delegateOptions); options.addDelegate(gpuDelegate); } else { // if the GPU is not supported, run on 4 threads options.setNumThreads(4); } Interpreter interpreter = new Interpreter(model, options); // Run inference writeToInput(input); interpreter.run(input, output); readFromOutput(output);
iOS
Быстрый
import TensorFlowLite // Load model ... // Initialize TensorFlow Lite interpreter with the GPU delegate. let delegate = MetalDelegate() if let interpreter = try Interpreter(modelPath: modelPath, delegates: [delegate]) { // Run inference ... }
Цель-C
// Import module when using CocoaPods with module support @import TFLTensorFlowLite; // Or import following headers manually #import "tensorflow/lite/objc/apis/TFLMetalDelegate.h" #import "tensorflow/lite/objc/apis/TFLTensorFlowLite.h" // Initialize GPU delegate TFLMetalDelegate* metalDelegate = [[TFLMetalDelegate alloc] init]; // Initialize interpreter with model path and GPU delegate TFLInterpreterOptions* options = [[TFLInterpreterOptions alloc] init]; NSError* error = nil; TFLInterpreter* interpreter = [[TFLInterpreter alloc] initWithModelPath:modelPath options:options delegates:@[ metalDelegate ] error:&error]; if (error != nil) { /* Error handling... */ } if (![interpreter allocateTensorsWithError:&error]) { /* Error handling... */ } if (error != nil) { /* Error handling... */ } // Run inference ... ```
C (до 2.3.0)
#include "tensorflow/lite/c/c_api.h" #include "tensorflow/lite/delegates/gpu/metal_delegate.h" // Initialize model TfLiteModel* model = TfLiteModelCreateFromFile(model_path); // Initialize interpreter with GPU delegate TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate(); TfLiteDelegate* delegate = TFLGPUDelegateCreate(nil); // default config TfLiteInterpreterOptionsAddDelegate(options, metal_delegate); TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options); TfLiteInterpreterOptionsDelete(options); TfLiteInterpreterAllocateTensors(interpreter); NSMutableData *input_data = [NSMutableData dataWithLength:input_size * sizeof(float)]; NSMutableData *output_data = [NSMutableData dataWithLength:output_size * sizeof(float)]; TfLiteTensor* input = TfLiteInterpreterGetInputTensor(interpreter, 0); const TfLiteTensor* output = TfLiteInterpreterGetOutputTensor(interpreter, 0); // Run inference TfLiteTensorCopyFromBuffer(input, inputData.bytes, inputData.length); TfLiteInterpreterInvoke(interpreter); TfLiteTensorCopyToBuffer(output, outputData.mutableBytes, outputData.length); // Clean up TfLiteInterpreterDelete(interpreter); TFLGpuDelegateDelete(metal_delegate); TfLiteModelDelete(model);
## Supported Models and Ops
With the release of the GPU delegate, we included a handful of models that can
be run on the backend:
* [MobileNet v1 (224x224) image classification](https://ai.googleblog.com/2017/06/mobilenets-open-source-models-for.html) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/mobilenet_v1_1.0_224.tflite)
<br /><i>(image classification model designed for mobile and embedded based vision applications)</i>
* [DeepLab segmentation (257x257)](https://ai.googleblog.com/2018/03/semantic-image-segmentation-with.html) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/deeplabv3_257_mv_gpu.tflite)
<br /><i>(image segmentation model that assigns semantic labels (e.g., dog, cat, car) to every pixel in the input image)</i>
* [MobileNet SSD object detection](https://ai.googleblog.com/2018/07/accelerated-training-and-inference-with.html) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/mobile_ssd_v2_float_coco.tflite)
<br /><i>(image classification model that detects multiple objects with bounding boxes)</i>
* [PoseNet for pose estimation](https://github.com/tensorflow/tfjs-models/tree/master/posenet) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/multi_person_mobilenet_v1_075_float.tflite)
<br /><i>(vision model that estimates the poses of a person(s) in image or video)</i>
To see a full list of supported ops, please see the
[advanced documentation](gpu_advanced).
## Non-supported models and ops
If some of the ops are not supported by the GPU delegate, the framework will
only run a part of the graph on the GPU and the remaining part on the CPU. Due
to the high cost of CPU/GPU synchronization, a split execution mode like this
will often result in slower performance than when the whole network is run on
the CPU alone. In this case, the user will get a warning like:
```none
WARNING: op code #42 cannot be handled by this delegate.
```
Мы не обеспечивали обратный вызов для этого сбоя, так как это не настоящий сбой времени выполнения, а то, что разработчик может наблюдать, пытаясь заставить сеть работать на делегате.
Советы по оптимизации
Оптимизация под мобильные устройства
Некоторые тривиальные операции с центральным процессором могут дорого обходиться графическому процессору на мобильных устройствах. Операции переформовать особенно дорого для запуска, в том числе 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).
Для достижения наилучшей производительности вам следует подумать о переобучении классификатора с помощью сетевой архитектуры, оптимизированной для мобильных устройств. Оптимизация логических выводов на устройстве может значительно снизить задержку и энергопотребление за счет использования преимуществ мобильного оборудования.
Сокращение времени инициализации с помощью сериализации
Функция делегирования графического процессора позволяет загружать из предварительно скомпилированного кода ядра и сериализованные и сохраненные на диске данные модели из предыдущих запусков. Такой подход позволяет избежать повторной компиляции и сокращает время запуска до 90%. Инструкции о том , как применять сериализации в проект, см GPU Делегирование сериализации .