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 API と C++ API も含まれています。
(2)次に、モジュールの build.gradle ファイルの android ブロックを更新して、CMake スクリプトから C API にアクセスできるように Prefab 機能を有効にします。
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)最後に、CMake スクリプトの依存関係として、パッケージ tensorflowlite_jni_gms_client と、C++ API の場合はパッケージ tflite_cc_api も追加する必要があります。どちらも AAR からインポートされます。
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 ランタイムを初期化する
LiteRT C または C++ API を呼び出す前に、Java または Kotlin コードで TfLiteNative ランタイムを初期化する必要があります。
Java
Task tfLiteInitializeTask = TfLiteNative.initialize(context);
Kotlin
val tfLiteInitializeTask: Task= TfLiteNative.initialize(context)
Google Play 開発者サービスの Task API を使用して、TfLiteNative.initialize は Google Play 開発者サービスからアプリケーションのランタイム プロセスに LiteRT ランタイムを非同期で読み込みます。addOnSuccessListener() を使用して、LiteRT API にアクセスするコードを実行する前に TfLite.initialize() タスクが完了していることを確認します。タスクが正常に完了すると、使用可能なすべての LiteRT ネイティブ API を呼び出すことができます。
ネイティブ コードの実装
C/C++ コードで Google Play 開発者サービスの LiteRT を使用するには、次のいずれか(または両方)を行います。
- Java コードから C または C++ 関数を呼び出すための新しい JNI 関数を宣言する
- 既存の C または C++ コードから LiteRT ネイティブ 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. }
次の loadModel 関数と runInference 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
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
C
Google Play 開発者サービスの C API ヘッダーを含む LiteRT は、非推奨または試験運用版の機能を除き、通常の LiteRT C API と同じ API を提供します。現時点では、次のヘッダーの関数と型を使用できます。
モデルの読み込みと実行のための TensorFlow Lite API:
tensorflow/lite/c/c_api.h tensorflow/lite/c/c_api_types.h
カスタム オペレーションとデリゲート(ハードウェア アクセラレーションなど)を定義するための TensorFlow Lite 拡張 API:
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:
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 開発者サービス C++ API ヘッダーを備えた LiteRT は、非推奨または試験運用版の機能を除き、通常の LiteRT C++ API と同じ API を提供します。ただし、このセクションの後半で説明するいくつかの例外があります。次のヘッダーの機能を利用できます。
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 のメンバーがいくつか含まれていません。
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)