LiteRT in C- und C++-APIs der Google Play-Dienste

Mit LiteRT in der Google Play-Dienste-Laufzeit können Sie Modelle für maschinelles Lernen (ML) ausführen, ohne LiteRT-Bibliotheken statisch in Ihre App einzubinden. In diesem Leitfaden finden Sie eine Anleitung zur Verwendung der C- oder C++-APIs für Google Play-Dienste.

Bevor Sie mit der LiteRT in der C-API oder C++-API der Google Play-Dienste arbeiten, müssen Sie das Build-Tool CMake installieren.

Build-Konfiguration aktualisieren

1. Fügen Sie dem App-Projektcode die folgenden Abhängigkeiten hinzu, um auf die Play-Services-API für LiteRT zuzugreifen:

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

Obwohl der Paketname mit -java endet, enthält dieses Paket auch die C- und C++-APIs.

(2) Aktivieren Sie dann die Funktion Prefab, um über Ihr CMake-Skript auf die C-API zuzugreifen. Aktualisieren Sie dazu den Android-Block der build.gradle-Datei Ihres Moduls:

buildFeatures {
  prefab = true
}

3. [Nur C++ API] Wenn Sie die C++ API verwenden, kopieren Sie tflite-java-extract-cpp-sdk.gradle in Ihr Projekt in das Verzeichnis app und fügen Sie Folgendes am Anfang des Gradle-Scripts Ihrer App (z. B. app/build.gradle) hinzu:

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

Dieser Code enthält Gradle-Code zum automatischen Entpacken des C++ SDK aus der AAR-Datei für play-services-tflite-java.

4. [Nur C++ API] Wenn Sie die C++ API verwenden, suchen Sie das Verzeichnis, das die CMake-Konfigurationsdatei Ihrer App enthält (normalerweise CMakeLists.txt). Dieses Verzeichnis ist normalerweise Ihr app/src/main/cpp-Verzeichnis. Kopieren Sie dann Findtflite_cc_api.cmake in Ihr Projekt in ein neues Unterverzeichnis Modules dieses Verzeichnisses. Dieser Code sucht nach dem C++ SDK, das im vorherigen Schritt vom Gradle-Script entpackt wurde.

5. Fügen Sie schließlich das Paket tensorflowlite_jni_gms_client und für die C++ API auch das Paket tflite_cc_api hinzu. Beide werden als Abhängigkeiten in Ihr CMake-Skript importiert:

C

find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG)

# Set up C/C++ compiler flags to enable use of LiteRT in Play services
# (rather than regular LiteRT 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 LiteRT in Play services C API (tensorflowlite_jni_gms_client) dependency.

find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG)

# Set up LiteRT 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 LiteRT in Play services
# (rather than regular LiteRT 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)
      

LiteRT-Laufzeit initialisieren

Bevor Sie die LiteRT C- oder C++-API aufrufen, müssen Sie die TfLiteNative-Laufzeit in Ihrem Java- oder Kotlin-Code initialisieren.

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

Mit der Task API der Google Play-Dienste lädt TfLiteNative.initialize die LiteRT-Laufzeit asynchron aus den Google Play-Diensten in den Laufzeitprozess Ihrer Anwendung. Verwenden Sie addOnSuccessListener(), um sicherzustellen, dass die Aufgabe TfLite.initialize() abgeschlossen wird, bevor Code ausgeführt wird, der auf LiteRT-APIs zugreift. Sobald die Aufgabe erfolgreich abgeschlossen wurde, können Sie alle verfügbaren LiteRT Native APIs aufrufen.

Implementierung von nativem Code

Wenn Sie LiteRT in Google Play-Diensten mit Ihrem C/C++-Code verwenden möchten, haben Sie folgende Möglichkeiten:

  • neue JNI-Funktionen deklarieren, um C- oder C++-Funktionen aus Ihrem Java-Code aufzurufen
  • die LiteRT Native API aus Ihrem vorhandenen C- oder C++-Code aufrufen.

JNI-Funktionen

Sie können neue JNI-Funktionen deklarieren, um die in C/C++-Code deklarierte LiteRT-Laufzeit für Ihren Java-/Kotlin-Code zugänglich zu machen:

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

Entsprechen den folgenden loadModel- und runInference-Funktionen in C oder 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

Anschließend können Sie Ihre C/C++-Funktionen aus Ihrem Java-/Kotlin-Code aufrufen:

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 nativem Code

Fügen Sie die entsprechende API-Headerdatei ein, um die LiteRT mit der Google Play Services API einzubinden:

C

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

C++

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

Sie können dann die reguläre LiteRT C- oder C++-API verwenden:

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);
      

Unterstützte APIs

C

Die LiteRT-C-API-Header mit Google Play-Diensten bieten dieselbe API wie die reguläre LiteRT-C-API, mit Ausnahme von Funktionen, die eingestellt oder experimentell sind. Derzeit sind die Funktionen und Typen aus den folgenden Headern verfügbar.

TensorFlow Lite-APIs zum Laden und Ausführen von Modellen :

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

TensorFlow Lite Extension APIs zum Definieren benutzerdefinierter Vorgänge und Delegates (z.B. für die Hardwarebeschleunigung):

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

Delegate-Plug-in-APIs für die Verwendung vorhandener Delegates:

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

Funktionen aus dem c_api_experimental.h-Header werden nicht unterstützt.

Sie können LiteRT-spezifische Funktionen mit Google Play-Diensten verwenden, indem Sie den folgenden Header einfügen:

tensorflow/lite/abi/tflite.h
.

C++

Die LiteRT mit Google Play Services C++ API-Headern bietet dieselbe API wie die reguläre LiteRT C++ API, mit Ausnahme von Funktionen, die eingestellt oder experimentell sind, und mit einigen kleineren Ausnahmen, die später in diesem Abschnitt aufgeführt werden. Die Funktionen aus den folgenden Headern sind verfügbar:

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
      

Für tensorflow/lite/interpreter.h schließt die unterstützte API mit Play-Diensten einige Elemente von tflite::Interpreter aus, für die LiteRT keine stabile ABI bietet:

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)