LiteRT nelle API C e C++ di Google Play Services

LiteRT nel runtime di Google Play Services ti consente di eseguire modelli di machine learning (ML) senza eseguire il bundling statico delle librerie LiteRT nella tua app. Questa guida fornisce istruzioni su come utilizzare le API C o C++ per Google Play Services.

Prima di utilizzare LiteRT nell'API C o C++ di Google Play Services, assicurati di aver installato lo strumento di compilazione CMake.

Aggiorna la configurazione di compilazione

(1) Aggiungi le seguenti dipendenze al codice del progetto dell'app per accedere all'API Play Services per LiteRT:

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

Tieni presente che, anche se il nome del pacchetto termina con -java, il pacchetto contiene anche le API C e C++.

(2) Quindi, abilita la funzionalità Prefab per accedere all'API C dallo script CMake aggiornando il blocco android del file build.gradle del modulo:

buildFeatures {
  prefab = true
}

(3) [Solo API C++] Se utilizzi l'API C++, copia tflite-java-extract-cpp-sdk.gradle nel tuo progetto, nella directory app, e aggiungi quanto segue all'inizio dello script gradle della tua app (ad es. app/build.gradle):

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

Questo contiene il codice Gradle per scompattare automaticamente l'SDK C++ dal file AAR per play-services-tflite-java.

(4) [Solo API C++] Se utilizzi l'API C++, individua la directory che contiene il file di configurazione CMake della tua app (in genere CMakeLists.txt). In genere, questa directory è la directory app/src/main/cpp. Quindi copia Findtflite_cc_api.cmake nel tuo progetto, in una nuova sottodirectory Modules di quella directory. Questo contiene il codice che trova l'SDK C++ scompattato dallo script Gradle nel passaggio precedente.

(5) Infine, devi aggiungere il pacchetto tensorflowlite_jni_gms_client e, per l'API C++, anche il pacchetto tflite_cc_api, entrambi importati dall'AAR, come dipendenze nello 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)
      

Inizializza il runtime LiteRT

Prima di chiamare l'API LiteRT C o C++, devi inizializzare il runtime TfLiteNative nel codice Java o Kotlin.

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

Utilizzando l'API Task di Google Play Services, TfLiteNative.initialize carica in modo asincrono il runtime TFLite da Google Play Services nel processo di runtime della tua app. Utilizza addOnSuccessListener() per assicurarti che l'attività TfLite.initialize() venga completata prima di eseguire il codice che accede alle API LiteRT. Una volta completata l'attività, puoi invocare tutte le API native TFLite disponibili.

Implementazione del codice nativo

Per utilizzare LiteRT in Google Play Services con il tuo codice C/C++, puoi eseguire una (o entrambe) delle seguenti operazioni:

  • dichiarare nuove funzioni JNI per chiamare funzioni C o C++ dal codice Java
  • Chiama l'API nativa LiteRT dal codice C o C++ esistente.

Funzioni JNI

Puoi dichiarare nuove funzioni JNI per rendere il runtime LiteRT dichiarato nel codice C/C++ accessibile al tuo codice Java/Kotlin come segue:

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

Corrispondenza alle seguenti funzioni C o C++ loadModel e runInference:

#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

Puoi quindi chiamare le funzioni C/C++ dal codice 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 in codice nativo

Includi il file di intestazione API appropriato per includere LiteRT con l'API Google Play Services:

C

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

C++

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

Puoi quindi utilizzare la normale API LiteRT C o C++:

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 supportate

C

Le intestazioni dell'API C di LiteRT con Google Play Services forniscono la stessa API della normale API C di LiteRT, escluse le funzionalità ritirate o sperimentali. Per il momento sono disponibili le funzioni e i tipi delle seguenti intestazioni.

API TensorFlow Lite per caricare ed eseguire i modelli:

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

API di estensione TensorFlow Lite per definire operazioni e delegati personalizzati (ad es. per l'accelerazione hardware):

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 dei plug-in dei delegati per l'utilizzo dei delegati esistenti:

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

Tieni presente che le funzioni dell'intestazione c_api_experimental.h non sono supportate.

Puoi utilizzare le funzioni specifiche di LiteRT con Google Play Services includendo la seguente intestazione:

tensorflow/lite/abi/tflite.h
.

C++

Gli intestazioni dell'API C++ LiteRT con i servizi Google Play forniscono la stessa API della normale API C++ LiteRT, escluse le funzionalità ritirate o sperimentali, e con alcune piccole eccezioni riportate più avanti in questa sezione. Sono disponibili le funzionalità dei seguenti intestazioni:

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
      

Per tensorflow/lite/interpreter.h, l'API supportata con i servizi Play esclude alcuni membri di tflite::Interpreter per i quali LiteRT non offre un ABI stabile:

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)