Attend the Women in ML Symposium on December 7 Register now

Delegados de GPU para TensorFlow Lite

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

El uso de unidades de procesamiento de gráficos (GPU) para ejecutar sus modelos de aprendizaje automático (ML) puede mejorar drásticamente el rendimiento de su modelo y la experiencia del usuario de sus aplicaciones habilitadas para ML. TensorFlow Lite permite el uso de GPU y otros procesadores especializados a través de controladores de hardware llamados delegados . Habilitar el uso de GPU con sus aplicaciones TensorFlow Lite ML puede proporcionar los siguientes beneficios:

  • Velocidad : las GPU están diseñadas para un alto rendimiento de cargas de trabajo paralelas masivas. Este diseño los hace muy adecuados para redes neuronales profundas, que consisten en una gran cantidad de operadores, cada uno de los cuales trabaja en tensores de entrada que se pueden procesar en paralelo, lo que generalmente resulta en una latencia más baja. En el mejor de los casos, ejecutar su modelo en una GPU puede funcionar lo suficientemente rápido como para habilitar aplicaciones en tiempo real que antes no eran posibles.
  • Eficiencia energética : las GPU realizan cálculos de ML de una manera muy eficiente y optimizada, por lo general, consumen menos energía y generan menos calor que la misma tarea que se ejecuta en las CPU.

Este documento proporciona una descripción general de la compatibilidad con GPU en TensorFlow Lite y algunos usos avanzados de los procesadores de GPU. Para obtener información más específica sobre la implementación de la compatibilidad con GPU en plataformas específicas, consulte las siguientes guías:

Compatibilidad con operaciones GPU ML

Existen algunas limitaciones en cuanto a qué operaciones de aprendizaje automático de TensorFlow, u ops , pueden ser aceleradas por el delegado de GPU de TensorFlow Lite. El delegado admite las siguientes operaciones con precisión flotante de 16 y 32 bits:

  • 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

De forma predeterminada, todas las operaciones solo se admiten en la versión 1. Habilitar el soporte de cuantificación habilita las versiones apropiadas, por ejemplo, ADD v2.

Solución de problemas de compatibilidad con GPU

Si el delegado de GPU no admite algunas de las operaciones, el marco solo ejecutará una parte del gráfico en la GPU y la parte restante en la CPU. Debido al alto costo de la sincronización de CPU/GPU, un modo de ejecución dividida como este a menudo resulta en un rendimiento más lento que cuando toda la red se ejecuta solo en la CPU. En este caso, la aplicación genera una advertencia, como por ejemplo:

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

No hay devolución de llamada para fallas de este tipo, ya que no se trata de una falla real en tiempo de ejecución. Al probar la ejecución de su modelo con el delegado de GPU, debe estar alerta a estas advertencias. Un gran número de estas advertencias puede indicar que su modelo no es el más adecuado para usar con aceleración de GPU y puede requerir una refactorización del modelo.

Modelos de ejemplo

Los siguientes modelos de ejemplo están diseñados para aprovechar la aceleración de GPU con TensorFlow Lite y se proporcionan como referencia y prueba:

Optimización para GPU

Las siguientes técnicas pueden ayudarlo a obtener un mejor rendimiento al ejecutar modelos en hardware de GPU con el delegado de GPU de TensorFlow Lite:

  • Operaciones de remodelación: algunas operaciones que son rápidas en una CPU pueden tener un alto costo para la GPU en dispositivos móviles. Las operaciones de remodelación son particularmente costosas de ejecutar, incluidas BATCH_TO_SPACE , SPACE_TO_BATCH , SPACE_TO_DEPTH , etc. Debe examinar detenidamente el uso de las operaciones de remodelación y considerar que pueden haberse aplicado solo para explorar datos o para las primeras iteraciones de su modelo. Eliminarlos puede mejorar significativamente el rendimiento.

  • Canales de datos de imagen : en la GPU, los datos del tensor se dividen en 4 canales, por lo que un cálculo en un tensor con la forma [B,H,W,5] se realiza casi igual en un tensor con la forma [B,H,W,8] , pero significativamente peor que [B,H,W,4] . Si el hardware de la cámara que está utilizando admite marcos de imagen en RGBA, alimentar esa entrada de 4 canales es significativamente más rápido, ya que evita una copia de memoria de RGB de 3 canales a RGBX de 4 canales.

  • Modelos optimizados para dispositivos móviles : para obtener el mejor rendimiento, debe considerar volver a capacitar a su clasificador con una arquitectura de red optimizada para dispositivos móviles. La optimización para la inferencia en el dispositivo puede reducir drásticamente la latencia y el consumo de energía al aprovechar las características del hardware móvil.

Compatibilidad con GPU avanzada

Puede usar técnicas avanzadas adicionales con el procesamiento de GPU para permitir un rendimiento aún mejor para sus modelos, incluidas la cuantificación y la serialización. Las siguientes secciones describen estas técnicas con más detalle.

Uso de modelos cuantificados

Esta sección explica cómo el delegado de GPU acelera los modelos cuantificados de 8 bits, incluidos los siguientes:

Para optimizar el rendimiento, utilice modelos que tengan tensores de entrada y salida de punto flotante.

¿Como funciona esto?

Dado que el backend de GPU solo admite la ejecución de punto flotante, ejecutamos modelos cuantificados dándole una "vista de punto flotante" del modelo original. A un alto nivel, esto implica los siguientes pasos:

  • Los tensores constantes (como pesos/sesgos) se descuantifican una vez en la memoria de la GPU. Esta operación ocurre cuando el delegado está habilitado para TensorFlow Lite.

  • Las entradas y salidas al programa GPU, si se cuantifican en 8 bits, se descuantifican y cuantifican (respectivamente) para cada inferencia. Esta operación se realiza en la CPU utilizando los núcleos optimizados de TensorFlow Lite.

  • Los simuladores de cuantificación se insertan entre operaciones para imitar el comportamiento cuantificado. Este enfoque es necesario para los modelos en los que los operadores esperan que las activaciones sigan los límites aprendidos durante la cuantificación.

Para obtener información sobre cómo habilitar esta función con el delegado de GPU, consulte lo siguiente:

Reducción del tiempo de inicialización con serialización

La función de delegado de GPU le permite cargar desde el código del kernel precompilado y los datos del modelo serializados y guardados en el disco de ejecuciones anteriores. Este enfoque evita la recompilación y puede reducir el tiempo de inicio hasta en un 90 %. Esta mejora se logra intercambiando espacio en disco por ahorro de tiempo. Puede habilitar esta función con algunas opciones de configuración, como se muestra en los siguientes ejemplos de código:

C++

    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;
      

Java

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

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

Cuando utilice la característica de serialización, asegúrese de que su código cumpla con estas reglas de implementación:

  • Almacene los datos de serialización en un directorio al que no puedan acceder otras aplicaciones. En dispositivos Android, use getCodeCacheDir() que apunta a una ubicación que es privada para la aplicación actual.
  • El token del modelo debe ser exclusivo del dispositivo para el modelo específico. Puede calcular un token de modelo generando una huella digital a partir de los datos del modelo mediante bibliotecas como farmhash::Fingerprint64 .