借助 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) 最后,您需要在 CMake 脚本中添加从 AAR 导入的软件包 tensorflowlite_jni_gms_client(对于 C++ API,还需要添加软件包 tflite_cc_api),作为依赖项:
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以异步方式将 LiteRT 运行时从 Google Play 服务加载到应用运行时进程中。使用 addOnSuccessListener() 确保 TfLite.initialize() 任务在执行访问 LiteRT API 的代码之前完成。任务成功完成后,您就可以调用所有可用的 LiteRT Native API 了。
原生代码实现
如需在 Google Play 服务中将 LiteRT 与 C/C++ 代码搭配使用,您可以执行以下一项(或两项)操作:
- 声明新的 JNI 函数,以便从 Java 代码中调用 C 或 C++ 函数
- 从现有的 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. }
与以下 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 与 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 服务 C API 标头的 LiteRT 提供的 API 与常规 LiteRT C 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 标头中的函数。
您可以通过添加以下头文件,使用特定于 LiteRT 的 Google Play 服务函数:
tensorflow/lite/abi/tflite.h
C++
包含 Google Play 服务的 LiteRT C++ API 标头提供的 API 与常规 LiteRT C++ 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 排除了一些 tflite::Interpreter 成员,LiteRT 未针对这些成员提供稳定的 ABI:
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)