【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】

    • 一、前文回顾
    • 二、CMSIS-NN简介
      • 2.1 为什么介绍CMSIS-NN?
      • 2.2 CMSIS-NN是什么?
      • 2.3 CMSIS-NN核心特性
      • 2.4 CMSIS-NN算子支持
    • 三、TFLM+CMSIS-NN集成
      • 3.1 包含TFLM的STM32项目
      • 3.2 理解TFLM中CMSIS-NN相关构建规则
      • 3.3 理解TFLM中CMSIS-NN相关算子实现
      • 3.4 集成CMSIS-NN方式1——作为TFLM的一部分
      • 3.5 集成CMSIS-NN方式2——作为独立的三方库
    • 四、TFLM+CMSIS-NN测试
      • 4.1 编译源代码
      • 4.2 下载Boot代码
      • 4.3 下载Appli代码
      • 4.4 运行TFLM基准测试
    • 五、问题解决
      • 5.1 specialize_files.py 输入不支持CMake列表参数问题
      • 5.2 specialize_files.py 输出的路径分隔符不一致问题
      • 5.3 specialize_files.py 输出和CMake列表格式不一致问题
      • 5.4 specialize_files.py 输出的最后一个文件无法找到
    • 六、项目源码
    • 七、参考链接

本文介绍了如何通过移植CMSIS-NN库并调整TensorFlow Lite for Microcontrollers (TFLM) 的构建配置,实现在STM32微控制器上利用DSP指令集加速TensorFlow Lite模型的推理过程。通过这一方法,我们能够有效地提升基于ARM Cortex-M系列MCU上运行深度学习模型的性能。文章首先介绍了CMSIS-NN库的基本概念及其在神经网络加速中的作用,随后详细阐述了移植库到STM32平台的步骤。接着,文章深入讲解了如何修改TFLM的构建规则,实现调用CMSIS-NN库实现TensorFlow算子。最后,通过实验验证了该方法在提高模型推理速度方面的显著效果,使用CMSIS-NN实现DSP加速后的人脸检测模型推理速度接近原来的3.5倍。

本系列博文目录:

  1. 【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】 (背景介绍、初步体验、框架移植)
  2. 【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【下篇】 (平台适配、编译集成、基准测试)
  3. 【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】 (CMSIS-NN简介、TFLM+CMSIS-NN集成、TFLM+CMSIS-NN测试)

一、前文回顾

此系列前面已经发布了两篇:

  1. 【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】

  2. 【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【下篇】

【上篇】介绍了TensorFlow、TensorFlow Lite、TensorFlow Lite for Microcontrollers(TFLM)是什么,如何下载TFLM源码,如何在个人电脑(PC)上体验运行TFLM基准测试。同时,分析了TFLM的部分Makefile源码分析。最后,介绍了如何移植TFLM的主体代码。

【下篇】介绍了如何准备STM32 CubeMX项目(以便于后续的TFLM可以顺利移植),如何将TFLM源码集成到STM32 CubeMX生成的项目中去,以及如何在STM32项目中运行TFLM基准测试。同时,介绍了过程中遇到的问题,以及解决方法。最后,给出了整个项目的完整可运行源代码。

二、CMSIS-NN简介

2.1 为什么介绍CMSIS-NN?

因为TFLM源码中有针对CMSIS-NN的算子适配层,通过该适配层可以实现将TensorFlow Lite模型的推理计算转化为对CMSIS-NN库的调用。

同时,CMSIS-NN底层支持DSP指令和MVE指令,在Cortex-M4、Cortex-M7、Cortex-M33上可以实现DSP指令加速计算,在Cortex-M55、Cortex-M85上可以实现MVE加速计算

简言之,TFLM默认的算子实现为纯CPU计算,而CMSIS-NN可以作为TFLM的后端,实现部分处理器上的DSP和MVE加速计算。

2.2 CMSIS-NN是什么?

CMSIS-NN是什么?官方的解释是:

CMSIS NN 软件库是一组高效的神经网络核(函数),旨在最大限度地提高 Arm Cortex-M 处理器上神经网络的性能并最大限度地减少内存占用。

