#tensorflow #cross-platform #machine-learning #bindings #ffi

tflitec

支持 x86_64 和 ARM (iOS, Android) 的 TensorFlow Lite C API 的安全 Rust 封装

11 个不稳定版本 (3 个破坏性版本)

0.6.0 2023年4月13日
0.5.2 2022年11月22日
0.5.1 2022年8月18日
0.4.1 2022年2月1日
0.3.2 2021年10月4日

#270 in 机器学习

Download history 3/week @ 2024-03-14 3/week @ 2024-03-21 18/week @ 2024-03-28 17/week @ 2024-04-04 29/week @ 2024-04-11 1/week @ 2024-04-18 3/week @ 2024-04-25

每月下载量 136

MIT 许可证

1.5MB
1K SLoC

包含 (ZIP 文件, 1.5MB) build-res/docsrs_res.zip

Crates.io Docs.rs

此crate是 TensorFlow Lite C API 的安全 Rust 封装。它的API与TensorFlow Lite Swift API非常相似。

支持的目标

以下目标已测试。然而,其他目标也可能正常工作。

  • iOS: aarch64-apple-iosx86_64-apple-ios
  • MacOS: x86_64-apple-darwin
  • Linux: x86_64-unknown-linux-gnu
  • Android: aarch64-linux-androidarmv7-linux-androideabi
  • Windows (详细信息)

请参阅 编译 部分,了解针对您的目标构建的说明。请仔细阅读 优化构建 部分。

功能

  • xnnpack - 编译 XNNPACK 并允许您使用 XNNPACK 代理。有关 XNNPACK 的详细信息,请参阅此处
  • xnnpack_qs8 - 使用额外的构建标志编译 XNNPACK,以加速对称量化操作符的推理。有关详细信息,请参阅此博客文章。这意味着已启用 xnnpack
  • xnnpack_qu8 - 与 xnnpack_qs8 类似,但加速了具有非对称量化的少数操作符。这意味着已启用 xnnpack

注意: xnnpack 已为 iOS 启用,但 xnnpack_qs8xnnpack_qu8 应手动启用。

示例

以下示例显示了在 TensorFlow Lite 模型上运行推理的过程。

use tflitec::interpreter::{Interpreter, Options};
use tflitec::tensor;
use tflitec::model::Model;

// Create interpreter options
let mut options = Options::default();
options.thread_count = 1;

// Load example model which outputs y = 3 * x
let model = Model::new("tests/add.bin")?;
// Or initialize with model bytes if it is not available as a file
// let model_data = std::fs::read("tests/add.bin")?;
// let model = Model::from_bytes(&model_data)?;

// Create interpreter
let interpreter = Interpreter::new(&model, Some(options))?;
// Resize input
let input_shape = tensor::Shape::new(vec![10, 8, 8, 3]);
let input_element_count = input_shape.dimensions().iter().copied().reduce(std::ops::Mul::mul).unwrap();
interpreter.resize_input(0, input_shape)?;
// Allocate tensors if you just created Interpreter or resized its inputs
interpreter.allocate_tensors()?;

// Create dummy input
let data = (0..input_element_count).map(|x| x as f32).collect::<Vec<f32>>();

let input_tensor = interpreter.input(0)?;
assert_eq!(input_tensor.data_type(), tensor::DataType::Float32);

// Copy input to buffer of first tensor (with index 0)
// You have 2 options:
// Set data using Tensor handle if you have it already
assert!(input_tensor.set_data(&data[..]).is_ok());
// Or set data using Interpreter:
assert!(interpreter.copy(&data[..], 0).is_ok());

// Invoke interpreter
assert!(interpreter.invoke().is_ok());

// Get output tensor
let output_tensor = interpreter.output(0)?;

assert_eq!(output_tensor.shape().dimensions(), &vec![10, 8, 8, 3]);
let output_vector = output_tensor.data::<f32>().to_vec();
let expected: Vec<f32> = data.iter().map(|e| e * 3.0).collect();
assert_eq!(expected, output_vector);
# // The line below is needed for doctest, please ignore it
# Ok::<(), Box<dyn std::error::Error>>(())

预构建库支持

如编译部分所述(编译部分),libtensorflowlite_c 会在编译过程中构建,这一步骤可能需要几分钟。为了重用预构建库,可以设置 TFLITEC_PREBUILT_PATH 或环境变量 TFLITEC_PREBUILT_PATH_<NORMALIZED_TARGET>(后者优先级更高)。NORMALIZED_TARGET 是目标三元组,它将被转换为大写和下划线,如 cargo 配置环境变量中所示。以下是一些不同 TARGET 的示例值

  • TFLITEC_PREBUILT_PATH_AARCH64_APPLE_IOS=/路径//TensorFlowLiteC.框架
  • TFLITEC_PREBUILT_PATH_ARMV7_LINUX_ANDROIDEABI=/路径//libtensorflowlite_c.so
  • TFLITEC_PREBUILT_PATH_X86_64_APPLE_DARWIN=/路径//libtensorflowlite_c.dylib
  • TFLITEC_PREBUILT_PATH_X86_64_PC_WINDOWS_MSVC=/path/to/tensorflowlite_c.dll。**注意**,预构建的 .dll 文件必须在同一目录下有对应的 .lib 文件。

