STM32 项目做到模型部署阶段,经常会遇到一个很具体的报错:程序代码还能编译,模型数组却放不进内部 Flash。有人会立刻加一颗 QSPI Flash,也有人把模型文件放进 SD 卡,接下来才发现模型虽然保存成功,推理时却读不到,或者延迟突然变得不可接受。
判断模型放在哪里,需要先回答两个问题:模型权重在推理时以什么方式被访问?激活值、输入窗口和算子工作区放在哪里?模型文件的存放位置只解决了容量问题,访问路径决定了运行结果。
| 先记住一个判断: |
一、模型文件大,不代表 RAM 也要同样大
把神经网络部署到 MCU,可以先按四类数据来检查。模型权重和网络结构通常是只读数据,负责告诉算子每个连接使用什么参数;激活缓冲区保存层与层之间的中间结果;输入输出缓冲区连接传感器和后处理;代码、栈、DMA 缓冲区以及 RTOS 对象还要继续占用片上资源。
| 传感器数据 ADC / I2S / SPI | 输入与激活 RAM 可读写、频繁更新 | CPU / NPU 推理 算子反复访问权重 | 只读权重 内部或外部 Flash |
图 1:权重的存放位置和激活缓冲区的运行位置可以不同
例如,INT8 模型的权重可以放在 8MB 外部 NOR Flash 中,Tensor Arena 仍然放在片上 SRAM,输入窗口由 DMA 写入另一块 RAM。外部 Flash 解决了“模型数组放不下”的问题,片上 SRAM 负责保证推理过程中频繁读写的数据有足够低的访问延迟。两者不能互相替代。
| 容量检查的基本式: RAM 需求 ≈ Tensor Arena + 输入输出缓冲区 + DMA 缓冲区 + 栈和系统运行时 模型文件只有 300KB,并不代表工程只需要 300KB 存储空间;模型文件有 2MB,也不代表必须准备 2MB 的可写 RAM。 |
二、四种存放位置,分别解决什么问题?
外部存储器的选择要看推理时的访问方式。只在开机加载一次的模型,可以接受较慢的介质;每个卷积层都要反复读取的权重,需要稳定的随机访问和足够带宽;每次采样都要更新的数据,则必须放进可写 RAM。
| 内部 Flash | ||
| 外部 QSPI / OSPI NOR Flash | ||
| 外部 SDRAM / PSRAM | ||
| SD 卡 |
这里最容易被忽略的是 QSPI/OSPI NOR Flash 的两种用法。第一种是 Memory-Mapped:外设把 Flash 映射到 MCU 地址空间,模型运行库可以按地址读取。第二种是普通间接读:每次访问都要经过驱动发起事务,再把数据搬到 RAM。后一种方式更像文件读取,适合启动时加载或分块缓存,直接让算子高频访问通常会遇到明显的等待。
三、内部 Flash 放不下时,先判断模型能不能直接从外部 Flash 运行
对于 STM32H7 这类没有专用 NPU 的 MCU,TFLite Micro 或生成式 AI 运行库通常会反复读取模型结构和权重;STM32N6 这类带 NPU 的平台还要考虑 NPU 能否直接看到该地址区域,以及权重和激活数据是否满足 Neural-ART 或相关运行时的布局要求。芯片支持外部存储器,不代表任意模型运行库都能直接使用它。
工程上可以按下面的顺序检查。第一,看工程生成的模型权重段是否被放进外部存储区;第二,看链接后的 Map 文件,确认权重起始地址和大小;第三,在调试器中读取模型首地址,确认内容不是全为 `0xFF` 或未初始化数据;第四,测量从内部 Flash 和外部 Flash 运行时的推理时间;第五,再决定保持映射访问,还是启动时把模型搬进 SDRAM。
/* 示意代码:实际段名、地址和启动加载方式按芯片工程修改 */ |
| 注意: |
如果外部 NOR 支持映射访问,模型可以留在外部 Flash,激活缓冲区放片上 SRAM 或外部 SDRAM;如果访问延迟导致推理时间超出任务周期,就把“整模型搬入 RAM”改成“只缓存当前需要的权重块”,或者重新量化、裁剪模型,减少对外部存储的访问压力。这个选择要用推理时间和总线占用来验证,不能只看外部 Flash 的容量。
四、三个常见项目,应该怎么选?
小型传感器分类:优先把量化模型放内部 Flash,Tensor Arena、输入窗口和 DMA 缓冲区放片上 SRAM。这样启动链路简单,推理延迟也容易测量。内部 Flash 只差几十 KB 时,先检查编译优化、调试符号和模型量化状态,再考虑扩展存储器。
多个模型或较大的轻量视觉模型:把模型包放外部 QSPI/OSPI NOR,使用 Memory-Mapped 访问或在启动阶段加载到 SDRAM。多个模型需要版本号、长度、校验值和回滚位置,不能把一堆裸数组直接拼在 Flash 后面就结束。
需要更新模型的产品:SD 卡可以承担开发阶段的数据导入和离线升级,量产产品更适合使用受控的外部 Flash 分区。升级时至少保留旧版本、完整性校验和失败回退路径,推理任务只读取通过校验的模型。
| 结论 |
说明:本文中的链接器段和运行时函数使用示意名称,具体工程应以目标 STM32 型号、模型工具链生成文件和链接脚本为准。
END

往期精选:

请点下【♡】给小编加鸡腿
