sipeed / TinyMaix

TinyMaix is a tiny inference library for microcontrollers (TinyML).
Apache License 2.0
879 stars 142 forks source link

make the examples more easy to port #25

Closed windfallw closed 1 year ago

windfallw commented 1 year ago

Description:

I'm tring to make the examples more easy to port to any other platform, most of the changes focus on how to make TinyMaix as an universal library.

Changes:

  1. add tm_examples.h as the entrance of all the demos (only support 4 demos currently)

  2. rename auto_test.py to build_test.py and make it more useful

  3. in tool directory (TODO)

    • changes some of the model convert scripts to make each models generate their unique header file.(the variable that stored the model were mdl_data before)
    • add convert.py to covert all the examples needed models. (but I couldn't find the way to do this, only find mnist and mbnet convert method in auto_test.py)

Tested on macOS and ESP-IDF

Zepan commented 1 year ago

emm,这涉及到设计思路的细节,我还是以中文表达才能比较准确描述我的想法,你也可以使用中文来交流讨论。

  1. 关于模型转换脚本固定相关宏名称的原因,主要是两方面原因,使用角度考虑和实际场景考虑。

    1. 使用角度,最早版本我也是根据模型名去生成对应名字,但是我发现,在实际使用过程中,经常会有一些中间版本的模型名字,比如 mbnet_96_v1 , mbnet_96_v1.0902 等临时的命名,一是导致宏定义名字很长很丑,二是我每次换一个模型还需要去主函数里手工修改对应的宏定义字符串,导致调试过程不太顺畅。反之固定相关名称,我只需要执行一次模型转换,再执行一次编译即可查看运行结果。
    2. 实际场景考虑,TinyMaix在实际TinyML场景里,由于单片机性能限制,大部分情况只会运行一个模型,所以固定名称没有问题。即使多个模型的情况下,我也更倾向于用户在转换脚本生成的文件里手工修改自己想要的相关名称(如上一点所示,因为模型名的命名可能是混乱较长的,自动生成的名字不美观)
  2. 关于为什么不把多个测试用例合并到一个例程里,这个差别比较轻微,我描述下我略微倾向于多个例程分开的原因

    1. 历史原因,这几个demo是一个个加上去的,所以它们天然是分开的独立工程
    2. 心智负担原因,TinyMaix希望使用者承担尽可能小的心智负担,也就是希望用户能简单地一眼看到底,而不要看到一层层代码和构建代码产生畏难情绪。所以单独的小工程对新用户来说可以使得他们更有信心。
    3. 考虑到IDE兼容的问题,因为很多单片机开发者水平局限于使用IDE开发,目前独立小工程的方式,比较适合用户拷贝到类似MDK之类的IDE项目里,因为在这些IDE里使用cmake相关操作需要手工修改,比较麻烦。
    4. 所以如果评测者希望有一个快速评测所有模型速度的方式的话,我会考虑到不影响普通用户的使用体验,新建一个专用benchmark工程
  3. auto_test这个原本是我临时手写的测试脚本,所以就是简单复制粘贴了,你的改动可以的,我稍后再完善下

综上所述,目前计划是,1.增加一个独立benchmark工程进行单纯的评测操作;2.完善自动测试脚本。

windfallw commented 1 year ago
  1. 关于模型转换脚本固定相关宏名称的原因,主要是两方面原因,使用角度考虑和实际场景考虑。

模型和宏名称可以固定,但考虑到如果有包含多个模型的需求的话,最好以static声明mdl_data数组,另外两个宏定义MDLBUFLENLBUFLEN在包含多个模型的时候可能会覆盖。可以给模型转换脚本增加一个可选的是否根据模型名称生成头文件的功能。

比如 mbnet_96_v1 , mbnet_96_v1.0902 等临时的命名

关于这个版本号的问题完全可以在python转换脚本中直接把版本号给截断。

反之固定相关名称,我只需要执行一次模型转换,再执行一次编译即可查看运行结果。

如果示例模型的命名是按一个格式固定来命名的话我觉得完全可以做到只填写一次模型名。

我也更倾向于用户在转换脚本生成的文件里手工修改自己想要的相关名称

可以给模型转换脚本增加一个可选字段,用于判断是否根据模型名称生成头文件,方便有需要的用户。

关于为什么不把多个测试用例合并到一个例程里,这个差别比较轻微,我描述下我略微倾向于多个例程分开的原因

使用mdk类ide的用户并不需要给cmake的命令执行加上如 cmake -DMNIST=1 -DCIFAR10=0 -DVWW=0 -DMBNET=0 .. 来启动对应示例,只需要包含tm_examples.h,并在其中将对应的demo的宏定义由0修改为1即可编译相对应的demo。 给cmake添加这个命令主要是为了方便auto_test.py现在是build_test.py进行快速测试,也就是说只有build_test.py才需要给cmake传参,因为它是自动脚本不能像人一样手动的在tm_examples.h中开启相应的demo。 因此例程完全可以合并到一起,并且使用难度反而比之前的更低。如果实在要分开的话,其实也可以做到共存。只需要给单独的例程中的CMakeLists.txt给加回去,并加上一个宏定义,这个宏定义用于判断当前例程的头文件是包含外部的tm_examples.h还是直接包含tinymaix.h即可。

需要修改的地方可以告诉我,我可以进行修改。

另外我可以上传一个Platformio直接 include tm_examples.h 编译例程的demo方便说明

Zepan commented 1 year ago

对于tm_examples.c来说,它的位置摆放相对于example下其它目录位置是异常的,自然的设计是example下每个目录的关系是平等的, 但tm_examples.c使得某几个目录的地位不同于其它example,不是很自然。

总的来说,你的PR改动带来的效果比较微妙,两种方式都说的过去,对于不同使用习惯的用户来说可能会有不同立场 你的提交我也反复斟酌了一个多小时,但是想想为了这些细微的差别花时间去比较确实意义不大。 benchmark毕竟只是评测场景,最近我在设计maixbox(上层具体应用工具箱),我会根据实际应用场景里的使用便利性去微调下层设计。 感谢你的关注与支持!