您可以在第一次编译库后在这些文件中找到 OUT_DIR,然后将它们复制到持久路径并设置环境变量。

XNNPACK 支持

您也可以使用预构建库激活 xnnpack 功能。然而,您必须使用 XNNPACK 构建该库,否则您将看到链接错误。

本地头文件目录支持

在编译过程中,一些 tensorflow 头文件会从 GitHub 下载,无论是否使用预构建的二进制文件。然而,一些用户可能难以访问 GitHub。因此,可以通过 TFLITEC_HEADER_DIRTFLITEC_HEADER_DIR_<NORMALIZED_TARGET> 环境变量(后者优先级更高)传递头文件目录。以下是一个示例命令

TFLITEC_HEADER_DIR=/path/to/tensorflow_v2.9.1_headers cargo build --release
# Structure of /path/to/tensorflow_v2.9.1_headers is given below:
# tensorflow_v2.9.1_headers
# └── tensorflow
#     └── lite
#         ├── c
#         │ ├── c_api.h            # Required
#         │ ├── c_api_types.h      # Required
#         │ └── common.h           # Required if xnnpack enabled
#         └── delegates
#             └── xnnpack
#                 └── xnnpack_delegate.h  # Required if xnnpack enabled

链接

此库构建 libtensorflowlite_c **动态库**,必须将其链接到它。如果您使用 cargo 编译并运行二进制目标,这不是问题。但是,如果您直接运行二进制文件,**必须**在库搜索路径中具有 libtensorflowlite_c 动态库。您可以将构建的库复制到系统库搜索路径(例如 /usr/lib/usr/local/lib)或将其目录(out)添加到搜索路径。

类似地,如果您分发依赖于此的预构建库,您也必须分发 libtensorflowlite_c。或者,在您的库中记录此警告,以指导您的用户。

编译

当前版本的crate构建了tensorflow项目的标签 v2.9.1。编译的动态库或框架将在OUT_DIR(见 cargo文档)下可用,这是tflitec的。在大多数情况下,你不需要这个,因为crate的输出已经适当链接。此外,建议阅读预构建库支持部分,以使你的构建更快。对于所有环境和目标,你都需要有以下内容:

优化构建

为了使用本地优化为你的机器构建TensorFlow或向Bazel传递其他--copts,设置以下环境变量:

TFLITEC_BAZEL_COPTS="OPT1 OPT2 ..." # space seperated values will be passed as `--copt=OPTN` to bazel
TFLITEC_BAZEL_COPTS="-march=native" # for native optimized build
# You can set target specific opts by appending normalized target to variable name
TFLITEC_BAZEL_COPTS_X86_64_APPLE_DARWIN="-march=native"

某些操作系统或目标可能需要额外的步骤。

Android

  • Android NDK
  • 以下环境变量需要正确设置,才能为android构建TensorFlow
    • ANDROID_NDK_HOME
    • ANDROID_NDK_API_LEVEL
    • ANDROID_SDK_HOME
    • ANDROID_API_LEVEL
    • ANDROID_BUILD_TOOLS_VERSION
  • Bindgen需要额外的参数,因此设置以下环境变量:
# Set appropriate host tag and target name.
# see https://android-docs.cn/ndk/guides/other_build_systems
HOST_TAG=darwin-x86_64 # as example
TARGET_TRIPLE=arm-linux-androideabi # as example
BINDGEN_EXTRA_CLANG_ARGS="\
-I${ANDROID_NDK_HOME}/sources/cxx-stl/llvm-libc++/include/ \
-I${ANDROID_NDK_HOME}/sysroot/usr/include/ \
-I${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/${HOST_TAG}/sysroot/usr/include/${TARGET_TRIPLE}/"
  • (推荐)cargo-ndk简化了cargo build过程。该工具的最新版本有--bindgen标志,它适当地设置了BINDGEN_EXTRA_CLANG_ARGS变量。因此,你可以跳过上述步骤。

Windows

Windows支持是实验性的。它已在Windows 10上进行了测试。你应该遵循TensorFlow Windows构建说明中的“为Windows设置”部分的说明。换句话说,在构建之前,你应该安装以下内容:

  • Python 3.8.x 64位(说明建议3.6.x,但此软件包与3.8.x进行了测试)
  • Bazel
  • MSYS2
  • Visual C++ Build Tools 2019

不要忘记通过遵循TensorFlow Windows构建说明(唯一例外是Python版本)来将相关路径添加到%PATH%环境变量中。

无运行时依赖

~0–3.5MB
~60K SLoC