Google Play 服務執行階段中的 LiteRT 可讓您執行機器學習 (ML) 模型,而無須將 LiteRT 程式庫靜態捆綁至應用程式。本指南將說明如何使用 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'
這個檔案包含 Gradle 程式碼,可自動從 play-services-tflite-java
的 AAR 檔案解開 C++ SDK。
(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) # 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 執行階段
在呼叫 LiteRT Native API 之前,您必須在 Java 或 Kotlin 程式碼中初始化 TfLiteNative
執行階段。
Java
Task tfLiteInitializeTask = TfLiteNative.initialize(context);
Kotlin
val tfLiteInitializeTask: Task= TfLiteNative.initialize(context)
使用 Google Play 服務 Task API,TfLiteNative.initialize
會以非同步方式將 TFLite 執行階段從 Google Play 服務載入至應用程式的執行階段程序。請使用 addOnSuccessListener()
,確保 TfLite.initialize()
工作在執行存取 LiteRT API 的程式碼前完成。工作順利完成後,您可以叫用所有可用的 TFLite Native API。
原生程式碼實作
如要在 Google Play 服務中使用 LiteRT 和 C/C++ 程式碼,您可以執行下列任一 (或兩者) 操作:
- 宣告新的 JNI 函式,以便從 Java 程式碼呼叫 C 或 C++ 函式
- 從現有的 C 或 C++ 程式碼呼叫 LiteRT Native API。
JNI 函式
您可以宣告新的 JNI 函式,讓 Java/Kotlin 程式碼能夠存取在 C/C++ 程式碼中宣告的 LiteRT 執行階段,如下所示:
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 標頭檔案,以便納入 LiteRT with Google Play 服務 API:
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 服務的 LiteRT 原生 API 標頭提供的 API 與一般 [LiteRT C API](../../api/tflite/c) 相同,但不含已淘汰或實驗功能。目前可使用下列標頭中的函式和類型。用於載入及執行模型的 TensorFlow Lite APItensorflow/lite/c/c_api.h tensorflow/lite/c/c_api_types.h
tensorflow/lite/c/c_api_opaque.h tensorflow/lite/c/common.h tensorflow/lite/c/builtin_op_data.h tensorflow/lite/builtin_ops.h
tensorflow/lite/acceleration/configuration/c/gpu_plugin.h tensorflow/lite/acceleration/configuration/c/xnnpack_plugin.h
C++
搭配 Google Play 服務的 LiteRT 原生 API 標頭提供的 API 與一般 [LiteRT C++ API](../../api/tflite/cc) 相同,但不含已淘汰或實驗性質的功能,以及本節稍後會提到的幾個次要例外狀況。可使用下列標頭的功能: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
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)