LiteRT en las APIs de C y C++ de los Servicios de Google Play

LiteRT en el entorno de ejecución de los Servicios de Google Play te permite ejecutar modelos de aprendizaje automático (ML) sin agrupar bibliotecas de LiteRT de forma estática en tu app. En esta guía, se proporcionan instrucciones para usar las APIs de C o C++ para los Servicios de Google Play.

Antes de trabajar con LiteRT en la API de C o C++ de los Servicios de Google Play, asegúrate de tener instalada la herramienta de compilación CMake.

Cómo actualizar la configuración de tu compilación

(1) Agrega las siguientes dependencias al código de tu proyecto de app para acceder a la API de los servicios de Play para LiteRT:

implementation "com.google.android.gms:play-services-tflite-java:16.4.0"

Ten en cuenta que, aunque el nombre del paquete termina en -java, ese paquete también contiene las APIs de C y C++.

(2) Luego, habilita la función Prefab para acceder a la API de C desde tu secuencia de comandos de CMake. Para ello, actualiza el bloque android del archivo build.gradle de tu módulo:

buildFeatures {
  prefab = true
}

(3) [Solo para la API de C++] Si usas la API de C++, copia tflite-java-extract-cpp-sdk.gradle en tu proyecto, en el directorio app, y agrega lo siguiente al comienzo de la secuencia de comandos de Gradle de tu app (p.ej., app/build.gradle):

apply from: 'tflite-java-extract-cpp-sdk.gradle'

Contiene código de Gradle para descomprimir automáticamente el SDK de C++ del archivo AAR para play-services-tflite-java.

(4) [Solo API de C++] Si usas la API de C++, busca el directorio que contiene el archivo de configuración de CMake de tu app (normalmente, CMakeLists.txt). Por lo general, ese directorio es el directorio app/src/main/cpp. Luego, copia Findtflite_cc_api.cmake en tu proyecto, en un nuevo subdirectorio Modules de ese directorio. Contiene código que encuentra el SDK de C++ que descomprimió la secuencia de comandos de Gradle en el paso anterior.

(5) Por último, debes agregar el paquete tensorflowlite_jni_gms_client y, para la API de C++, también el paquete tflite_cc_api, que se importan desde el AAR, como dependencias en tu secuencia de comandos de CMake:

C

``` find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Set up C/C++ compiler flags to enable use of TFLite in Play services # (rather than regular TFLite bundled with the app). add_compile_definitions(TFLITE_IN_GMSCORE) add_compile_definitions(TFLITE_WITH_STABLE_ABI) target_link_libraries(tflite-jni # your JNI lib target tensorflowlite_jni_gms_client::tensorflowlite_jni_gms_client android # other deps for your target log) ```

C++

``` # Configura la dependencia de TFLite en la API de C de los servicios de Play (tensorflowlite_jni_gms_client). find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Configura la dependencia de TFLite en la API de C++ de los servicios de Play (tflite_cc_api). list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Modules") find_package(tflite_cc_api REQUIRED MODULE) include_directories(${tflite_cc_api_INCLUDE_DIR}) add_subdirectory(${tflite_cc_api_DIR} tflite_cc_api_build) # Set up C/C++ compiler flags to enable use of TFLite in Play services # (rather than regular TFLite bundled with the app). add_compile_definitions(TFLITE_IN_GMSCORE) add_compile_definitions(TFLITE_WITH_STABLE_ABI) target_link_libraries(tflite-jni # your JNI lib target tflite_cc_api::tflite_cc_api tensorflowlite_jni_gms_client::tensorflowlite_jni_gms_client android # other deps for your target log) ```

Inicializa el entorno de ejecución de LiteRT

Antes de llamar a la API nativa de LiteRT, debes inicializar el tiempo de ejecución de TfLiteNative en tu código Java o Kotlin.

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

Con la API de Task de los Servicios de Google Play, TfLiteNative.initialize carga de forma asíncrona el entorno de ejecución de TFLite de los Servicios de Google Play en el proceso de tiempo de ejecución de tu aplicación. Usa addOnSuccessListener() para asegurarte de que la tarea TfLite.initialize() se complete antes de ejecutar el código que accede a las APIs de LiteRT. Una vez que la tarea se haya completado correctamente, puedes invocar todas las APIs nativas de TFLite disponibles.

Implementación de código nativo

Para usar LiteRT en los Servicios de Google Play con tu código C/C++, puedes hacer una (o ambas) de las siguientes acciones:

  • Declara nuevas funciones JNI para llamar a funciones C o C++ desde tu código Java.
  • Llamar a la API nativa de LiteRT desde tu código C o C++ existente

Funciones de JNI

Puedes declarar funciones JNI nuevas para que el entorno de ejecución de LiteRT declarado en código C/C++ sea accesible para tu código Java/Kotlin de la siguiente manera:

Java

package com.google.samples.gms.tflite.c;

