当前位置: 首页 > article >正文

解决由于历史原因解析tflite失败的问题

文章目录

  • 0. 背景
  • 1. tflite 历史遗留问题
  • 2. schema
  • 3. flatbuffers 编译器
    • 3.1 安装 FlatBuffers 编译器
    • 3.2. 编译 FlatBuffers schema 文件
    • 3.3 使用生成的 Python 文件
  • 4 问题未解决
  • 终极解决方案

写在最前面:解决方法是升级tensorflow版本,重新生成tflite

0. 背景

今天遇到了这么一个问题:

  File "***/scripts/tflite/schema.py", line 9366, in Tensors
    x = self._tab.Indirect(x)
  File "***/anaconda3/lib/python3.8/site-packages/flatbuffers/table.py", line 46, in Indirect
    return off + encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
  File "***/anaconda3/lib/python3.8/site-packages/flatbuffers/encode.py", line 26, in Get
    return packer_type.unpack_from(memoryview_type(buf), head)[0]
struct.error: unpack_from requires a buffer of at least 1574732 bytes for unpacking 4 bytes at offset 1574728 (actual buffer size is 853240)

我是在解析某个tflite模型的时候遇到这个问题的,而我在解析别的iflite文件的时候是正常的。
于是分析到是tensorflow的schema文件版本差异的问题,在此记录一下解决过程。

1. tflite 历史遗留问题

最开始的时候,tflite 认为 opcode 不会超过 256 个,所以使用了 u8 来存储。后来就超过了 256 个,改成 int 来存储。但是又不能直接改,所以搞了个巧妙的方式:如果 opcode 小于 256,那么还是用 u8 来存,但是大于 256 的就必须走新的 field 了。

不太好的一点就是,他们把老的那个 field 换了名字,而新的 field 直接用了原来的名字,导致直接调用原来的接口名字的函数在不适配他的逻辑的情况下生成的就是全 0 的东西。

这也就是为什么我解析这个 tflite 模型得到的算子全是 ADD 算子。

2. schema

schema.fbs 是一个 FlatBuffers schema 文件,它定义了数据结构。这个文件通常由你自己创建,以匹配你的特定需求。

对于TensorFlow,它们的 FlatBuffers schema 文件是公开的,可以从它们的源代码库中获取。

我在 https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/schema 找到了 schema.fbs 这个文件,将其下载下来。

在这里插入图片描述
同时在这里也可以看到schema之前是有很多版本的。

需要确保 schema.fbs 文件与正在使用的 TensorFlow Lite 版本匹配。如果 schema.fbs 文件与你的 TensorFlow Lite 版本不匹配,可能会遇到问题。

3. flatbuffers 编译器

要使用 FlatBuffers 在 Python 中生成 schema 文件,需要先安装 FlatBuffers 编译器。这个编译器可以将 FlatBuffers schema 文件编译成 Python 类或其他语言的类。

我是使用python,所以在这里记录python。

3.1 安装 FlatBuffers 编译器

在 FlatBuffers 的 GitHub 仓库下载预编译的二进制文件,或者从源代码编译。

使用以下命令从源代码编译 FlatBuffers:

git clone https://github.com/google/flatbuffers.git
cd flatbuffers
mkdir build
cd build
cmake ..
make flatc

编译完成后,FlatBuffers 编译器(flatc)将位于 flatbuffers 目录。

3.2. 编译 FlatBuffers schema 文件

假设你的 FlatBuffers schema 文件名为 schema.fbs,你可以使用以下命令编译它:

./flatc --python schema.fbs
这在当前目录生成一个名为 tflite 的文件夹。

或者,使用
./flatc -p --gen-onefile schema.fbs
得到文件schema_generated.py,这样子好管理版本,但是使代码变得难以管理和阅读,因为所有的代码都在一个文件中。schema.fbs 文件中定义了很多的表和结构,生成的 Python 代码会非常长。

我个人是喜欢用前者生成一个python文件,需要参考源码的时候去后者生成的文件夹里找源码看。

3.3 使用生成的 Python 文件

import schema

# 读取 TFLite 模型文件。
with open('your_model.tflite', 'rb') as f:
    buf = f.read()

# 使用 schema 模块解析模型。
model = schema.Model.GetRootAsModel(buf, 0)

# 现在,你可以使用 model 对象来访问模型的各种属性。
# 例如,你可以获取模型中的操作符数量:
print(model.OperatorCodesLength())

# 或者,你可以获取模型中的第一个操作符的类型:
op_code = model.OperatorCodes(0)
print(op_code.BuiltinCode())

4 问题未解决

我更换了其他版本的 schema.fbs 之后,问题还是没有解决。。。
看来不是schema的问题

需要在解析的时候做以下修改:

tfliteOpSet[tfliteOp->opcode_index]->builtin_code

改成

static_cast<tflite::BuiltinOperator>(tfliteOpSet[tfliteOp->opcode_index]->deprecated_builtin_code)

  • tfliteOpSet[tfliteOp->opcode_index]->builtin_code:这里使用的是builtin_code,这是TensorFlow Lite中内建操作的枚举值。这种方式是推荐的,因为builtin_code是最新的,包含了所有的TensorFlow Lite内建操作。

  • static_cast<tflite::BuiltinOperator>(tfliteOpSet[tfliteOp->opcode_index]->deprecated_builtin_code):这里使用的是 deprecated_builtin_code,这是在旧版本的TensorFlow Lite中使用的,现在已经被标记为弃用(deprecated)。static_cast<tflite::BuiltinOperator>是将 deprecated_builtin_code 转换为 BuiltinOperator 枚举类型。这种方式不推荐使用,因为 deprecated_builtin_code 可能不包含所有的TensorFlow Lite内建操作。

终极解决方案

升级tensorflow版本,重新生成tflite。


http://www.kler.cn/a/274539.html

相关文章:

  • 鸿蒙学习笔记:用户登录界面
  • 3. Kafka入门—安装与基本命令
  • SpringBoot 启动类 SpringApplication 二 run方法
  • 使用 Docker 打包和运行 Vue 应用
  • kafka常用命令(持续更新)
  • 智慧商城:购物车模块基本静态结构 + 构建vuex cart模块,获取数据存储(异步actions)
  • 一款非常流行的数字音乐工作站软件FL Studio for Mac 21.2.3.3586中文版新功能特色
  • uniapp rich-text组件在苹果手机上最多显示两行样式失效
  • 课时69:流程控制_for循环_for (())案例
  • 10 Internet基本服务(3)
  • VMware的安装和Ubuntu的配置安装
  • 奥特曼剧透GPT-5,将在高级推理功能上实现重大进步
  • Java-Java基础学习(2)-网络编程-TCP-UDP
  • Spring Boot 自动化单元测试类的编写过程
  • LeetCode 热题100 图论专题解析
  • C#,图论与图算法,有向图(Graph)之环(Cycle)判断的颜色算法与源代码
  • WiFi是可以连接网络,但是在Pixel 手机上就连接提示受阻,无法上网-解决方法
  • 大数据面试题 —— HBase
  • [LLM] 大模型基础|预训练|有监督微调SFT | 推理
  • node.js 的常用命令
  • SLAM 求解IPC算法
  • SQL的INSERT IGNORE用法
  • .NET 异步编程(异步方法、异步委托、CancellationToken、WhenAll、yield)
  • 图像分割在疾病诊断中的应用案例
  • 无法加载DLL“SQLite.Interop.dll“:找不到指定模块
  • Linux作业