TFLM_day7
发布时间:2026/9/29 9:38:02 锦皓数字建站

轻松学习 TFLM Day 7:把.tflite模型接到 TFLM 示例里摘要:本文以 TFLM 仓库自带的hello_world示例为入口,完整演示如何把一个.tflite模型接入 TFLM 并完成一次真实推理。内容涵盖:模型接入的完整链路、.tflite转 C 数组的三种方式(Bazel 规则、命令行脚本、手动生成)及验证方法、最小接入代码、完整可编译示例、int8 量化模型的输入量化与输出反量化、Bazel 模型规则配置、常见报错定位,以及面向 AI 芯片的接入检查清单。核心思路是:先把模型编译成 C 数组,再通过GetModel→MicroMutableOpResolver→MicroInterpreter→AllocateTensors→Invoke完成推理,并强调「先 host 后硬件」的调试顺序。Day 6 我们已经知道如何从模型找出需要注册的 op。今天继续做完整实战:把一个.tflite模型放进 TFLM 示例,让它完成一次真实推理。本章以仓库自带的hello_world为入口。它的结构简单,适合先在 macOS/Linux host 上验证,再迁移到 MCU、DSP 或 NPU 平台。1. 模型接入的完整链路TFLM 不能直接把文件路径传给MicroInterpreter。嵌入式程序通常需要把.tflite内容编译成 C/C++ 数组:my_model.tflite | | Bazel generate_cc_arrays v my_model_data.cc + my_model_data.h | v const unsigned char g_my_model_data[] | | tflite::GetModel(...) v MicroInterpreter | v AllocateTensors - 写入输入 - Invoke - 读取输出除了模型本身,还必须准备:内容作用op resolver给模型中的每种 op 找到 registration。tensor arena保存 tensor、OpData 和 scratch buffer。输入转换把应用数据转换成模型需要的类型和量化格式。输出转换把模型输出转换成应用可以理解的结果。构建规则把模型数组、示例代码和 TFLM runtime 链接起来。2. 先选择一个具体模型本文使用仓库中的:tensorflow/lite/micro/examples/hello_world/models/hello_world_float.tflite它的模型特点是:输入:float32,单个数值 输出:float32,单个数值 op:FULLY_CONNECTED对应 resolver:tflite::MicroMutableOpResolver1resolver;resolver.AddFullyConnected();如果你要接入自己的模型,先把下面的路径替换成自己的.tflite文件,并按 Day 6 的方法重新分析 op。3.1 从 .tflite 到 C 数组的完整转换步骤上一节介绍了generate_cc_arrays的 Bazel 规则,这一节我们把它拆开,看看一个.tflite文件到底是怎么变成 C 数组的,以及如何验证转换结果。3.1.1 官方转换工具TFLM 仓库提供了两种方式把.tflite转成 C 数组:方式一:Bazel 规则(推荐,集成到构建系统)在models/BUILD中声明generate_cc_arrays,构建时自动生成:generate_cc_arrays(name="generated_my_model_cc",src="my_model.tflite",out="my_model_data.cc",)generate_cc_arrays(name="generated_my_model_hdr",src="my_model.tflite",out="my_model_data.h",)方式二:命令行工具(适合快速验证)TFLM 仓库提供了独立的转换脚本,可以直接在终端运行:# 从 tflite-micro 仓库根目录执行python tensorflow/lite/micro/tools/convert/convert_to_cc_source.py\--input=my_model.tflite\--output=my_model_data.cc\--output_header=my_model_data.h\--namespace=tflite如果你不想依赖仓库脚本,也可以用xxd或 Python 手动生成:# 用 xxd 生成 C 数组(Linux/macOS)xxd-imy_model.tflitemy_model_data.cc# 用 Python 生成 C 数组(跨平台)withopen("my_model.tflite","rb")asf:data=f.read()withopen("my_model_data.cc","w")asf:f.write("const unsigned char g_my_model_data[] = {\n")foriinrange(0,len(data),12):chunk=data[i:i+12]f.write(" "+", ".join(f"0x{b:02x}"forbinchunk)+",\n")f.write("};\n")f.write(f"const unsigned int g_my_model_data_len ={len(data)};\n")3.1.2 生成文件的格式说明generate_cc_arrays会生成两个文件:my_model_data.cc—— 包含模型字节数组:// 由 generate_cc_arrays 自动生成,不要手工编辑constunsignedcharg_my_model_data[]={0x1c,0x00,0x00,0x00,0x54,0x46,0x4c,0x33,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ... 更多字节};constunsignedintg_my_model_data_len=12345;my_model_data.h—— 声明数组供其他文件引用:// 由 generate_cc_arrays 自动生成,不要手工编辑#ifndefTENSORFLOW_LITE_MICRO_EXAMPLES_HELLO_WORLD_MODELS_MY_MODEL_DATA_H_#defineTENSORFLOW_LITE_MICRO_EXAMPLES_HELLO_WORLD_MODELS_MY_MODEL_DATA_H_externconstunsignedcharg_my_model_data[];externconstunsignedintg_my_model_data_len;#endif// TENSORFLOW_LITE_MICRO_EXAMPLES_HELLO_WORLD_MODELS_MY_MODEL_DATA_H_关键点:数组名g_my_model_data由out参数推导,实际名称以生成文件为准。数组类型固定为unsigned char,每个元素是一个字节。g_my_model_data_len记录模型文件的总字节数,可用于校验。3.1.3 验证生成的数组与原始模型一致转换后一定要验证,避免数组损坏导致运行时崩溃。有三种验证方式:方式一:比较文件大小# 原始 .tflite 文件大小ls-lmy_model.tflite# 生成数组声明的长度grep"g_my_model_data_len"my_model_data.cc两者应该完全一致。方式二:用 Python 校验字节内容importre# 读取原始模型withopen("my_model.tflite","rb")asf:original=f.read()# 从生成的 .cc 文件中提取数组withopen("my_model_data.cc","r")asf
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。