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) 最后,您需要在 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 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++

``` # 在 Play 服务 C API (tensorflowlite_jni_gms_client) 依赖项中设置 TFLite。 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 原生 API 之前,您必须在 Java 或 Kotlin 代码中初始化 TfLiteNative 运行时。

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

TfLiteNative.initialize 使用 Google Play 服务 Task API 将 TFLite 运行时从 Google Play 服务异步加载到应用的运行时进程中。使用 addOnSuccessListener() 确保在执行访问 LiteRT API 的代码之前完成 TfLite.initialize() 任务。任务成功完成后,您可以调用所有可用的 TFLite 原生 API。

原生代码实现

如需在 Google Play 服务中将 LiteRT 与 C/C++ 代码搭配使用,您可以执行以下任一操作(或同时执行这两项操作):

  • 声明新的 JNI 函数,以便从 Java 代码调用 C 或 C++ 函数
  • 从现有的 C 或 C++ 代码调用 LiteRT 原生 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.
}
        

与以下 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 头文件,以便添加 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

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

C++

```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 服务的原生 API 头文件的 LiteRT 提供与常规 [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` 头文件中的函数。 您可以通过包含 `tensorflow/lite/abi/tflite.h` 将 LiteRT 专用函数与 Google Play 服务搭配使用。

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 不包括 `tflite::Interpreter` 的部分成员,因为 LiteRT 不提供稳定的 ABI: ```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) ```