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) # Configura gli indicatori del compilatore C/C++ per abilitare l'utilizzo di TFLite in Play Services # (anziché il normale TFLite in bundle con l'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 dipendenza di TFLite nell'API C di Play Services (tensorflowlite_jni_gms_client). find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Configura la dipendenza di TFLite nell'API C++ di Play Services (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) # Configura gli indicatori del compilatore C/C++ per abilitare l'utilizzo di TFLite in Play Services # (anziché il normale TFLite in bundle con l'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 nativa LiteRT, devi inizializzare il runtimeTfLiteNative 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

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

C++

```c++ // Carica il modello. auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer( model_asset, model_asset_length); ... // Inizializza l'interprete. BuiltinOpResolver op_resolver; InterpreterBuilder interpreter_builder(*model, op_resolver); interpreter_builder(&interpreter); std::unique_ptr<Interpreter>` interpreter; interpreter_builder(&interpreter); ```

API supportate

C

Gli intestazioni dell'API nativa LiteRT con i servizi Google Play forniscono la stessa API della normale [API C LiteRT](../../api/tflite/c), 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: ```none 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): ```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 ``` API plug-in dei delegati per l'utilizzo di delegati esistenti: ```none 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 funzioni specifiche per LiteRT con Google Play Services includendo "tensorflow/lite/abi/tflite.h".

C++

Gli intestazioni dell'API nativa LiteRT con Google Play Services forniscono la stessa API della normale [API C++ LiteRT](../../api/tflite/cc), escluse le funzionalità ritirate o sperimentali e con alcune piccole eccezioni indicate più avanti in questa sezione. La funzionalità dei seguenti intestazioni è disponibile: ```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 ``` Per "tensorflow/lite/interpreter.h", l'API supportata con Play Services esclude alcuni membri di "tflite::Interpreter" per i quali LiteRT non offre un ABI stabile: ```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) ```