Google Play 開発者サービスの C および C++ API の LiteRT

Google Play 開発者サービス ランタイムの LiteRT を使用すると、LiteRT ライブラリをアプリに静的にバンドルすることなく、機械学習(ML)モデルを実行できます。このガイドでは、Google Play 開発者サービスの C または C++ API の使用方法について説明します。

Google Play 開発者サービスの C API または C++ API で LiteRT を使用する前に、CMake ビルドツールがインストールされていることを確認してください。

ビルド構成を更新する

(1)LiteRT の Play 開発者サービス API にアクセスするには、アプリ プロジェクト コードに次の依存関係を追加します。

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

パッケージ名は -java で終わっていますが、このパッケージには C と C++ の API も含まれています。

(2)次に、モジュールの build.gradle ファイルの android ブロックを更新して Prefab 機能を有効にし、CMake スクリプトから C API にアクセスできるようにします。

buildFeatures {
  prefab = true
}

(3)[C++ API のみ] C++ API を使用している場合は、tflite-java-extract-cpp-sdk.gradle をプロジェクトの app ディレクトリにコピーし、アプリの Gradle スクリプト(app/build.gradle など)の先頭に以下を追加します。

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

これには、play-services-tflite-java の AAR ファイルから C++ SDK を自動的に解凍する Gradle コードが含まれています。

(4)[C++ API のみ] C++ API を使用している場合は、アプリの CMake 構成ファイル(通常は CMakeLists.txt)を含むディレクトリを見つけます。通常、このディレクトリは app/src/main/cpp ディレクトリです。次に、Findtflite_cc_api.cmake をプロジェクトの新しい Modules サブディレクトリにコピーします。これには、前の手順の Gradle スクリプトによって解凍された C++ SDK を見つけるコードが含まれています。

(5)最後に、パッケージ tensorflowlite_jni_gms_client と、C++ API の場合はパッケージ tflite_cc_api を追加する必要があります。どちらも AAR からインポートされ、CMake スクリプトの依存関係として追加されます。

C

``` find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Play 開発者サービスで TFLite の使用を有効にするように C/C++ コンパイラ フラグを設定します(アプリにバンドルされている通常の TFLite ではなく)。 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++

``` # Play 開発者サービス C API の TFLite(tensorflowlite_jni_gms_client)依存関係を設定します。 find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Play 開発者サービスの C++ API(tflite_cc_api)の依存関係に TFLite を設定します。 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 ランタイムを初期化する

LiteRT Native API を呼び出す前に、Java または Kotlin コードで TfLiteNative ランタイムを初期化する必要があります。

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

TfLiteNative.initialize は、Google Play 開発者サービスの Task API を使用して、Google Play 開発者サービスから TFLite ランタイムを非同期でアプリのランタイム プロセスに読み込みます。addOnSuccessListener() を使用して、LiteRT API にアクセスするコードを実行する前に TfLite.initialize() タスクが完了するようにします。タスクが正常に完了すると、使用可能なすべての TFLite ネイティブ API を呼び出すことができます。

ネイティブ コードの実装

Google Play 開発者サービスで C/C++ コードで LiteRT を使用するには、次のいずれか(または両方)を行います。

  • Java コードから C または C++ 関数を呼び出す新しい JNI 関数を宣言する
  • 既存の C または C++ コードから LiteRT Native API を呼び出します。

JNI 関数

次のように、新しい JNI 関数を宣言して、C/C++ コードで宣言された LiteRT ランタイムを Java/Kotlin コードからアクセスできるようにします。

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

次の loadModelrunInference の C または 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

次に、Java/Kotlin コードから C/C++ 関数を呼び出します。

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

適切な API ヘッダー ファイルを含めて、Google Play 開発者サービス API に LiteRT を含めます。

C

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

C++

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

その後、通常の LiteRT C または C++ API を使用できます。

C

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

C++

```c++ // モデルを読み込む。auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer( model_asset, model_asset_length); ... // インタープリタを初期化します。 BuiltinOpResolver op_resolver; InterpreterBuilder interpreter_builder(*model, op_resolver); interpreter_builder(&interpreter); std::unique_ptr<Interpreter>` interpreter; interpreter_builder(&interpreter); ```

サポートされている API

C

Google Play 開発者サービスの LiteRT ネイティブ API ヘッダーは、非推奨または試験運用版の機能を除き、通常の [LiteRT C API](../../api/tflite/c) と同じ API を提供します。現時点では、次のヘッダーの関数と型を使用できます。モデルの読み込みと実行用の TensorFlow Lite API : ```none tensorflow/lite/c/c_api.h tensorflow/lite/c/c_api_types.h ``` カスタム演算とデリゲートを定義するための TensorFlow Lite 拡張 API (ハードウェア アクセラレーションなど): ```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: ```none tensorflow/lite/acceleration/configuration/c/gpu_plugin.h tensorflow/lite/acceleration/configuration/c/xnnpack_plugin.h ``` 「c_api_experimental.h」ヘッダーの関数はサポートされていません。 Google Play 開発者サービスで LiteRT に固有の関数を使用するには、`tensorflow/lite/abi/tflite.h` を追加します。

C++

Google Play 開発者サービス ネイティブ API ヘッダーを使用する LiteRT は、非推奨または試験運用版の機能と、このセクションの後半で説明するいくつかの例外を除き、通常の [LiteRT C++ API](../../api/tflite/cc) と同じ API を提供します。次のヘッダーの機能が使用できます。 ```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 ``` 「tensorflow/lite/interpreter.h」の場合、Play 開発者サービスでサポートされている API には、LiteRT が安定した ABI を提供しない「tflite::Interpreter」の一部のメンバーが含まれていません。 ```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) ```