CMSIS-NN是一个计算库,它向上提供了神经网络(NN)计算接口,实现了神经网络计算的硬件加速。它内部实现了纯CPU计算、DSP计算、MVE计算,屏蔽了底层硬件的具体细节,降低了编程难度。

2.3 CMSIS-NN核心特性

总结一下官方的介绍,可以知道CMSIS-NN库的核心特性:

  • 专为Cortex-M处理器开发;

  • 神经网络计算函数;

  • 最大化性能;

  • 最小化内存占用;

  • CMSIS-NN的硬件和软件支持

2.4 CMSIS-NN算子支持

在CMSIS-NN源码仓首页,可以看到CMSIS-NN库提供了三种算子实现,分别为:

  • 纯C,CMSIS-NN提供了所有算子的纯C实现,用于像Cortex-M0和Cortex-M3这样的处理器;
  • DSP扩展,在支持DSP扩展的处理器上,可以使用DSP指令加速计算,例如Cortex-M4或Cortex-M7;
  • MVE扩展,在支持ARM Helium技术的处理器上,可以使用MVE指令加速计算,例如 Cortex-M55 或 Cortex-M85;

三、TFLM+CMSIS-NN集成

接下来,我将介绍如何将TFLM和CMSIS-NN集成到STM32项目中。

3.1 包含TFLM的STM32项目

前面的文章中,我们已经知道了如何将TFLM集成到STM32项目中,本文将以上一篇文章的代码为基础,继续进行CMSIS-NN的集成和测试。

基础项目代码仓链接:

https://gitcode.com/xusiwei1236/STM32H7S78-DK-TFLM

这个代码仓就是——已经包含了TFLM的STM32项目。

3.2 理解TFLM中CMSIS-NN相关构建规则

TFLM的构建规则Makefile文件中,和CMSIS-NN相关的主要代码片段为:

tflm-makefile-638

这段代码中,比较重要的有两处,分别为:

  • 649行,CMSIS-NN对应的OPTIMIZED_KERNEL_DIR变量值为cmsis_nn,此时会包含cmsis_nn.inc构建规则文件;
  • 651到653行,调用specialize_files.py脚本,用于将算子实现源文件列表MICROLITE_CC_KERNEL_SRCS中的部分文件替换为CMSIS-NN适配源文件列表;

cmsis_nn.inc文件内容如下:

cmsis_nn_inc

这段代码中,可以看到TFLM支持两种方式和CMSIS-NN集成:

  • CMSIS-NN作为独立的三方库,链接到一起;
  • CMSIS-NN作为TFLM的一部分,编译到一起;

specialize_files.py文件源码如下:

specialize_files_py

该文件实现了:

  • 遍历base_files列表中的条目,检查在specialized_directory目录下是否存在和它的基础文件名(basename)相同的文件;
  • 如果存在,则使用specialized_directory目录下的替换掉base_files中的这一条;
  • 否则,保持原来位于base_files中的这一条不变!

3.3 理解TFLM中CMSIS-NN相关算子实现

对于CMSIS-NN,实际运行时的specialized_directory指定的参数值是tensorflow/lite/micro/kernels/cmsis_nn子目录。

该目录下包含的文件如下:

image-20241016001239443

实际执行specialize_files.py脚本时,实际的替换文件的对应关系如下:

