Selecciona operadores de TensorFlow

Dado que la biblioteca de operadores integrados de LiteRT solo admite una cantidad limitada de operadores de TensorFlow, no todos los modelos se pueden convertir. Para obtener más detalles, consulta la compatibilidad con operadores.

Para permitir la conversión, los usuarios pueden habilitar el uso de ciertas operaciones de TensorFlow en su modelo de LiteRT. Sin embargo, ejecutar modelos de LiteRT con operaciones de TensorFlow requiere incorporar el tiempo de ejecución principal de TensorFlow, lo que aumenta el tamaño del objeto binario del intérprete de LiteRT. En Android, puedes evitar esto compilando de forma selectiva solo las operaciones de TensorFlow necesarias. Para obtener más detalles, consulta cómo reducir el tamaño del binario.

En este documento, se describe cómo convertir y ejecutar un modelo de LiteRT que contiene operaciones de TensorFlow en la plataforma que elijas. También se analizan las métricas de rendimiento y tamaño, y las limitaciones conocidas.

Cómo convertir un modelo

En el siguiente ejemplo, se muestra cómo generar un modelo de LiteRT con operaciones de TensorFlow seleccionadas.

import tensorflow as tf

converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.target_spec.supported_ops = [
  tf.lite.OpsSet.TFLITE_BUILTINS, # enable LiteRT ops.
  tf.lite.OpsSet.SELECT_TF_OPS # enable TensorFlow ops.
]
tflite_model = converter.convert()
open("converted_model.tflite", "wb").write(tflite_model)

Ejecuta la inferencia

Cuando se usa un modelo de LiteRT que se convirtió con compatibilidad para operaciones de TensorFlow seleccionadas, el cliente también debe usar un entorno de ejecución de LiteRT que incluya la biblioteca necesaria de operaciones de TensorFlow.

AAR de Android

Para reducir el tamaño del objeto binario, compila tus propios archivos AAR personalizados como se indica en la siguiente sección. Si el tamaño del objeto binario no es una preocupación considerable, te recomendamos que uses el AAR prediseñado con operaciones de TensorFlow alojado en MavenCentral.

Puedes especificarlo en tus dependencias de build.gradle agregándolo junto con el AAR de LiteRT estándar de la siguiente manera:

dependencies {
    implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly-SNAPSHOT'
    // This dependency adds the necessary TF op support.
    implementation 'org.tensorflow:tensorflow-lite-select-tf-ops:0.0.0-nightly-SNAPSHOT'
}

Para usar instantáneas nocturnas, asegúrate de haber agregado el repositorio de instantáneas de Sonatype.

Una vez que agregues la dependencia, se instalará automáticamente el delegado necesario para controlar las operaciones de TensorFlow del grafo en los grafos que lo requieran.

Nota: La dependencia de las operaciones de TensorFlow es relativamente grande, por lo que probablemente querrás filtrar las ABIs x86 innecesarias en tu archivo .gradle configurando tu abiFilters.

android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a'
        }
    }
}

Cómo compilar el AAR de Android

Para reducir el tamaño del binario o en otros casos avanzados, también puedes compilar la biblioteca de forma manual. Suponiendo que tienes un entorno de compilación de LiteRT que funciona, compila el AAR de Android con las operaciones de TensorFlow seleccionadas de la siguiente manera:

sh tensorflow/lite/tools/build_aar.sh \
  --input_models=/a/b/model_one.tflite,/c/d/model_two.tflite \
  --target_archs=x86,x86_64,arm64-v8a,armeabi-v7a

Esto generará el archivo AAR bazel-bin/tmp/tensorflow-lite.aar para las operaciones integradas y personalizadas de LiteRT, y generará el archivo AAR bazel-bin/tmp/tensorflow-lite-select-tf-ops.aar para las operaciones de TensorFlow. Si no tienes un entorno de compilación que funcione, también puedes compilar los archivos anteriores con Docker.

Desde allí, puedes importar los archivos AAR directamente a tu proyecto o publicar los archivos AAR personalizados en tu repositorio local de Maven:

mvn install:install-file \
  -Dfile=bazel-bin/tmp/tensorflow-lite.aar \
  -DgroupId=org.tensorflow \
  -DartifactId=tensorflow-lite -Dversion=0.1.100 -Dpackaging=aar
mvn install:install-file \
  -Dfile=bazel-bin/tmp/tensorflow-lite-select-tf-ops.aar \
  -DgroupId=org.tensorflow \
  -DartifactId=tensorflow-lite-select-tf-ops -Dversion=0.1.100 -Dpackaging=aar

Por último, en el build.gradle de tu app, asegúrate de tener la dependencia mavenLocal() y reemplaza la dependencia estándar de LiteRT por la que admite operaciones de TensorFlow seleccionadas:

allprojects {
    repositories {
        mavenCentral()
        maven {  // Only for snapshot artifacts
            name 'ossrh-snapshot'
            url 'https://oss.sonatype.org/content/repositories/snapshots'
        }
        mavenLocal()
    }
}

dependencies {
    implementation 'org.tensorflow:tensorflow-lite:0.1.100'
    implementation 'org.tensorflow:tensorflow-lite-select-tf-ops:0.1.100'
}

iOS

Uso de CocoaPods

LiteRT proporciona CocoaPods precompilados de operaciones de TF seleccionadas para arm64, de los que puedes depender junto con los CocoaPods TensorFlowLiteSwift o TensorFlowLiteObjC.

Nota: Si necesitas usar operaciones de TF seleccionadas en un simulador de x86_64, puedes compilar el framework de operaciones seleccionadas por tu cuenta. Consulta la sección Cómo usar Bazel y Xcode para obtener más detalles.

# In your Podfile target:
  pod 'TensorFlowLiteSwift'   # or 'TensorFlowLiteObjC'
  pod 'TensorFlowLiteSelectTfOps', '~> 0.0.1-nightly'

Después de ejecutar pod install, debes proporcionar una marca de vinculador adicional para forzar la carga del framework de operaciones de TF seleccionado en tu proyecto. En tu proyecto de Xcode, ve a Build Settings -> Other Linker Flags y agrega lo siguiente:

Para versiones >= 2.9.0, haz lo siguiente:

-force_load $(SRCROOT)/Pods/TensorFlowLiteSelectTfOps/Frameworks/TensorFlowLiteSelectTfOps.xcframework/ios-arm64/TensorFlowLiteSelectTfOps.framework/TensorFlowLiteSelectTfOps

Para versiones anteriores a la 2.9.0, haz lo siguiente:

-force_load $(SRCROOT)/Pods/TensorFlowLiteSelectTfOps/Frameworks/TensorFlowLiteSelectTfOps.framework/TensorFlowLiteSelectTfOps

Luego, podrás ejecutar cualquier modelo convertido con SELECT_TF_OPS en tu app para iOS. Por ejemplo, puedes modificar la app para iOS de clasificación de imágenes para probar la función de operaciones de TF seleccionadas.

  • Reemplaza el archivo del modelo por el que se convirtió con SELECT_TF_OPS habilitado.
  • Agrega la dependencia TensorFlowLiteSelectTfOps a Podfile según las instrucciones.
  • Agrega el parámetro de vinculador adicional como se indicó anteriormente.
  • Ejecuta la app de ejemplo y comprueba si el modelo funciona correctamente.

Cómo usar Bazel y Xcode

LiteRT con operaciones de TensorFlow seleccionadas para iOS se puede compilar con Bazel. Primero, sigue las instrucciones de compilación para iOS para configurar correctamente tu espacio de trabajo de Bazel y el archivo .bazelrc.

Una vez que hayas configurado el espacio de trabajo con la compatibilidad con iOS habilitada, puedes usar el siguiente comando para compilar el framework de complementos de las operaciones de TF seleccionadas, que se puede agregar sobre el TensorFlowLiteC.framework normal. Ten en cuenta que el framework de operaciones de TF seleccionado no se puede compilar para la arquitectura i386, por lo que debes proporcionar de forma explícita la lista de arquitecturas de destino, sin incluir i386.