public class TfLiteJni {
  static {
    System.loadLibrary("tflite-jni");
  }
  public TfLiteJni() { /**/ };
  public native void loadModel(AssetManager assetManager, String assetName);
  public native float[] runInference(float[] input);  // For example.
}
      

Kotlin

package com.google.samples.gms.tflite.c

class TfLiteJni() {
  companion object {
    init {
      System.loadLibrary("tflite-jni")
    }
  }
  external fun loadModel(assetManager: AssetManager, assetName: String)
  external fun runInference(input: FloatArray): FloatArray  // For example.
}
        

Coincidir con las siguientes funciones loadModel y runInference de C o C++:

#ifdef __cplusplus
extern "C" {
#endif

void Java_com_google_samples_gms_tflite_c_loadModel(
  JNIEnv *env, jobject tflite_jni, jobject asset_manager, jstring asset_name){
  //...
}

jfloatArray Java_com_google_samples_gms_tflite_c_TfLiteJni_runInference(
  JNIEnv* env, jobject tfliteJni, jfloatArray input) {
  //...
}

#ifdef __cplusplus
}  // extern "C".
#endif

Luego, puedes llamar a tus funciones de C/C++ desde tu código Java/Kotlin:

Java

tfLiteHandleTask.onSuccessTask(unused -> {
    TfLiteJni jni = new TfLiteJni();
    jni.loadModel(getAssets(), "add.bin");
    //...
});
    

Kotlin

tfLiteHandleTask.onSuccessTask {
    val jni = TfLiteJni()
    jni.loadModel(assets, "add.bin")
    // ...
}
      

LiteRT en código nativo

Incluye el archivo de encabezado de API adecuado para incluir LiteRT con la API de los Servicios de Google Play:

C

``` #include "tensorflow/lite/c/c_api.h" ```

C++

``` #include "tensorflow/lite/interpreter.h" #include "tensorflow/lite/model_builder.h" ```

Luego, puedes usar la API normal de LiteRT C o C++:

C

```c++ TfLiteModel* model = TfLiteModelCreate(model_asset, model_asset_length); // ... TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate(); // ... TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options); ```

C++

```c++ // Carga el modelo. auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer( model_asset, model_asset_length); ... // Inicializa el intérprete. BuiltinOpResolver op_resolver; InterpreterBuilder interpreter_builder(*model, op_resolver); interpreter_builder(&interpreter); std::unique_ptr<Interpreter>` interpreter; interpreter_builder(&interpreter); ```

API admitidas

C

LiteRT con encabezados de API nativa de los Servicios de Google Play proporciona la misma API que la [API de LiteRT C](../../api/tflite/c) normal, excepto las funciones que dejaron de estar disponibles o son experimentales. Por ahora, están disponibles las funciones y los tipos de los siguientes encabezados. APIs de TensorFlow Lite para cargar y ejecutar modelos: ```none tensorflow/lite/c/c_api.h tensorflow/lite/c/c_api_types.h ``` APIs de extensión de TensorFlow Lite para definir operaciones y delegados personalizados (p.ej., para la aceleración de hardware): ```none tensorflow/lite/c/c_api_opaque.h tensorflow/lite/c/common.h tensorflow/lite/c/builtin_op_data.h tensorflow/lite/builtin_ops.h ``` APIs de complementos delegados para usar delegados existentes: ```none tensorflow/lite/acceleration/configuration/c/gpu_plugin.h tensorflow/lite/acceleration/configuration/c/xnnpack_plugin.h ``` Ten en cuenta que no se admiten las funciones del encabezado "c_api_experimental.h". Para usar funciones específicas de LiteRT con los Servicios de Google Play, incluye "tensorflow/lite/abi/tflite.h".

C++

LiteRT con encabezados de API nativa de los Servicios de Google Play proporciona la misma API que la [API de LiteRT en C++](../api/tflite/cc) normal, excepto por las funciones que están obsoletas o son experimentales, y con algunas excepciones menores que se mencionan más adelante en esta sección. La funcionalidad de los siguientes encabezados está disponible: ```none tensorflow/lite/model_builder.h tensorflow/lite/interpreter_builder.h tensorflow/lite/interpreter.h tensorflow/lite/signature_runner.h tensorflow/lite/acceleration/configuration/delegate_registry.h tensorflow/lite/kernels/builtin_op_kernels.h tensorflow/lite/kernels/register.h tensorflow/lite/tools/verifier.h ``` En el caso de "tensorflow/lite/interpreter.h", la API compatible con los Servicios de Play expulsa algunos miembros de "tflite::Interpreter" para los que LiteRT no ofrece una ABI estable: ```c++ Interpreter::variables() Interpreter::nodes_size() Interpreter::node_and_registration(int node_index) Interpreter::kTensorsReservedCapacity Interpreter::kTensorsCapacityHeadroom Interpreter::OpProfilingString(const TfLiteRegistration&, const TfLiteNode*) Interpreter::SetExternalContext(TfLiteExternalContextType type, TfLiteExternalContext* ctx) ```