默认算子文件CMSIS-NN算子文件
tensorflow/lite/micro/kernels/add.cctensorflow/lite/micro/kernels/cmsis_nn/add.cc
tensorflow/lite/micro/kernels/batch_matmul.cctensorflow/lite/micro/kernels/cmsis_nn/batch_matmul.cc
tensorflow/lite/micro/kernels/conv.cctensorflow/lite/micro/kernels/cmsis_nn/conv.cc
tensorflow/lite/micro/kernels/depthwise_conv.cctensorflow/lite/micro/kernels/cmsis_nn/depthwise_conv.cc
tensorflow/lite/micro/kernels/fully_connected.cctensorflow/lite/micro/kernels/cmsis_nn/fully_connected.cc
tensorflow/lite/micro/kernels/mul.cctensorflow/lite/micro/kernels/cmsis_nn/mul.cc
tensorflow/lite/micro/kernels/pooling.cctensorflow/lite/micro/kernels/cmsis_nn/pooling.cc
tensorflow/lite/micro/kernels/softmax.cctensorflow/lite/micro/kernels/cmsis_nn/softmax.cc
tensorflow/lite/micro/kernels/svdf.cctensorflow/lite/micro/kernels/cmsis_nn/svdf.cc
tensorflow/lite/micro/kernels/transpose_conv.cctensorflow/lite/micro/kernels/cmsis_nn/transpose_conv.cc
tensorflow/lite/micro/kernels/unidirectional_sequence_lstm.cctensorflow/lite/micro/kernels/cmsis_nn/unidirectional_sequence_lstm.cc

这里以第一行add.cc为例,默认的算子实现主体代码为:

tf-add-cc

CMSIS-NN版本的add.cc代码主体代码为:

tf-add-cmsis-nn

都提供了Register_ADD()函数,用于注册ADD算子。

3.4 集成CMSIS-NN方式1——作为TFLM的一部分

理解了前面的Makefile代码,就可以编写CMake构建规则,从而实现在STM32项目中集成TFLM和CMSIS-NN。

前文提到,STM32项目集成CMSIS-NN有两种方式,分别为:

  • CMSIS-NN作为TFLM的一部分,编译到TFLM的静态库(libtflite-micro.a)文件中;
  • CMSIS-NN作为独立的三方库,链接到STM32的可执行程序(.elf)文件中;

首先,介绍第一种方式,也就是CMSIS-NN作为TFLM的一部分;这种方式Appli子项目不直接依赖CMSIS-NN库,无需修改,更易于理解。

基于对Makefile源码的理解,修改tflite-micro目录的CMakeLists.txt文件内容:

tflm-cmakelists-diff

这段修改中包含了cmsis-nn.cmakecmsis-nn.cmake文件的内容为:

cmsis-nn.cmake

整个修改实现了:

  • 调用specialize_files.py脚本,将MICROLITE_KERNEL_CC_SRCS中的部分算子文件路径替换为cmsis_nn目录内的,实现了CMSIS-NN适配层的编译;
  • cmsis-nn.cmake中匹配到的CMSIS-NN源文件,添加到TFLM库的源文件列表中,实现了CMSIS-NN代码的编译,并作为TFLM库的一部分;

这样修改之后,重新编译生成的libtflite-micro.a中就包含了CMSIS-NN的代码,以及基于CMSIS-NN的TensorFlow算子实现。

3.5 集成CMSIS-NN方式2——作为独立的三方库

另外一种集成CMSIS-NN的方式是,CMSIS-NN作为独立的三方库,最终连接到整个项目的可执行文件(.elf)中。

要实现这种继承方式,需要在刚修改的TFLM的CMakeLists.txt的基础上进行修改:

tflm-cmakelists-diff-2

一共修改两处:

  • add_library代码片段,删除CMSIS-NN相关的代码文件;
  • 文件末尾添加add_subdirectory(tensorflow/lite/micro/tools/make/downloads/cmsis_nn),让CMSIS-NN的CMakeLists.txt被包含到整个项目中;

除此之外,还需要修改Appli目录的CMakeLists.txt文件,具体修改内容如下图:

Appli-CMakeLists.diff

一共修改了三处:

  • 新增了TF_CMSIS_NN_DIR变量定义,用于记录cmsis_nn源码所在子目录;
  • target_link_directories下,增加一行,指定CMSIS-NN库文件生成的目录;
  • target_link_libraries下,增加一行,指定链接cmsis-nn库;

以上这种修改方式,也可以实现将TFLM和CMSIS-NN集成到STM32项目中。

四、TFLM+CMSIS-NN测试

4.1 编译源代码

