如何在先楫HPM6750上运行轻量级AI推理框架TinyMaix

一、TinyMaix是什么?

TinyMaix是国内sipeed团队开发一个轻量级AI推理框架,官方介绍如下:

TinyMaix 是面向单片机的超轻量级的神经网络推理库,即 TinyML 推理库,可以让你在任意单片机上运行轻量级深度学习模型。

甚至在 Arduino ATmega328 (32KB Flash, 2KB RAM) 上都能基于 TinyMaix 进行手写数字识别。

二、TinyMaix移植

本节介绍如何将TinyMaix移植到HPM6750,详细步骤如下:

2.1 开发环境搭建

先楫官方支持SDK开发环境和RT-Thread开发环境,两种开发环境的搭建方法均可在官方提供的开发板用户手册(HPM6750EVKMINI USER GUIDE.pdf 或 HPM6750EVK USER GUIDE.pdf 文件)中找到,也可以参考我此前发布的帖子,具体见本文最后的参考链接。

考虑到TinyMaix对于现已支持的MCU,基准测试都是基于裸机进行的,因此这里使用的是HPM SDK开发环境。另外,基于裸机的移植在RTOS环境下一般也可以运行。因此,对于MCU芯片的计算类开源项目的移植(例如这里的TinyMaix),最好是基于裸机进行。

使用的HPM SDK版本为0.14.0,使用的SEGGER Embedded Studio版本信息为:

SEGGER Embedded Studio for RISC-V

Release 6.40 Build 2022102501.51567

Windows x64

© 2014-2022 SEGGER Microcontroller GmbH

© 1997-2022 Rowley Associates Ltd.

segger-cc: version 15.0.0

segger-ld: version 4.36.0

segger-rtl: version 4.20.0

GCC/BINUTILS: built using the GNU RISC-V Toolchain version GCC 12.20/Binutils 2.39 source distribution

Clang/LLVM: built using the version 15.0.0 source distribution

2.2 TinyMaix移植步骤

由于TinyMaix本身的源代码文件不多,整个移植过程相对还是比较简单的。

整体基本上分为三步:

  • 目录规划;

  • 修改源码;

  • 编译运行;

下面介绍具体操作步骤。

2.2.1 目录规划

考虑到TinyMaix和hpm_sdk都是使用CMake构建的,为了不对TinyMaix进行过多侵入性修改,这里采取的策略是——添加一个中间层。具体是将HPM6750平台的CMakeLists.txt文件放在TinyMaix源码目录的上一层,如下所示:

hpm_sdk/app/├── CMakeLists.txt # HPM6750平台的CMakeLists.txt├── src│ └── benchmark.c└── TinyMaix/ # TinyMaix源码目录

2.2.2 修改源码

这里在src/benchmark.c文件内容如下:

#include <stdio.h>

#include "board.h"

#define MODEL_MNIST 1#

define MODEL_CIFAR10 2#

define MODEL_VWW 3#

define MODEL_MBNET 4

#define CONFIG_MODEL MODEL_CIFAR10 // 修改这一行切换 测试程序

#define main benchmark_main

#if (CONFIG_MODEL == MODEL_MNIST)

#include "mnist/main.c"#elif (CONFIG_MODEL == MODEL_CIFAR10)

#include "cifar10/main.c"

#elif (CONFIG_MODEL == MODEL_VWW)

#include "vww/main.c"

#elif (CONFIG_MODEL == MODEL_MBNET)

#include "mbnet/label.c"

#include "mbnet/main.c"

#endif

#undef main

int main(void)

{

board_init();

printf("benchmark start...\n");

benchmark_main(0, NULL);

__asm__

("wfi");return 0;

}

为了不直接拷贝基准测试代码,简化代码结构,这里使用了不太常见的:

直接#include 某个.c文件;

在#include "xxx/main.c"前面,定义宏#define main benchmark_main,之后取消宏定义;

这样实现了将TinyMaix原有的测试代码作为benchmark.c一部分,而又不与这里的main函数相冲突的目的。

PS:这里为了简便,并没有把TinyMaix放到hpm_sdk的middleware目录,实际项目中使用的话最好将TinyMaix放到middleware目录。

另外,还需要修改`tm_port.h文件:

diff --git a/include/tm_port.h b/include/tm_port.h

index 357fc6b..5d1768c 100644

--- a/include/tm_port.h

+++ b/include/tm_port.h

@@ -31,7 +31,7 @@ limitations under the License.

#define TM_OPT_LEVEL TM_OPT0

#define TM_MDL_TYPE TM_MDL_INT8

#define TM_FASTSCALE (0) //enable if your chip don't have FPU, may speed up 1/3, but decrease accuracy

-#define TM_LOCAL_MATH (0) //use local math func (like exp()) to avoid libm

+#define TM_LOCAL_MATH (1) //use local math func (like exp()) to avoid libm

#define TM_ENABLE_STAT (1) //enable mdl stat functions

#define TM_MAX_CSIZE (1000) //max channel num //used if INT8 mdl //cost TM_MAX_CSIZE*4 Byte

#define TM_MAX_KSIZE (5*5) //max kernel_size //cost TM_MAX_KSIZE*4 Byte@@ -49,9 +49,10

@@ limitations under the License.

#define TM_DBGL() TM_PRINTF("###L%d\n",__LINE__);

/******************************* DBG TIME CONFIG ************************************/

-#include <sys/time.h>

-#include <time.h>

-#define TM_GET_US() ((uint32_t)((uint64_t)clock()*1000000/CLOCKS_PER_SEC))

+#include "board.h"

+#define TM_GET_US() (uint32_t)(HPM_MCHTMR->MTIME * 1000000uLL / clock_get_frequency(clock_mchtmr0))

#define TM_DBGT_INIT() uint32_t _start,_finish;float _time;_start=TM_GET_US();

#define TM_DBGT_START() _start=TM_GET_US();

2.2.3 编译运行

HPM6750项目的生成命令:

2.2.3 编译运行

HPM6750项目的生成命令:

HPM6750项目的编译、运行,具体可以开发环境搭建文章,链接见本文末尾。

手写数字识别(mnist模型),运行后,串口输出结果如下:

三、基准测试

下面是TinyMaix四种常用的基准测试模型的基准测试,四个模型分别为:

  • mnist——手写数字识别模型,输入28x28x1

  • cifar——10分类模型,输入32x32x3

  • vww——人体检测二分类模型,输入96x96x3,输出有无人

  • mbnet——1000分类模型,输入128x128x3

3.1 场景1: TM_MDL_INT8 + TM_OPT0
3.2 场景2: TM_MDL_INT8 + TM_OPT1
3.3 场景3: TM_MDL_FP32 + TM_OPT0
3.4 注意事项
  • 在SEGGER Embedded Studio中, 可以通过如下菜单Project 'xxx' Options -> Code -> Code Generation -> Optimization Level修改优化等级;

  • 在SEGGER Embedded Studio中, 默认的堆大小设置为16384 字节(16KB),不够运行vww96 和 mbnet128 模型,你可以通过菜单 Code -> Runtime Memory Area -> Heap Size修改具体配置大小,例如可以为524288(512KB);

  • 对于FP32模型,需要将RISC-V ISA设置从默认的rv32imac改为rv32gc(Code -> Code Generation -> RIS-V ISA),确保编译器可以生成浮点数操作指令。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值