LiteRT dans les API C et C++ des services Google Play

LiteRT dans l'environnement d'exécution des services Google Play vous permet d'exécuter des modèles de machine learning (ML) sans regrouper de manière statique les bibliothèques LiteRT dans votre application. Ce guide explique comment utiliser les API C ou C++ pour les services Google Play.

Avant d'utiliser LiteRT dans l'API C ou l'API C++ des services Google Play, assurez-vous d'avoir installé l'outil de compilation CMake.

Mettre à jour la configuration de compilation

(1) Ajoutez les dépendances suivantes au code de votre projet d'application pour accéder à l'API Play Services pour LiteRT:

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

Notez que même si le nom du package se termine par -java, ce package contient également les API C et C++.

(2) Ensuite, activez la fonctionnalité Prefab pour accéder à l'API C à partir de votre script CMake en mettant à jour le bloc Android du fichier build.gradle de votre module:

buildFeatures {
  prefab = true
}

(3) [API C++] Si vous utilisez l'API C++, copiez tflite-java-extract-cpp-sdk.gradle dans votre projet, dans votre répertoire app, puis ajoutez ce qui suit au début du script Gradle de votre application (par exemple, app/build.gradle):

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

Il contient du code Gradle permettant de décompresser automatiquement le SDK C++ à partir du fichier AAR pour play-services-tflite-java.

(4) [API C++ uniquement] Si vous utilisez l'API C++, recherchez le répertoire contenant le fichier de configuration CMake de votre application (normalement CMakeLists.txt). Ce répertoire est normalement votre répertoire app/src/main/cpp. Copiez ensuite Findtflite_cc_api.cmake dans votre projet, dans un nouveau sous-répertoire Modules de ce répertoire. Il contient du code qui recherche le SDK C++ décompressé par le script Gradle à l'étape précédente.

(5) Vous devez enfin ajouter le package tensorflowlite_jni_gms_client et, pour l'API C++, le package tflite_cc_api, tous deux importés depuis l'AAR, en tant que dépendances dans votre script 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++

# Set up TFLite in Play services C API (tensorflowlite_jni_gms_client) dependency.

find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG)

# Set up TFLite in Play services C++ API (tflite_cc_api) dependency.

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)
      

Initialiser l'environnement d'exécution LiteRT

Avant d'appeler l'API LiteRT C ou C++, vous devez initialiser l'environnement d'exécution TfLiteNative dans votre code Java ou Kotlin.

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

À l'aide de l'API Task des services Google Play, TfLiteNative.initialize charge de manière asynchrone l'environnement d'exécution TFLite à partir des services Google Play dans le processus d'exécution de votre application. Utilisez addOnSuccessListener() pour vous assurer que la tâche TfLite.initialize() se termine avant d'exécuter le code qui accède aux API LiteRT. Une fois la tâche terminée, vous pouvez appeler toutes les API natives TFLite disponibles.

Implémentation du code natif

Pour utiliser LiteRT dans les services Google Play avec votre code C/C++, vous pouvez effectuer l'une (ou les deux) des opérations suivantes:

  • déclarer de nouvelles fonctions JNI pour appeler des fonctions C ou C++ à partir de votre code Java ;
  • Appelez l'API native LiteRT à partir de votre code C ou C++ existant.

Fonctions JNI

Vous pouvez déclarer de nouvelles fonctions JNI pour rendre l'environnement d'exécution LiteRT déclaré en code C/C++ accessible à votre code Java/Kotlin comme suit:

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.
}
        

Correspondance avec les fonctions C ou C++ loadModel et runInference suivantes:

#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

Vous pouvez ensuite appeler vos fonctions C/C++ à partir de votre code 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 code natif

Incluez le fichier d'en-tête d'API approprié pour inclure LiteRT avec l'API des services Google Play:

C

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

C++

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

Vous pouvez ensuite utiliser l'API LiteRT C ou C++ standard:

C

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

C++

  // Load the model.
  auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer(
      model_asset, model_asset_length);
  ...
  // Initialize the interpreter.
  BuiltinOpResolver op_resolver;
  InterpreterBuilder interpreter_builder(*model, op_resolver);
  interpreter_builder(&interpreter);
  std::unique_ptr<Interpreter>` interpreter;
  interpreter_builder(&interpreter);
      

API compatibles

C

Les en-têtes d'API C LiteRT avec les services Google Play fournissent la même API que l'API C LiteRT standard, à l'exception des fonctionnalités obsolètes ou expérimentales. Pour l'instant, les fonctions et les types des en-têtes suivants sont disponibles.

API TensorFlow Lite pour charger et exécuter des modèles :

tensorflow/lite/c/c_api.h
tensorflow/lite/c/c_api_types.h
      

API d'extension TensorFlow Lite pour définir des opérations et des délégués personnalisés (par exemple, pour l'accélération matérielle) :

tensorflow/lite/c/c_api_opaque.h
tensorflow/lite/c/common.h
tensorflow/lite/c/builtin_op_data.h
tensorflow/lite/builtin_ops.h
      

API de plug-in de délégation pour utiliser des délégués existants:

tensorflow/lite/acceleration/configuration/c/gpu_plugin.h
tensorflow/lite/acceleration/configuration/c/xnnpack_plugin.h
      

Notez que les fonctions de l'en-tête c_api_experimental.h ne sont pas acceptées.

Vous pouvez utiliser des fonctions spécifiques à LiteRT avec les services Google Play en incluant l'en-tête suivant:

tensorflow/lite/abi/tflite.h
.

C++

Les en-têtes d'API C++ LiteRT avec les services Google Play fournissent la même API que l' API C++ LiteRT standard, à l'exception des fonctionnalités obsolètes ou expérimentales, et avec quelques exceptions mineures indiquées plus loin dans cette section. Les fonctionnalités des en-têtes suivants sont disponibles:

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
      

Pour tensorflow/lite/interpreter.h, l'API compatible avec les services Play exclut quelques membres de tflite::Interpreter pour lesquels LiteRT n'offre pas d'ABI stable:

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)