第一种方式集成CMSIS-NN,由于上层代码不依赖CMSIS-NN库,即不新增库依赖;因此,其编译方式和此前的文章方式一样,这里不在介绍。

这里仅介绍第二种方式集成CMSIS-NN的编译方法,分为如下几步:

  1. 清理输出目录,如下图操作:

    image-20241019205845206

  2. 编译tflite-micro库,如下图操作:

    image-20241019210234667

  3. 编译xxx_benchmark库,如下图操作:

    image-20241019210123597

  4. 编译cmsis-nn库,如下图操作:

    image-20241019210824201

  5. 编译Appli目标,如下图操作:

    image-20241019210320714

  6. 编译Boot代码,如下图所示:

    image-20241019210403135

4.2 下载Boot代码

由于Appli代码需要使用Boot代码进行跳转,因此,下载Appli代码之前,需要先将Boot代码下载到开发板上。

下载之前,先将STM32H7S78-DK开发板和PC通过USB线连接好,板子由三个USB口,注意连接到标有STLK的。

下载Boot代码,按照如下图所示操作:

image-20241019213805347

执行过程中终端子窗口会输出进度等信息:

image-20241019213920660

4.3 下载Appli代码

下载Appli代码,按照如下图操作:

image-20241019211731626

执行过程中终端子窗口会输出进度等信息:

image-20241019213610487

4.4 运行TFLM基准测试

打开MobaXterm,添加会话,选择STLink的虚拟串口设备,参数如下:

image-20241019020056378

连接设备之后,按下开发板上的NRST按钮,重启设备,可以看到串口输出如下:

20241014234609

可以看到,开发板上,运行有人图像的人体检测耗时为286毫秒,没有人的耗时为286毫秒;连续运行10次的耗时分别为2863毫秒和2863毫秒,速度有点慢。

和上一篇文章的数据对比如下:

测试项目TFLMTFLM+CMSIS-NN
WithPersonDataIterations(1)993286
NoPersonDataIterations(1)994286
NoPersonDataIterations(10)99382863
NoPersonDataIterations(10)99402863

五、问题解决

第三章、第四章实际过程中遇到了一些问题,为了保持前文逻辑连贯,没有在前面记录,本章将记录具体问题及解决方法。

5.1 specialize_files.py 输入不支持CMake列表参数问题

【问题现象】specialize_files.py脚本输出和输入参数base_files的值完全一样。

【问题原因】specialize_files.py脚本使用Python的string.split对参数base_files的值进行分隔,要求值是空白字符(空格、TAB、换行等)分隔的。而CMake的列表字符串是分号分隔的。

【解决方法】将MICROLITE_CC_KERNEL_SRCS中的分隔符替换为空格,再将其传给specialize_files.py脚本,具体代码为:

specialize_files_py_input

5.2 specialize_files.py 输出的路径分隔符不一致问题

【问题现象】specialize_files.py 输出的路径分隔符不一致,有正斜杠也有反斜杠,导致后续报错——文件找不到。

【问题原因】CMake代码使用的路径分隔符是正斜杠,specialize_files.py代码里面使用的是os.path.sep,在Windows上是反斜杠。

【解决方法】将反斜杠全部替换为正斜杠。

specialize_files_py_ouput2

5.3 specialize_files.py 输出和CMake列表格式不一致问题

【问题现象】specialize_files.py 输出的文件列表是空格分隔的,和CMake列表格式不一致。

【问题原因】specialize_files.py 使用空格拼接文件列表为一个字符串之后输出,而CMake列表需要用使用分号分隔。

【解决方法】将字符串中的空格替换为分号。

specialize_files_py_ouput3

5.4 specialize_files.py 输出的最后一个文件无法找到

【问题现象】specialize_files.py 输出的文件列表的最后一个文件,后续CMake代码提示该文件找不到。

【问题原因】乍看起来文件路径是对的,能够找到;实际将该文件路径字符串加上双引号输出之后,发现末尾多了一个换行符。

【解决方法】去除末尾的空白字符。

specialize_files_py_ouput1

六、项目源码

