嵌入式AI基础:神经网络模型在MCU上的部署流程、内存类型及STM32内存架构简介
将神经网络模型部署到MCU(微控制器)上,与部署到PC或云端服务器有着本质区别。MCU的资源极度受限,尤其是内存容量和计算能力。理解模型在MCU上的部署流程,以及MCU内部复杂的内存架构,是进行后续模型内存占用分析与优化的前提。本章将系统梳理从训练好的模型到在STM32上运行的完整链路,并深入剖析Flash、RAM、SRAM、CCM等关键内存区域的特点与分工,为后续章节的量化、剪枝和算子优化打下坚实的硬件认知基础。
2.1 神经网络模型在MCU上的部署全流程
核心原理:从训练框架到嵌入式运行时的鸿沟
在PC端,深度学习模型依赖浮点运算、动态内存分配和操作系统调度。而MCU环境通常没有MMU(内存管理单元),缺乏操作系统支持,且浮点运算能力弱(部分Cortex-M0/M3甚至没有FPU)。因此,模型部署的本质是“静态化”与“预规划”的过程:将训练好的权重参数转换为C数组,将动态计算图展开为静态调用序列,将浮点运算量化为定点运算,并在编译期确定所有内存缓冲区的地址和大小。
STM32CubeAI作为ST官方工具链,其核心价值在于自动完成以下转换:
- 格式转换:支持Keras、TFLite、ONNX等格式输入,输出为针对特定STM32型号优化的C代码。
- 算子映射:将神经网络层(卷积、池化、全连接等)映射到CMSIS-NN或STM32CubeAI自研的优化算子库。
- 内存规划:在编译期计算每层输入/输出张量的内存需求,并复用缓冲区以降低RAM峰值。
操作流程:CubeAI部署的四个关键阶段
- 模型准备与验证:在PC端完成训练,确保模型精度达标。导出为ONNX或TFLite格式,并记录输入/输出张量的shape和dtype。
- CubeAI配置:在STM32CubeMX中启用CubeAI插件,选择目标芯片型号(如STM32F746ZG),导入模型文件。配置量化选项(如8位量化)、输入输出缓冲区大小、是否启用DMA等。
- 代码生成与分析报告:工具生成
network.c、network_data.c和network.h。同时生成一份内存分析报告,详细列出Flash占用(权重+代码)和RAM占用(激活值+中间缓冲区)。 - 集成与运行时调用:在用户代码中调用
ai_run()函数执行推理。需注意输入数据需按特定格式排列(如NHWC或NCHW),输出数据需从内部缓冲区拷贝到用户指定区域。
activations_size(激活值总大小)、weights_size(权重总大小)、scratch_buffer_size(临时缓冲区大小)。这些数值直接决定了模型能否在目标芯片上运行。例如,若报告显示activations_size = 120KB,而STM32F746的SRAM仅有320KB,且用户代码还需占用约50KB,则剩余可用空间不足,需考虑量化或网络结构压缩。
案例拆解:手写数字识别模型在STM32F746上的部署
假设我们有一个简单的CNN模型(2个卷积层+2个全连接层),输入为28×28灰度图,输出为10类。在PC上模型大小为1.2MB(float32)。部署到STM32F746(Cortex-M7,1MB Flash,320KB RAM)时:
| 阶段 | 操作 | 结果 |
|---|---|---|
| 初始状态 | float32模型 | Flash占用1.2MB,RAM峰值约800KB(无法运行) |
| 8位量化 | 权重转为int8 | Flash降至300KB,RAM峰值降至200KB |
| 内存复用 | CubeAI自动复用激活缓冲区 | RAM峰值降至120KB |
| 最终部署 | 启用CCM存放堆栈 | Flash占用320KB,RAM占用150KB,推理时间约80ms |
此案例说明,量化是降低Flash占用的最有效手段,而内存复用是降低RAM峰值的关键。CubeAI的编译器会自动分析网络各层的依赖关系,将不重叠的中间张量分配到同一块物理内存。
2.2 内存类型深度解析:Flash、RAM、SRAM与CCM
核心原理:不同内存的物理特性与访问路径
STM32系列芯片内部集成了多种内存,它们在容量、速度、访问方式和功耗上各有差异。理解这些差异是进行内存分配优化的前提。
- Flash(非易失性):用于存储代码、常量权重和只读数据。通过I-Code总线(取指)和D-Code总线(数据访问)与CPU连接。读取速度通常为24MHz(零等待状态),但若CPU主频更高(如168MHz),则需插入等待周期,影响性能。
- SRAM(易失性):通过系统总线(System Bus)访问,支持字节、半字、字访问。速度与CPU主频同步,无等待状态。但容量有限(通常几十KB到几百KB)。
- CCM(Core Coupled Memory):仅存在于部分型号(如F4系列),通过专用总线直接连接到CPU内核,访问速度与CPU同频,零等待。但不能通过DMA控制器访问,且只能由CPU直接读写。
- 外部RAM(如SDRAM):通过FMC(灵活存储控制器)接口扩展,容量可达数MB,但访问速度远低于内部SRAM,且需要额外的硬件设计和初始化代码。
判断方法:如何为不同数据选择合适的内存区域
| 数据类型 | 推荐存放位置 | 原因 |
|---|---|---|
| 模型权重(常量) | Flash | 掉电不丢失,不占用宝贵的RAM |
| 输入/输出张量 | SRAM | 需要频繁读写,SRAM速度快 |
| 中间激活值 | SRAM(可复用) | 生命周期短,需高速访问 |
| 堆栈(Stack) | CCM(若可用) | CPU频繁压栈/弹栈,CCM零等待提升性能 |
| 大尺寸查找表 | Flash(若允许)或外部RAM | Flash容量大,但读取慢;外部RAM容量大但需硬件 |
.ld文件)自定义内存区域。例如,将.ccmram段指向CCM地址(如0x10000000),并将堆栈指针指向该区域。CubeAI生成的代码默认将激活缓冲区放在SRAM,但高级用户可手动修改network.c中的内存分配宏,将部分缓冲区移至CCM。
案例拆解:STM32H743的内存分配实战
STM32H743拥有2MB Flash、1MB RAM(分为AXI SRAM、SRAM1-4等),且支持外部SDRAM。假设我们需要部署一个目标检测模型(YOLO-Tiny),权重约2MB,激活值峰值约500KB。
- Flash分配:2MB权重全部放入内部Flash,但需注意Flash的读取速度。若模型推理时频繁读取权重,建议启用ART加速器(自适应实时存储器加速器)以提升Flash读取效率。
- RAM分配:将激活缓冲区分配到AXI SRAM(主RAM,容量512KB),因为该区域支持DMA访问,便于后续使用DMA进行数据搬运。将堆栈分配到SRAM4(128KB),避免与激活缓冲区冲突。
- 外部SDRAM:若激活值超过1MB,可将部分不频繁访问的层(如全连接层)的中间结果暂存到SDRAM,但需注意SDRAM的访问延迟(约10-20ns),可能影响推理速度。
实际测试表明,合理利用CCM和AXI SRAM的分工,可使推理速度提升约15%,因为减少了总线冲突。
2.3 STM32内存架构与总线矩阵
核心原理:多总线并行与访问冲突
现代STM32(如F4、H7系列)采用多总线矩阵架构,允许CPU、DMA和外设同时访问不同内存区域,从而提升系统吞吐量。以STM32F4为例,其总线矩阵包含:
- I-Bus:CPU取指总线,连接Flash和CCM。
- D-Bus:CPU数据访问总线,连接Flash、SRAM和外设。
- S-Bus:系统总线,连接SRAM、外设和DMA。
- DMA总线:DMA控制器专用,可访问SRAM、Flash和外设。
当CPU从Flash取指的同时,DMA正在向SRAM写入数据,这两者可以并行执行,互不干扰。但若CPU和DMA同时访问同一SRAM区域,则会产生总线仲裁,导致一方等待。
内存架构对AI推理的影响
在AI推理过程中,CPU需要频繁读取Flash中的权重,同时读写SRAM中的激活值。如果权重和激活值位于同一总线域,则可能产生冲突。例如,在F4上,Flash和SRAM都通过D-Bus访问,当CPU执行卷积运算时,需要同时读取权重(Flash)和输入激活(SRAM),这会导致D-Bus的竞争。
解决方案包括:
- 使用CCM存放部分数据:CCM通过专用总线连接CPU,不占用D-Bus,可缓解竞争。
- 启用Flash预取和缓存:STM32的ART加速器可缓存Flash内容,减少重复读取的等待时间。
- 调整数据布局:将权重按访问顺序重新排列,提高缓存命中率。
案例拆解:总线冲突导致的推理延迟问题
某工程师在STM32F429上部署语音识别模型,发现推理时间波动较大,有时高达300ms,有时仅150ms。通过分析发现,问题源于DMA正在后台传输音频数据(占用S-Bus),而CPU同时通过D-Bus访问Flash和SRAM,导致总线仲裁频繁。
优化措施:
- 将音频DMA缓冲区从SRAM1移至SRAM2(不同总线域),减少与CPU的冲突。
- 将模型权重从Flash复制到SRAM3(通过S-Bus访问),使CPU的D-Bus仅访问SRAM1中的激活值。
- 调整DMA优先级,降低音频传输的优先级,确保推理的实时性。
优化后,推理时间稳定在140ms±5ms,且音频采集无丢包。此案例说明,内存架构的优化不仅是容量问题,更是总线带宽的调度问题。
通过本章的学习,我们建立了从模型到硬件的完整映射认知。下一阶段,我们将深入探讨如何利用CubeAI的内存报告进行精确的占用分析,并针对Flash和RAM分别制定优化策略。但在此之前,请务必掌握本章的内存架构基础,因为所有优化手段都受限于物理硬件的约束。