在NXP i.MX 8上部署TensorFlow Lite Flex Delegate:解决边缘AI算子兼容性问题

发布时间:2026/6/8 14:06:32

在NXP i.MX 8上部署TensorFlow Lite Flex Delegate:解决边缘AI算子兼容性问题 1. 项目概述在嵌入式边缘AI项目的实际部署中我们常常会遇到一个棘手的问题辛辛苦苦在云端训练好的TensorFlow模型准备部署到像NXP i.MX 8这样的嵌入式Linux平台时TensorFlow LiteTFLite转换器却报错提示某个算子不支持。比如模型里用了一个tf.roll操作这在完整的TensorFlow里是再普通不过的算子但在TFLite的标准算子库里却找不到。这时候摆在工程师面前的路通常只有两条要么修改模型结构用TFLite支持的算子去近似替代但这往往意味着模型精度或性能的损失要么就得自己动手为TFLite实现一个自定义算子Custom Op这又引入了额外的开发和维护成本。有没有一种方法能让我们在享受TFLite轻量、高效运行时优势的同时又能直接调用那些“超纲”的完整TensorFlow算子呢答案是肯定的这就是TensorFlow Lite Flex Delegate。你可以把它理解为一个“桥梁”或“适配器”。当TFLite解释器在执行模型时遇到它自身不认识的算子Flex Delegate会把这个算子“转交”给内置的、精简版的TensorFlow运行时去执行。这样一来我们就能在资源受限的边缘设备上运行几乎任何用标准TensorFlow训练出来的模型而无需进行伤筋动骨的模型手术。本文将以NXP i.MX 8系列处理器的Yocto Linux平台为实战环境手把手带你完成从源码构建支持Flex Delegate的TFLite运行时库到部署运行包含特殊算子模型的完整流程。无论你是正在为模型部署头疼的嵌入式AI工程师还是对边缘计算感兴趣并希望深入理解TFLite扩展机制的开发者这篇基于NXP官方应用笔记AN13699的深度实践指南都将为你提供可直接复现的“操作手册”和背后的原理剖析。2. 核心原理为什么需要Flex Delegate在深入动手之前我们有必要先厘清Flex Delegate解决的核心问题及其工作原理。这能帮助我们在后续遇到复杂情况时做出正确的判断和决策。2.1 TensorFlow Lite的算子生态与局限TensorFlow Lite的设计哲学是“轻量”与“高效”。为了在手机、微控制器和嵌入式Linux设备上流畅运行它对完整的TensorFlow算子集进行了大幅裁剪。TFLite内置的算子Built-in Ops只有一百多个涵盖了卷积、池化、全连接等最常见的神经网络层。而完整的TensorFlow算子库则庞大得多超过一万个包含各种数据处理、数学运算和特殊的神经网络操作。这种差异直接导致了兼容性问题。当你尝试用TFLiteConverter转换一个包含tf.roll、tf.image.resize等非内置算子的模型时转换器会明确报错Some operators are not supported by the native TFLite runtime, but you can enable the TF kernels fallback using TF Select. TF Select ops: Roll这条错误信息正是我们整个任务的起点。它指出了问题Roll算子不被支持也暗示了解决方案启用TF Select即Flex Delegate的前端配置。2.2 Flex Delegate的桥梁作用Flex Delegate的本质是一个TFLite委托Delegate。TFLite的委托机制允许将模型或模型的一部分计算卸载到特定的硬件加速器如GPU、NPU或软件后端上执行。Flex Delegate就是一种特殊的软件委托它的后端不是硬件而是一个内置的、轻量级的TensorFlow运行时。它的工作流程可以概括为以下几步模型转换在转换模型时我们通过converter.target_spec.supported_ops参数显式声明支持tf.lite.OpsSet.SELECT_TF_OPS。这告诉转换器“遇到TFLite不支持的算子时不要报错把它标记为‘需由Flex委托处理’”。运行时加载在设备端我们加载的TFLite解释器需要链接或动态加载libtensorflowlite_flex.so这个库。这个库包含了Flex Delegate的实现以及一个精简的TensorFlow运行时。算子分发当解释器执行模型时遇到被标记的算子它会将计算任务和所需的张量数据传递给Flex Delegate。TF运行时执行Flex Delegate调用其内部的TensorFlow运行时来执行该算子并将结果返回给TFLite解释器从而完成一次“混合执行”。注意启用Flex Delegate会显著增加运行时库的体积约120MB因为它需要打包一部分TensorFlow运行时的核心功能。这是为了获得算子灵活性所必须付出的存储空间代价。2.3 i.MX 8平台上的协同加速i.MX 8系列芯片通常集成了CPU、GPU和NPU神经处理单元。NXP为其提供了VX Delegate用于将TFLite算子加速到GPU或NPU上。这里有一个关键点Flex Delegate处理的TensorFlow算子目前无法被硬件加速它们会回退到CPU上执行。但这并不意味着整个模型都变慢了。一个模型可以同时包含TFLite内置算子和TensorFlow算子。其执行模式是TFLite内置算子由VX Delegate如果启用尝试加速到GPU/NPU否则由TFLite的CPU内核执行。TensorFlow算子通过SELECT_TF_OPS由Flex Delegate在CPU上执行。因此模型性能取决于两种算子的比例和硬件加速器的支持情况。对于包含少量特殊算子的模型整体性能依然可以受益于硬件加速。3. 构建支持Flex Delegate的TensorFlow Lite运行时理论清晰后我们进入实战环节。首先需要在开发主机上构建出能在ARM架构的i.MX 8平台上运行的TFLite Flex Delegate库。NXP官方推荐使用Bazel构建系统和Docker环境以规避复杂的依赖问题。3.1 构建环境准备与源码获取构建环境的选择至关重要。虽然可以在宿主机直接安装Bazel但版本管理和依赖冲突极易导致构建失败。使用TensorFlow官方维护的Docker镜像是最稳妥的方案。步骤一获取特定分支的TensorFlow源码Flex Delegate的构建依赖于TensorFlow源码树。NXP维护了一个包含i.MX平台优化和示例的分支。# 克隆NXP维护的TensorFlow仓库 git clone https://github.com/NXPmicro/tensorflow.git cd tensorflow # 切换到包含ODTOn-Device Training示例的分支该分支也包含了构建Flex Delegate所需的所有配置 git checkout imx-ODT-example实操心得务必使用imx-ODT-example分支。主分支或其他分支的构建配置可能不包含针对elinux_aarch64嵌入式Linux ARM64的完整支持导致后续构建失败。步骤二准备Docker构建环境我们将使用TensorFlow的开发镜像它预装了正确版本的Bazel和其他编译工具链。# 拉取TensorFlow开发镜像 docker pull tensorflow/tensorflow:devel # 运行Docker容器并将本地源码目录挂载到容器内 # 注意替换 path-to-tensorflow-sources 为你本地TensorFlow源码的绝对路径 # 如果网络需要代理请设置 http_proxy 和 https_proxy 环境变量 docker run -e http_proxyyour-http-proxy \ -e https_proxyyour-https-proxy \ -e no_proxylocalhost,127.0.0.1 \ -it -w /tensorflow -v /path-to-tensorflow-sources:/tensorflow \ -e HOST_PERMS$(id -u):$(id -g) \ tensorflow/tensorflow:devel bash执行上述命令后你将进入Docker容器的bash shell并且当前工作目录/tensorflow就是挂载的源码目录。步骤三配置构建参数在容器内运行配置脚本。这个脚本会交互式地询问一些编译选项对于交叉编译到ARM平台大部分选项可以直接回车使用默认值。./configure在配置过程中当询问Python路径、CUDA支持等时除非你有特殊需求否则一律选择默认No。我们的目标是在Docker内为ARM设备编译不需要本地GPU支持。3.2 编译Flex Delegate动态库与工具构建环境就绪后就可以开始编译了。我们主要目标是两个产物Flex Delegate动态库.so文件和集成了Flex Delegate的基准测试工具。编译Flex Delegate动态库# 在Docker容器内执行 bazel build --configmonolithic --configelinux_aarch64 -c opt //tensorflow/lite/delegates/flex:tensorflowlite_flex--configmonolithic: 构建单体的TensorFlow减少依赖更适合部署。--configelinux_aarch64: 指定目标平台为嵌入式Linux ARM 64位。-c opt: 启用优化编译。//tensorflow/lite/delegates/flex:tensorflowlite_flex: 要构建的Bazel目标即Flex Delegate共享库。编译完成后库文件位于bazel-bin/tensorflow/lite/delegates/flex/libtensorflowlite_flex.so。编译集成Flex Delegate的benchmark_model工具单独一个动态库还不够我们需要一个能使用它的可执行程序。TensorFlow源码中提供了一个基准测试工具benchmark_model我们可以编译一个它的“增强版”。bazel build --configmonolithic --configelinux_aarch64 -c opt //tensorflow/lite/tools/benchmark:benchmark_model_plus_flex这个命令会生成一个名为benchmark_model_plus_flex的二进制文件。关键在于它的依赖项在BUILD文件中定义deps [ :benchmark_tflite_model_lib, # 基准测试核心逻辑 //tensorflow/lite/delegates/flex:delegate, # **静态链接**的Flex Delegate //tensorflow/lite/testing:init_tensorflow, # 初始化TensorFlow运行时 //tensorflow/lite/tools:logging, ]注意//tensorflow/lite/delegates/flex:delegate这个依赖它意味着Flex Delegate的代码被静态链接到了最终的可执行文件中。因此benchmark_model_plus_flex是一个独立的二进制运行时不需要额外的.so库文件。注意事项上述构建的二进制是静态链接Flex Delegate的。如果你希望使用动态链接例如多个应用共享同一个Flex Delegate库需要修改Bazel构建文件创建一个依赖tensorflowlite_flex.so的动态链接目标。这在官方文档中有提及但静态链接方式对于单一应用部署更为简单和可靠。3.3 针对TensorFlow 2.8.0的构建补丁说明如果你使用的是TensorFlow 2.8.0版本在构建动态链接目标时可能会遇到可见性visibility错误。这是因为相关目标的默认可见性设置可能不允许被其他包引用。需要手动打补丁修改tensorflow/lite/delegates/flex/BUILD文件找到tflite_flex_shared_library规则确保其visibility属性为公开tflite_flex_shared_library( name tensorflowlite_flex, visibility [//visibility:public], # 确保这一行存在 )修改tensorflow/lite/delegates/flex/build_def.bzl文件在tflite_flex_shared_library宏定义中确保tflite_cc_shared_object的visibility参数被正确传递def tflite_flex_shared_library( ... tflite_cc_shared_object( name name, visibility visibility, # 确保visibility参数被传递 ... ) )进行上述修改后再重新执行构建命令即可。4. 在i.MX 8平台部署与运行构建产物需要在目标设备——i.MX 8开发板的Linux文件系统中运行。以下是如何部署和测试的详细步骤。4.1 文件部署与环境配置假设你已经通过SD卡或网络文件系统NFS将i.MX 8的根文件系统挂载到了开发主机上。对于静态链接版本推荐将编译生成的bazel-bin/tensorflow/lite/tools/benchmark/benchmark_model_plus_flex文件复制到目标板的文件系统中例如/usr/local/bin/。赋予可执行权限chmod x /usr/local/bin/benchmark_model_plus_flex。这个二进制文件是自包含的可以直接运行。对于动态链接版本复制动态库bazel-bin/tensorflow/lite/delegates/flex/libtensorflowlite_flex.so到目标板的/usr/lib/目录。或者复制到自定义目录并通过设置LD_LIBRARY_PATH环境变量让系统找到它例如export LD_LIBRARY_PATH/path/to/libs:$LD_LIBRARY_PATH。复制动态链接的可执行文件例如benchmark_model_plus_flex_dynamic到目标板。确保可执行文件有运行权限。4.2 运行第一个示例包含tf.roll的简单模型现在我们将在设备上运行一个实际的模型。首先我们需要一个包含TFLite不支持的算子如tf.roll的模型。以下是创建和转换该模型的Python脚本import tensorflow as tf import numpy as np import os def make_simple_keras_model(input_shape, num_classes): 创建一个包含tf.roll算子的简单CNN模型 inputs tf.keras.layers.Input(shapeinput_shape, namex) x tf.keras.layers.Conv2D(32, 3, paddingvalid, activationrelu)(inputs) x tf.keras.layers.Conv2D(64, 3, paddingvalid, activationrelu)(x) x tf.keras.layers.Flatten()(x) x tf.keras.layers.Dense(num_classes, activationrelu)(x) # 关键插入一个TFLite原生不支持的算子 x tf.roll(x, shift1, axis1) outputs tf.keras.layers.Softmax()(x) return tf.keras.Model(inputs, outputs) def convert_and_quantize_model_to_tflite(saved_model_dir, representative_data_gen): 转换并量化模型关键步骤是启用SELECT_TF_OPS converter tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations [tf.lite.Optimize.DEFAULT] # 启用默认优化包含量化 converter.representative_dataset representative_data_gen # 量化校准数据集 # **核心配置启用TensorFlow算子支持** converter.target_spec.supported_ops [ tf.lite.OpsSet.TFLITE_BUILTINS_INT8, # 支持int8量化的内置算子 tf.lite.OpsSet.SELECT_TF_OPS # 启用TensorFlow算子回退 ] converter.inference_input_type tf.int8 converter.inference_output_type tf.int8 # 使用新版转换器和量化器TF 2.x推荐 converter.experimental_new_converter True converter.experimental_new_quantizer True tflite_model_quant_int8 converter.convert() return tflite_model_quant_int8 if __name__ __main__: # 1. 创建并训练一个简单模型此处用MNIST示例 model make_simple_keras_model((28, 28, 1), 10) model.summary() (train_images, train_labels), _ tf.keras.datasets.mnist.load_data() train_images train_images / 255.0 train_labels tf.keras.utils.to_categorical(train_labels) model.compile(optimizeradam, losscategorical_crossentropy, metrics[accuracy]) model.fit(train_images, train_labels, batch_size32, epochs1) # 快速训练一个epoch # 2. 保存为SavedModel格式 SAVE_DIR SimpleFlexModel/ tf.saved_model.save(model, SAVE_DIR) # 3. 准备量化用的代表性数据集生成器 def representative_dataset_gen(): for i in range(100): # yield一个批次的输入数据格式需与模型输入匹配 yield [train_images[i].astype(np.float32).reshape(1, 28, 28, 1)] # 4. 转换并保存模型 tflite_quant_model convert_and_quantize_model_to_tflite(SAVE_DIR, representative_dataset_gen) with open(os.path.join(SAVE_DIR, simple_flex_model_int8.tflite), wb) as f: f.write(tflite_quant_model) print(模型已保存为 simple_flex_model_int8.tflite)将生成的simple_flex_model_int8.tflite文件复制到i.MX 8开发板上。在设备上运行推理并启用硬件加速 在i.MX 8开发板的终端中执行以下命令# 切换到模型所在目录 cd /path/to/your/model # 使用静态链接的benchmark工具并指定VX Delegate进行硬件加速 ./benchmark_model_plus_flex \ --graph./simple_flex_model_int8.tflite \ --enable_op_profilingtrue \ --external_delegate_path/usr/lib/libvx_delegate.so关键参数解析--graph: 指定要运行的TFLite模型文件路径。--enable_op_profilingtrue: 启用算子级性能分析输出每个算子的执行时间。--external_delegate_path: 指定外部委托库VX Delegate的路径。这将使模型中TFLite内置的算子如Conv2D尝试在GPU/NPU上加速执行。分析输出结果 命令执行后你会看到类似如下的输出片段INFO: Created TensorFlow Lite delegate for select TF ops. INFO: TfLiteFlexDelegate delegate: 1 nodes delegated out of 8 nodes with 1 partitions. ... Operator-wise Profiling Info: Run Order [node type] [start] [first] [avg ms] [times called] [Name] Vx Delegate 0.089 0.460 0.444 1 [tfl.dequantize]:9 TfLiteFlexDelegate 0.533 0.251 0.332 1 [model/tf.roll/Roll]:8 Vx Delegate 0.865 0.119 0.157 1 [StatefulPartitionedCall:0]:10 ...从分析结果中可以清晰看到TfLiteFlexDelegate接管了名为[model/tf.roll/Roll]:8的算子节点这正是我们模型中插入的tf.roll操作。其他算子如反量化tfl.dequantize和最后的调用节点由Vx Delegate处理这意味着它们被成功卸载到了硬件加速器上。这完美印证了混合执行模式Flex Delegate处理特殊算子CPUVX Delegate加速标准算子GPU/NPU。5. 进阶应用在设备端进行模型训练On-Device TrainingFlex Delegate更强大的一个应用场景是支持端侧训练On-Device Training, ODT。传统的TFLite只负责推理而ODT允许设备利用新收集的数据对已有模型进行微调fine-tuning实现个性化适配同时保护数据隐私。这需要调用更复杂的TensorFlow算子如梯度计算、优化器更新等。5.1 获取与编译端侧训练示例NXP在imx-ODT-example分支中提供了一个适配好的端侧训练C示例。# 在之前已拉取源码并进入Docker容器的环境下编译示例程序 bazel build --configmonolithic --configelinux_aarch64 -c opt //tensorflow/lite/examples/label_image_odt:label_image_odt编译产物是label_image_odt二进制它已经静态链接了Flex Delegate。5.2 准备模型与数据端侧训练模型需要使用支持“签名Signatures”的格式。你可以按照 TensorFlow官方示例 使用Jupyter Notebook生成一个包含train、infer、save、load等多个签名的TFLite模型。这里我们假设你已经获得了一个名为odt-model-empty.tflite的未训练初始模型。数据方面需要将训练集和测试集例如Fashion MNIST转换为程序可读的格式。示例程序通常支持读取图片文件。可以使用以下Python脚本准备数据import tensorflow as tf import os import pathlib from PIL import Image def save_mnist_to_images(path, images, labels): 将MNIST数据保存为按类别分类的bmp图片 base_path pathlib.Path(path) base_path.mkdir(parentsTrue, exist_okTrue) # 创建0-9共10个子目录 for label in range(10): (base_path / str(label)).mkdir(parentsTrue, exist_okTrue) # 保存图片 for idx, (image, label) in enumerate(zip(images, labels)): dest_path base_path / str(label) / f{idx}.bmp img_array image.reshape(28, 28).astype(uint8) img Image.fromarray(img_array, modeL) img.save(dest_path) # 加载Fashion MNIST数据集 (train_images, train_labels), (test_images, test_labels) tf.keras.datasets.fashion_mnist.load_data() # 保存为图片 save_mnist_to_images(./dataset/fashion_mnist/train, train_images, train_labels) save_mnist_to_images(./dataset/fashion_mnist/test, test_images, test_labels)将生成的fashion_mnist文件夹、odt-model-empty.tflite模型文件和label_image_odt可执行文件一同复制到i.MX 8设备上的同一个目录例如~/odt_demo。5.3 在设备上执行训练与推理在开发板的终端中运行以下命令启动端侧训练cd ~/odt_demo ./label_image_odt \ --train_dataset ./fashion_mnist/train \ --test_dataset ./fashion_mnist/test \ -m ./odt-model-empty.tflite \ --num_epochs 5 \ --batch_size 1000 \ --save_path ./tmp/checkpoint.ckpt--train_dataset/--test_dataset: 指定训练和测试数据集的图片目录路径。-m: 指定包含训练签名的TFLite模型文件。--num_epochs: 训练轮数。--batch_size: 批处理大小。--save_path: 训练后权重检查点的保存路径。程序会读取数据在设备上执行指定轮数的训练并定期在测试集上评估准确率。训练完成后会将更新后的模型权重保存到指定的检查点文件。这个过程完全在设备端CPU上完成利用了Flex Delegate来执行反向传播、优化器更新等训练算子。5.4 核心代码机制解析端侧训练示例的核心在于利用TFLite的**签名Signature**机制。一个模型可以定义多个签名每个签名相当于模型的一个子图有特定的输入和输出。在ODT模型中train签名用于执行一个训练步骤前向传播、损失计算、反向传播、权重更新。infer签名用于使用训练后的权重进行推理。save/load签名用于将内存中的权重保存到文件或从文件加载。C代码的关键操作如下// 1. 加载模型并创建解释器 std::unique_ptrtflite::Interpreter interpreter; tflite::ops::builtin::BuiltinOpResolver resolver; tflite::InterpreterBuilder(*model, resolver)(interpreter); // 2. 分配张量 interpreter-AllocateTensors(); // 3. 获取“train”签名运行器SignatureRunner auto* train_runner interpreter-GetSignatureRunner(train); // 4. 为签名运行器分配输入/输出张量通过名称索引 TfLiteTensor* input_x train_runner-input_tensor(x); TfLiteTensor* input_y train_runner-input_tensor(y); // ... 将训练数据填充到 input_x 和 input_y ... // 5. 执行一个训练步骤 train_runner-Invoke(); // 6. 训练后使用“save”签名保存权重 auto* save_runner interpreter-GetSignatureRunner(save); // ... 设置保存路径到save签名的输入张量 ... save_runner-Invoke();整个过程中train和save签名内部的复杂算子如GradientTape、优化器apply_gradients都是由Flex Delegate在CPU上处理的。6. 常见问题、限制与排查技巧在实际部署Flex Delegate的过程中你可能会遇到各种问题。以下是一些常见情况的排查思路和当前方案的限制。6.1 构建与编译问题问题1Bazel构建失败提示找不到工具链或配置错误。排查确保严格按照步骤使用tensorflow/tensorflow:develDocker镜像。宿主机环境差异极大Docker能保证环境一致性。检查确认在Docker内运行了./configure脚本并为所有问题选择了适合交叉编译的选项通常选N或默认。解决清理Bazel缓存后重试bazel clean --expunge。问题2编译benchmark_model_plus_flex时链接失败提示Flex Delegate相关符号未定义。排查这通常是因为//tensorflow/lite/delegates/flex:delegate这个静态库目标没有正确构建或包含。解决确保先成功构建了//tensorflow/lite/delegates/flex:tensorflowlite_flex。可以尝试单独构建该目标确认无报错后再构建benchmark工具。6.2 运行时问题问题1在设备上运行程序时报错“ERROR: TfLiteFlexDelegate delegate: Failed to create/init Flex delegate.”排查这是最典型的错误意味着Flex Delegate初始化失败。可能原因及解决动态库缺失或路径错误对于动态链接版本确保libtensorflowlite_flex.so位于系统的库路径如/usr/lib下或LD_LIBRARY_PATH环境变量已正确设置。使用ldd benchmark_model_plus_flex_dynamic检查依赖。模型未启用SELECT_TF_OPS使用xxd或文本编辑器查看.tflite文件开头搜索字符串SELECT_TF_OPS。如果找不到说明模型转换时未添加该选项需要重新转换模型。TensorFlow算子仍不支持Flex Delegate支持大部分但非全部TensorFlow算子。极少数非常冷门或依赖特定资源的算子可能仍不支持。查看TFLite转换时的完整错误日志。问题2启用VX Delegate后程序崩溃或无加速效果。排查首先在不使用--external_delegate_path参数的情况下运行确认模型仅用Flex DelegateCPU可以正常工作。检查确认libvx_delegate.so库文件存在于指定路径并且与TFLite版本兼容。NXP的BSP通常会提供该库。分析查看--enable_op_profilingtrue的输出确认哪些算子被委托给了Vx Delegate。如果所有算子都在TfLiteFlexDelegate或CPU上可能是模型中的算子都不被VX Delegate支持或者委托库加载失败。6.3 当前方案的限制了解限制有助于合理设计你的边缘AI应用二进制体积巨大包含Flex Delegate的TFLite运行时库约120MB比纯TFLite运行时大很多。这对于存储空间极度受限的设备可能是个问题。目前TFLite的算子选择性链接用于裁剪库大小功能在Linux平台上支持不完善。Flex算子仅限CPU通过Flex Delegate执行的TensorFlow算子无法利用i.MX 8的GPU/NPU进行硬件加速。性能关键路径上的算子如果必须是TensorFlow算子则需要评估CPU执行的性能是否满足要求。端侧训练的硬件加速限制训练过程目前端侧训练的所有操作包括前向、反向传播都只能在CPU上执行无法加速。推理过程即使训练后的模型用于推理如果其infer签名中包含动态形状的张量这是训练模型的常见情况它也可能无法被VX Delegate加速因为许多硬件加速器要求固定的输入输出维度。量化支持为包含训练签名的模型进行训练后量化Post-training quantization或量化感知训练Quantization-aware training目前可能遇到TFLite转换器的限制需要仔细测试。内存消耗Flex Delegate会加载一个轻量化的TensorFlow运行时这会增加运行时的内存占用。在内存紧张的设备上需要监控内存使用情况。6.4 性能优化建议算子融合与替换在模型设计阶段尽可能使用TFLite原生支持的算子。如果必须使用TensorFlow算子考虑是否可以用一组TFLite算子来模拟其功能虽然可能增加计算图复杂度但可能获得硬件加速的整体收益。性能剖析务必使用--enable_op_profilingtrue参数进行分析。识别出是哪些Flex算子成为了性能瓶颈。如果只有一两个算子且计算量不大影响可能可接受如果存在大量复杂算子则需要重新评估模型设计。分批处理对于端侧训练合理设置batch_size。太小的batch size无法充分利用CPU的SIMD指令如NEON太大的batch size可能导致内存不足。需要通过实验找到设备上的最佳值。使用更高效的模型格式考虑将训练好的、包含Flex算子的模型通过tf.lite.TFLiteConverter的target_spec.supported_ops设置为[tf.lite.OpsSet.TFLITE_BUILTINS]进行重新转换如果可能看看转换器是否已经能够将某些复杂操作分解为内置算子从而完全摆脱对Flex Delegate的依赖。

相关新闻