如需本文修改后项目源码的,请在评论区留言。我将会在留言超过10条,或本文阅读量超过1200之后,将本文修改的最终源码全部开源。

当然,动手能力强的读者,也可以根据文章描述的步骤,一步步修改得到最终版本的源码。

七、参考链接

  1. TensorFlow Lite for Microcontrollers介绍: TensorFlow Lite for Microcontrollers (google.cn)
  2. TensorFlow Lite for Microcontrollers入门: 微控制器入门 | TensorFlow (google.cn)
  3. tflite-micro 源码仓: https://github.com/tensorflow/tflite-micro
  4. CMake最新文档: CMake Reference Documentation — CMake 3.30.3 Documentation
  5. CMSIS-NN在线文档: CMSIS-NN: CMSIS NN Software Library (arm-software.github.io)
  6. CMSIS-NN 源码仓: https://github.com/ARM-software/CMSIS-NN

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/57467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode使用法则及神器介绍

目录 1.Vscode设置中文 2.文插件选择configure display Language 3.插件 4.代码格式化 5.创建代码模板 一个好的插件,可以快速提高优秀程序猿的工作效率,减少开发时间; 1.Vscode设置中文 首先打开VSCode软件 快捷键【CtrlShiftP】 2.…

基于neo4j的医疗图谱问答与展示

找不到好的毕业设计题材?或者对人工智能领域感兴趣却不知道如何下手?这里给大家推荐一款基于Neo4j的医疗图谱问答系统项目,绝对是毕业设计的不二选择。 这个项目依托于医疗领域的知识图谱,为用户提供交流问答系统。它不仅具有知识…

3DsMax删除FBX 导出的预设

3DsMax删除FBX 导出的预设 文档 https://help.autodesk.com/view/3DSMAX/2025/CHS/?guidGUID-9939F041-5E2D-4AA8-A732-6C2A1DFB5314删除静态FBX 这个预设 使用everything 搜索预设文件的后缀.fbxexportpreset ,然后 文件路径 C:\Users\GoodCooking\Documents\3…

GPU 与 GPU 服务器:科技璀璨之星,开启无限未来

今天咱们要来聊聊在科技领域中闪闪发光的 GPU 和 GPU 服务器。这可真是一对厉害的 “科技搭档”,正以其卓越的性能成为众多行业发展的强大动力源。 先来说说 GPU 吧。它呀,一开始是为了满足图形处理的高要求而诞生的。但随着科技不断进步,人…

WRF-LES与PALM微尺度气象大涡模拟

针对微尺度气象的复杂性,大涡模拟(LES)提供了一种无可比拟的解决方案。微尺度气象学涉及对小范围内的大气过程进行精确模拟,这些过程往往与天气模式、地形影响和人为因素如城市布局紧密相关。在这种规模上,传统的气象模…

百度搜索推广和信息流推广的区别,分别适用于什么场景!

信息流推广和搜索广告,不仅仅是百度,是很多平台的两个核心推广方式。 1、搜索广告: 就是基于用户的搜索习惯,更多是用户有疑问、还有用户当下就要做出行动的广告。 比如上门服务、线上咨询服务、招商加盟、了解产品各种型号和信…

Java应用程序的测试覆盖率之设计与实现(二)-- jacoco agent

说在前面的话 要想获得测试覆盖率报告,第一步要做的是,采集覆盖率数据,并输入到tcp。 而本文便是介绍一种java应用程序部署下的推荐方式。 作为一种通用方案,首先不想对应用程序有所侵入,其次运维和管理方便。 正好…

什么是机器人流量?如何识别和预防有害机器人流量?

机器人流量是指由自动软件程序(或机器人)而非人类用户生成的互联网流量。机器人可以执行各种任务,包括有益的和恶意的,而且速度比人类快得多。 据估计,大约 30% 的互联网流量来自旨在窃取内容、破坏服务和开展其他恶意…

深入浅出:深度学习模型部署全流程详解