bazel build -c opt --config=ios --ios_multi_cpus=arm64,x86_64 \
  //tensorflow/lite/ios:TensorFlowLiteSelectTfOps_framework

Esto generará el framework en el directorio bazel-bin/tensorflow/lite/ios/. Para agregar este nuevo framework a tu proyecto de Xcode, sigue los pasos similares que se describen en la sección Configuración del proyecto de Xcode de la guía de compilación para iOS.

Después de agregar el framework al proyecto de tu app, se debe especificar un parámetro de vinculador adicional en el proyecto de tu app para forzar la carga del framework de operaciones de TF seleccionado. En tu proyecto de Xcode, ve a Build Settings -> Other Linker Flags y agrega lo siguiente:

-force_load <path/to/your/TensorFlowLiteSelectTfOps.framework/TensorFlowLiteSelectTfOps>

C/C++

Si usas Bazel o CMake para compilar el intérprete de LiteRT, puedes habilitar el delegado de Flex vinculando una biblioteca compartida del delegado de Flex de LiteRT. Puedes compilarlo con Bazel con el siguiente comando.

bazel build -c opt --config=monolithic tensorflow/lite/delegates/flex:tensorflowlite_flex

Este comando genera la siguiente biblioteca compartida en bazel-bin/tensorflow/lite/delegates/flex.

Plataforma Nombre de la biblioteca
Linux libtensorflowlite_flex.so
macOS libtensorflowlite_flex.dylib
Windows tensorflowlite_flex.dll

Ten en cuenta que el TfLiteDelegate necesario se instalará automáticamente cuando se cree el intérprete en el tiempo de ejecución, siempre y cuando se vincule la biblioteca compartida. No es necesario instalar de forma explícita la instancia del delegado, como suele ser necesario con otros tipos de delegados.

Nota: Esta función está disponible desde la versión 2.7.

Python

LiteRT con operaciones de TensorFlow seleccionadas se instalará automáticamente con el paquete pip de TensorFlow. También puedes optar por instalar solo el paquete pip del intérprete de LiteRT.

Métricas

Rendimiento

Cuando se usa una combinación de operaciones integradas y seleccionadas de TensorFlow, todas las optimizaciones de LiteRT y las operaciones integradas optimizadas estarán disponibles y se podrán usar con el modelo convertido.

En la siguiente tabla, se describe el tiempo promedio que se tarda en ejecutar la inferencia en MobileNet en un Pixel 2. Los tiempos indicados son un promedio de 100 ejecuciones. Estos destinos se compilaron para Android con las marcas: --config=android_arm64 -c opt.

Compilación Tiempo (milisegundos)
Solo operaciones integradas (TFLITE_BUILTIN) 260.7
Usar solo operaciones de TF (SELECT_TF_OPS) 264.5

Tamaño de los objetos binarios

En la siguiente tabla, se describe el tamaño del binario de LiteRT para cada compilación. Estos destinos se compilaron para Android con --config=android_arm -c opt.

Compilación Tamaño del objeto binario de C++ Tamaño del APK de Android
Solo operaciones integradas 796 KB 561 KB
Operaciones integradas y operaciones de TF 23.0 MB 8.0 MB
Operaciones integradas y operaciones de TF (1) 4.1 MB 1.8 MB

(1) Estas bibliotecas se compilan de forma selectiva para el modelo i3d-kinetics-400 con 8 operaciones integradas de TFLite y 3 operaciones de TensorFlow. Para obtener más detalles, consulta la sección Reduce el tamaño del binario de LiteRT.

Limitaciones conocidas

  • Tipos no admitidos: Es posible que algunas operaciones de TensorFlow no admitan el conjunto completo de tipos de entrada/salida que suelen estar disponibles en TensorFlow.

Actualizaciones

  • Versión 2.6
    • Se mejoró la compatibilidad con los operadores basados en atributos de GraphDef y las inicializaciones de recursos de HashTable.
  • Versión 2.5
  • Versión 2.4
    • Se mejoró la compatibilidad con los delegados acelerados por hardware