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

Mit LiteRT in der Google Play-Dienstlaufzeit können Sie Modelle für maschinelles Lernen ausführen, ohne LiteRT-Bibliotheken statisch in Ihre App einzubinden. In diesem Leitfaden erfahren Sie, wie Sie die C- oder C++-APIs für Google Play-Dienste verwenden.

Bevor Sie mit der LiteRT in der C API oder C++ API von Google Play-Diensten arbeiten, müssen Sie das Build-Tool CMake installiert haben.

Buildkonfiguration aktualisieren

(1) Fügen Sie dem Code Ihres App-Projekts die folgenden Abhängigkeiten hinzu, um auf die Play-Dienste API für LiteRT zuzugreifen:

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

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

(2) Aktivieren Sie dann die Funktion Prefab, um über Ihr CMake-Script 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 am Anfang des Gradle-Scripts Ihrer App (z.B. app/build.gradle) Folgendes hinzu:

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

Dieser enthält Gradle-Code, mit dem das C++ SDK automatisch aus der AAR-Datei für play-services-tflite-java entpackt wird.

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

(5) Fügen Sie abschließend das Paket tensorflowlite_jni_gms_client und für die C++ API auch das Paket tflite_cc_api hinzu, die beide aus dem AAR importiert werden, als Abhängigkeiten in Ihr CMake-Script:

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)
      

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 von Google Play-Diensten lädt TfLiteNative.initialize die TFLite-Laufzeit asynchron aus den Google Play-Diensten in den Laufzeitprozess Ihrer Anwendung. Mit addOnSuccessListener() kannst du dafür sorgen, dass die Aufgabe TfLite.initialize() abgeschlossen ist, bevor Code ausgeführt wird, der auf LiteRT APIs zugreift. Sobald die Aufgabe abgeschlossen ist, können Sie alle verfügbaren TFLite Native APIs aufrufen.

Native Code-Implementierung

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. Gehen Sie dazu so vor:

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

Übereinstimmung mit den folgenden loadModel- und runInference-C- oder C++-Funktionen:

#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

Sie können Ihre C/C++-Funktionen dann 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 LiteRT in die 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 C API-Header von LiteRT mit Google Play-Diensten bieten die gleiche 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-Erweiterungs-APIs zum Definieren benutzerdefinierter Vorgänge und Delegierten (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
      

Plug-in-APIs für die Verwendung vorhandener Bevollmächtigter:

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 den Google Play-Diensten verwenden, indem Sie die folgende Überschrift einfügen:

tensorflow/lite/abi/tflite.h
.

C++

Die C++ API-Header von LiteRT mit Google Play-Diensten bieten die gleiche API wie die reguläre LiteRT C++ API, mit Ausnahme von Funktionen, die eingestellt oder experimentell sind, und mit einigen kleineren Ausnahmen, die weiter unten in diesem Abschnitt aufgeführt sind. Die folgenden Überschriften 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
      

Bei tensorflow/lite/interpreter.h schließt die unterstützte API mit Play-Diensten einige Mitglieder von tflite::Interpreter aus, für die LiteRT kein stabiles 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)