博主简介:努力学习的22级计算机科学与技术本科生一枚🌸博主主页: Yaoyao2024往期回顾: 【论文精读】PSAD:小样本部件分割揭示工业异常检测的合成逻辑每日一言🌼: 生活要有所期待, 否则就如同罩在…

u盘装win10系统提示“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”解决方法

我们在u盘安装原版win10 iso镜像时,发现在选择硬盘时提示了“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”,直接导致了无法继续安装下去。出现这种情况要怎么解决呢?下面小编分享u盘安装win10系统提示“windows无法安装到这个磁盘…

一款好用的搜索软件——everthing(搜索比文件资源管理器快)

everthing官网链接 在官网选择下载 1.下载后双击打开 2.点击OK(需要其他语言自己选择) 3.选择安装位置(路径最好别带中文和空格) 继续点击下一步 4. 点击下一步 5.继续点击安装 6.然后就完成了 7.点击打开然后就可以搜索了

【有啥问啥】CLIP Adapter:提升视觉语言模型性能的利器

CLIP Adapter:提升视觉语言模型性能的利器 1. 引言 在视觉语言预训练领域,CLIP(Contrastive Language-Image Pre-training)模型凭借其强大的跨模态表征能力,在多个任务上取得了显著成果。然而,如同其他预…

多模态大语言模型(MLLM)-Deepseek Janus

论文链接:https://arxiv.org/abs/2410.13848 代码链接:https://github.com/deepseek-ai/Janus 本次解读Janus: Decoupling Visual Encoding for Unified Multimodal Understanding and Generation 前言 Deepseek出品,必属精品。 创新点 传…

【javax maven项目缺少_Maven的依赖管理 引入依赖】

javax maven项目缺少_Maven的依赖管理 引入依赖 Maven的依赖管理 - 引入依赖依赖管理(引入依赖)导入依赖 https://blog.csdn.net/weixin_28932089/article/details/112381468 Maven的依赖管理 - 引入依赖 依赖管理(引入依赖) 能够掌握依赖引入的配置方式 导入依赖 导入依赖练…

【经管】比特币与以太坊历史价格数据集(2014.1-2024.5)

一、数据介绍 数据名称:比特币与以太坊历史价格数据集 频率:逐日 时间范围: BTC:2014/9/18-2024/5/1 ETH:2017/11/10-2024/5/1 数据格式:面板数据 二、指标说明 共计7个指标:Date、Open…

C#,自动驾驶技术,ASAM OpenDRIVE BS 1.8.0 规范摘要与C# .NET Parser

本文介绍自动驾驶技术的标准之一《ASAM OpenDRIVE》1.8.0 版本的规范摘要,及北京联高软件开发有限公司实现的 C# 版本 xodr 文件(XML) Parser 源代码。 本文档是 ASAM e.V. 的版权财产。 在更改常规许可条款时,ASAM 允许不受限制地…

HCIP--1

同一区域内的OSPF路由器拥有一致的 LSDB, 在区域内,OSPF 采用 SPF算法计算路由一个区域太多路由器,硬件资源跟不上,所以多划分区域 OSPF 路由计算原理 1. 区域内路由计算 LSA 在OSPF中,每个路由器生成 LSA,用于告诉…

Git Push(TODO)

最近经常碰到GIT push不上去的问题。到处求人解决也真是尴尬,想自己看看,所以刚刚在github上建了一个仓,试了下。结果如下: 暂时可能还不行,因为数据都是加密的,没法看到具体GIT的交互信息。。。 后面再想办…

CMOS 图像传感器:像素寻址与信号处理

CMOS image sensor : pixel addressing and signal processing CMOS image sensor 对于寻址和信号处理有三种架构 pixel serial readout and processingcolumn parallel readout and processingpixel parallel readout and processing 其中,图 (b) column paralle…

Pr 视频效果:自动重构

视频效果/变换/自动重构 Transform/Auto Reframe 自动重构 Auto Reframe效果是用于快速调整视频素材以适应不同长宽比的一项强大工具。 随着各种平台和设备的多样化,视频内容需要适应不同的屏幕尺寸和比例,如 16:9(横屏)、9:16&am…