
TinyML 这个词这两年出现的频率越来越高但很多人对它的理解还停留在在单片机上跑个神经网络这种模糊概念上。真到要动手选板子的时候问题就来了到底什么样的硬件才能跑得动 AI 模型是不是随便一块 STM32 就能上手算力、内存、功耗这三者之间怎么平衡我前后用过十几块不同定位的开发板做 TinyML 相关的验证从 Cortex-M4 到 M7从纯 MCU 到带 NPU 的异构芯片都折腾过踩的坑不算少。这篇就把一块能跑 AI 模型的 TinyML 开发板到底需要哪些硬件这件事拆开讲清楚从核心计算单元、内存配置、传感器接口到供电与调试把选型和设计的逻辑讲透。不管你是刚接触 TinyML 的嵌入式新手还是正在做端侧 AI 硬件方案的老工程师应该都能从中找到可以直接参考的东西。1. 先搞清楚 TinyML 到底在硬件上跑什么1.1 TinyML 模型的实际计算特征很多人一上来就问这块板子算力多少 TOPS这个问题在 TinyML 场景下其实问偏了。TinyML 跑的模型和云端那些动辄几十亿参数的大模型完全是两回事。典型的 TinyML 模型是关键词唤醒KWS、手势识别、异常检测、简单图像分类这类任务模型参数量通常在几十 KB 到几百 KB 之间运算量在几百万到几千万 MAC乘累加级别。这意味着什么意味着 TinyML 的核心瓶颈往往不是算力而是内存带宽和内存容量。一个 200KB 的模型权重需要常驻内存中间层的激活值activation需要动态分配输入数据的缓冲区也要占地方。如果你的 MCU 只有 128KB 的 SRAM光模型权重就吃掉一大半剩下的根本不够跑推理。所以选板子的第一件事是算清楚你的模型需要多大的内存 footprint。我一般会这样估算模型权重大小约等于参数量乘以量化位宽除以 8。比如一个 100K 参数的模型用 int8 量化权重大约 100KB。再加上激活值缓冲通常需要权重量的 1.5 到 2 倍。所以一个 int8 量化的 100K 参数模型实际需要 250KB 到 300KB 的 RAM 才能比较舒服地跑起来。这个数字直接决定了你该选什么档次的芯片。1.2 推理框架对硬件的隐性要求TinyML 常用的推理框架有 TensorFlow Lite for MicrocontrollersTFLM、CMSIS-NN、Edge Impulse 导出的 SDK 等。这些框架对硬件有一些隐性但很关键的要求很多人选板子的时候容易忽略。TFLM 本身是纯 C 实现的对硬件没有特殊依赖但它依赖一个算子库。如果你用的是 ARM Cortex-M 系列CMSIS-NN 会针对 M 系列的 DSP 指令和 SIMD 指令做优化这时候芯片有没有 DSP 扩展、有没有 HeliumM55/M85 上的向量扩展就直接影响推理速度。同样是 100MHz 的主频带 DSP 指令的 M4 跑卷积可能比不带 DSP 的 M0 快五到十倍。另一个隐性要求是浮点单元FPU。虽然现在主流做法是 int8 量化推理但训练后量化PTQ过程中有些算子仍然需要浮点运算如果你的芯片没有硬件 FPU这些算子会退化成软件浮点速度慢得让人怀疑人生。所以我的建议是做 TinyML芯片至少要有单精度 FPU最好是带 DSP 扩展的 Cortex-M4F 起步。1.3 从任务反推硬件档次的实用方法与其纠结参数不如从你的实际任务反推。我整理了一个简单的对照表是我自己在项目里常用的判断依据任务类型典型模型规模推荐最低配置典型芯片举例关键词唤醒、振动异常检测10K-50K 参数M4F128KB RAM无 DSP 也可STM32L4 系列手势识别、简单音频分类50K-150K 参数M4F/M7256KB RAM带 DSPSTM32F4、STM32H7图像分类小分辨率150K-500K 参数M7512KB RAM带 DSP/CacheSTM32H743、STM32H750多模态、实时视觉500K 参数带 NPU 或双核异构带 Ethos-U 的 M55、带 NPU 的异构 SoC这张表不是绝对的但能帮你快速定位。比如你要做的是识别几个关键词那 STM32L4 这种低功耗 M4F 就够了没必要上 H7。反过来如果你要做 96x96 的灰度图像分类还要求实时帧率那 H743 这种带 Cache 和 DSP 的 M7 才是合理起点。2. 核心计算单元MCU 选型的几个硬指标2.1 主频不是唯一指标Cache 和总线架构更关键拿 STM32H743 举例它跑 480MHzCortex-M7 内核看起来很美。但如果你把代码放在外部 QSPI Flash 里跑没有 Cache 的话取指延迟会让你怀疑这块芯片是不是坏了。H743 有 L1 CacheI-Cache 和 D-Cache还有 TCM紧耦合内存这些才是它跑 AI 推理时真正的性能保障。我实测过一个对比同样的模型代码和数据都放在 TCM 里跑和放在外部 SDRAM 里跑推理时间差了将近 3 倍。原因就是 TCM 是零等待周期的而外部存储要经过总线矩阵、可能还有 Cache miss 的开销。所以选 MCU 的时候一定要看它有没有 TCM、TCM 多大、Cache 多大。H743 有 1MB 的 TCMITCM DTCM这在跑 TinyML 时非常关键——你可以把模型权重和关键算子都塞进 TCM推理速度会稳定很多。另一个容易被忽略的是总线矩阵和 DMA。TinyML 推理过程中传感器数据要通过 DMA 搬进内存推理结果要通过 DMA 搬出去。如果总线架构设计得不好CPU 访问内存和 DMA 访问内存会互相抢带宽导致推理时间抖动。H7 系列的多层 AXI 总线矩阵就是为解决这个问题设计的这也是它比 F4 系列更适合跑 AI 的原因之一。2.2 DSP 扩展与 Helium加速推理的硬件红利ARM 的 DSP 扩展在 M4、M7、M33 上都有提供了一批 SIMD 指令比如 SIMD 乘加、饱和运算、位反转等。CMSIS-NN 库会把这些指令用起来卷积和全连接层的速度能提升好几倍。我做过一个测试在 M7 上跑一个 100K 参数的 CNN用 CMSIS-NN 优化过的版本比纯 C 实现快了大约 4.5 倍。Helium 是 ARMv8.1-M 架构引入的向量扩展M55 和 M85 支持。它相当于给 MCU 加了一个小型的向量单元能一次处理多个数据。对于 TinyML 来说Helium 的收益非常明显尤其是卷积和矩阵乘法。不过目前支持 Helium 的芯片还不多生态也在完善中如果你现在就要量产M7 DSP 是更稳妥的选择。这里有个实操经验不要只看芯片手册上写的支持 DSP 指令要确认你的工具链和推理框架真的用上了这些指令。我见过有人用 Keil 编译 TFLM默认优化等级下 CMSIS-NN 的汇编优化根本没启用跑出来的速度和没 DSP 差不多。正确做法是在编译选项里打开-mcpucortex-m7 -mfpufpv5-d16这类参数并确保 CMSIS-NN 的预编译库被正确链接。2.3 双核与异构什么时候需要更复杂的架构STM32H7 有双核版本H745、H747一个 M7 加一个 M4。这种架构在 TinyML 场景下有用吗有用但要看你怎么用。常见的做法是 M7 跑推理M4 负责传感器采集、通信和系统管理。这样推理任务不会被中断打断实时性更好。但双核也带来了核间通信的开销和调试复杂度。如果你的任务比较简单单核 M7 完全够用没必要为了看起来更强上双核。我个人的判断标准是如果推理任务的 deadline 很紧比如每 10ms 必须出结果而且系统还有其他实时任务那双核值得考虑否则单核更省心。再往上就是带 NPU 的异构芯片了比如带 Ethos-U55/U65 的 M55 组合或者一些国产的带 NPU 的 SoC。这类芯片的算力能到 0.5 TOPS 甚至更高能跑更复杂的模型。但代价是开发工具链更复杂模型部署需要经过额外的编译步骤比如 Vela 编译器把 TFLite 模型转成 Ethos-U 能执行的格式。如果你团队里没有专门做模型部署的人上手门槛不低。3. 内存配置TinyML 最容易被低估的瓶颈3.1 SRAM 容量与模型 footprint 的匹配计算前面提到了模型 footprint 的估算这里展开讲一下怎么精确计算。假设你有一个 TFLite 模型文件大小是 180KB。这个文件里包含了权重、偏置和算子描述。部署到 MCU 上时权重需要放在 Flash 或者 RAM 里激活值需要放在 RAM 里。TFLM 提供了一个MicroInterpreter的 API你可以通过arena_used_bytes()来查看实际用了多少 RAM。但在这之前你需要先给 arena 分配一块内存。我的经验是arena 大小至少要是模型文件大小的 1.5 倍如果模型里有比较多的中间层可能要 2 倍。比如 180KB 的模型arena 至少给 270KB保险起见给 360KB。这时候如果你的 MCU 只有 512KB SRAM看起来够但别忘了系统本身还要用 RAM——栈、堆、通信缓冲区、传感器驱动缓冲区。实际留给 TFLM arena 的可能只有 300KB 左右。所以选芯片的时候SRAM 容量要留足余量我一般建议可用 SRAM 至少是模型文件大小的 3 倍。3.2 外部存储与内存扩展的取舍当片上 SRAM 不够时有几个选择外挂 SDRAM、外挂 QSPI Flash、或者用带更大片上 RAM 的芯片。外挂 SDRAM 的好处是容量大、成本相对低但访问延迟高而且需要配置 FMC/OctoSPI 控制器。如果你把模型权重放在 SDRAM 里每次推理都要从 SDRAM 读权重速度会比片上 RAM 慢不少。我的做法是权重放外部 Flash推理时按需加载到片上 TCM 或 SRAM 里这样兼顾了容量和速度。STM32H743 支持 OctoSPI可以外挂 Octal Flash 或 HyperRAM。HyperRAM 是个不错的选择它比 SDRAM 接口简单功耗也低适合做推理时的数据缓冲区。但 HyperRAM 的带宽有限不适合放频繁访问的权重。还有一种思路是用带大容量片上 RAM 的芯片比如有些国产 MCU 带 1MB 甚至 2MB SRAM。这类芯片省去了外挂存储的麻烦但价格通常更高而且生态和工具链的成熟度需要评估。3.3 内存布局对推理速度的实际影响内存布局这件事很多人不重视但它对推理速度的影响可能比主频还大。我举个实际例子同样的模型同样的芯片STM32H743我把权重放在不同的位置推理时间如下权重存放位置推理时间相对值说明DTCM1.0基准零等待周期最快AXI SRAM1.3有 Cache但仍有开销外部 SDRAM2.8总线延迟高Cache miss 多外部 QSPI Flash无 Cache5.5取指延迟极大这个表说明什么说明如果你要做高性能 TinyML一定要把关键数据放在 TCM 里。H743 的 DTCM 有 128KBITCM 有 64KB加起来 192KB。对于小模型完全可以把权重和 arena 都放进 TCM。对于大一点的模型至少把最频繁访问的层放进 TCM。具体操作上你可以用链接脚本linker script把特定的段分配到 TCM。比如在 GCC 里可以用__attribute__((section(.dtcmram)))把数组放到 DTCM。TFLM 的 arena 也可以通过自定义内存分配器来指定位置。4. 传感器与接口数据从哪来结果往哪去4.1 音频、视觉、IMU 三类典型传感器的接口需求TinyML 的输入数据主要来自三类传感器麦克风音频、摄像头视觉、IMU运动。每类传感器对硬件接口的要求不同。音频场景通常用 I2S 接口的数字麦克风比如 INMP441、ICS-43434。I2S 需要 MCU 支持 I2S 外设并且最好有 DMA 支持这样音频数据可以自动搬进缓冲区不占 CPU。采样率一般是 16kHz16bit 位深单声道。对于关键词唤醒通常需要 1 秒的音频窗口也就是 32KB 的缓冲区16kHz × 2字节 × 1秒。这个缓冲区大小在选内存时要算进去。视觉场景用 DCMI数字摄像头接口或者 SPI 接口的摄像头。DCMI 是 STM32 上常用的并行摄像头接口支持 DMA能直接把手图像数据搬进内存。但 DCMI 的引脚多PCB 布线麻烦。SPI 摄像头比如一些国产的低分辨率模块引脚少但带宽有限适合低帧率、低分辨率的场景。如果你要做 96x96 的灰度图SPI 摄像头勉强够用如果要做 224x224 的 RGB那必须上 DCMI 或者更高级的接口。IMU 通常用 SPI 或 I2C 接口。SPI 速度快适合高采样率I2C 引脚少适合低速场景。做振动异常检测时采样率可能要几 kHz这时候 SPI 更合适。做手势识别时100Hz 左右的采样率I2C 就够了。4.2 DMA 通道分配与数据吞吐的实战考量DMA 在 TinyML 系统里太重要了但很多人分配 DMA 通道时很随意结果跑起来发现数据丢包或者推理时间抖动。我的经验是给每个高速数据源分配独立的 DMA 通道并且尽量用不同的 DMA 控制器。STM32H7 有两个 DMA 控制器DMA1、DMA2和多个 BDMA 通道。I2S 音频、DCMI 摄像头、SPI 传感器最好各用一个独立的通道。如果通道不够用至少要把音频和视觉分开因为这两个数据流对实时性要求最高。另一个坑是 DMA 和 Cache 的一致性问题。H7 有 D-CacheDMA 搬运数据时不经过 Cache会导致 CPU 读到旧数据。解决办法是要么把 DMA 缓冲区放在非 Cache 区域比如 SRAM4要么在 DMA 传输前后做 Cache 维护invalidate/clean。我一般推荐前者省事且不容易出错。4.3 输出执行器与通信接口的选型推理出结果之后通常要驱动一些执行器或者把结果发出去。常见的输出包括GPIO 控制 LED 或继电器、PWM 控制电机或蜂鸣器、UART/CAN 发送结果给上位机或其他节点。这里有个容易忽略的点输出动作的延迟也会影响用户体验。比如关键词唤醒后要点亮 LED如果从推理完成到 GPIO 翻转之间有几十毫秒的延迟用户会觉得反应慢。所以输出路径也要尽量短最好在推理完成的中断里直接操作 GPIO不要经过多层任务调度。通信接口方面UART 最简单适合调试和低速数据传输。CAN 适合工业场景抗干扰强。如果要做无线可以加 BLE 或 LoRa 模块但要注意这些模块的功耗和唤醒延迟。做电池供电的 TinyML 设备时通信模块往往是功耗大头选型时要特别关注它的休眠电流和唤醒时间。5. 供电、时钟与调试那些不起眼但致命的细节5.1 电源域设计与低功耗模式的实际表现TinyML 设备很多是电池供电的功耗直接决定续航。但功耗优化不是简单选个 LDO 或者 DC-DC 就行它涉及到电源域划分、低功耗模式配置和外设时钟管理。STM32H7 有多个电源域VDD主电源、VDDA模拟电源、VBAT备份电源、VDDLDO内部 LDO 输出等。做低功耗设计时要把不用的外设时钟关掉把不用的电源域断开。比如你不用 ADC就把 VDDA 相关的电路简化不用 RTC就不需要 VBAT。低功耗模式方面H7 支持 Sleep、Stop、Standby 等模式。TinyML 的典型工作模式是采集-推理-休眠循环。在休眠时进入 Stop 模式电流可以降到几百微安唤醒后跑推理电流可能到几十毫安。平均功耗取决于占空比。我做过一个关键词唤醒的 demo推理时间 20ms休眠 980ms平均电流大约 2mA用 1000mAh 电池能跑 20 天左右。但这里有个坑从 Stop 模式唤醒后系统时钟需要重新配置外设需要重新初始化。如果你的推理任务对唤醒延迟敏感这个重新配置的时间要算进去。H7 从 Stop 模式唤醒大约需要几十微秒还算快但如果你用的是更慢的时钟源可能会到毫秒级。5.2 时钟树配置对推理稳定性的影响时钟树配置看起来是底层的事但它对推理稳定性影响很大。H7 的主频可以到 480MHz但这是通过 PLL 倍频得到的。如果 PLL 配置不稳定或者电源纹波太大可能会导致偶发的计算错误。我的经验是做 TinyML 时时钟配置要留余量。比如 H7 标称 480MHz你可以跑 400MHz这样功耗更低稳定性更好推理速度的损失也在可接受范围内。另外外部晶振的选择也很重要尽量用质量好的晶振负载电容要匹配好否则 PLL 可能锁不定或者有抖动。还有一个细节Cache 和 TCM 的时钟配置。有些芯片的 TCM 和 Cache 可以独立配置时钟如果配置不当可能会导致访问延迟增加。这个要看具体芯片的参考手册不同系列差异很大。5.3 调试接口与固件烧录的避坑经验调试接口这块SWD 是标配但有些细节要注意。比如 SWD 的引脚要和 GPIO 复用如果你在代码里把 SWD 引脚配置成了普通 GPIO下次就烧不进去了。我踩过这个坑最后是用 BOOT0 拉高进入 DFU 模式才救回来。另外做 TinyML 时经常需要看推理时间这时候DWTData Watchpoint and Trace的周期计数器很好用。你可以在推理前后读 DWT-CYCCNT算出精确的周期数。但要注意DWT 在低功耗模式下可能不工作测出来的时间可能不准。固件烧录方面如果你用外部 Flash 存模型烧录时要确保模型数据也被正确写入。有些 IDE 默认只烧录内部 Flash外部 Flash 的数据需要单独烧录或者通过 bootloader 加载。我一般会在固件里加一个模型校验的步骤启动时检查外部 Flash 里的模型 CRC 是否正确不对就报错避免跑出莫名其妙的结果。6. 从选型到落地一套可复用的硬件评估流程6.1 需求拆解与硬件规格书的形成说了这么多技术点最后落到实操上我一般会按这个流程来评估一块板子能不能用第一步明确任务类型和模型规模。是音频、视觉还是 IMU模型参数量大概多少量化方式是 int8 还是 float16这些决定了内存和算力的底线。第二步算内存账。模型文件大小 × 1.5 到 2 倍 arena 需求。加上系统 RAM、传感器缓冲区、通信缓冲区得到总 RAM 需求。然后看芯片的 SRAM 够不够不够的话考虑外挂存储。第三步算算力账。根据模型的 MAC 数和目标帧率/实时性要求估算需要的算力。M4F 大概能跑几十 MOPSM7 能跑几百 MOPS带 NPU 的能到 TOPS 级别。留 2 倍余量比较稳妥。第四步看接口。传感器接口I2S/SPI/I2C/DCMI、输出接口GPIO/PWM/UART/CAN、调试接口SWD/JTAG是否满足。第五步评估功耗和供电。电池供电的话算平均功耗和续航市电供电的话关注电源纹波和散热。第六步看生态和工具链。芯片厂商有没有提供 TinyML 相关的例程、库、文档社区活跃度如何遇到问题能不能找到人问6.2 快速验证用现成开发板跑通第一个模型理论算完最好尽快上手验证。我的建议是先用现成的开发板跑一个最简单的模型比如 Hello World 级别的正弦波预测或者关键词唤醒。这样能快速验证工具链是否顺畅、推理时间是否符合预期、内存是否够用。STM32H743I-DISCO 或者 NUCLEO-H743ZI 都是不错的起点板载 ST-Link烧录调试方便SRAM 够大外设齐全。跑通 TFLM 的 micro_speech 例程你能得到第一手的推理时间数据这比看手册估算靠谱得多。跑通之后再逐步替换成你自己的模型和传感器观察内存占用和推理时间的变化。这个过程可能会发现一些之前没考虑到的问题比如某个算子的内存开销特别大或者某个传感器的 DMA 配置和 TFLM 冲突。早发现早解决比画完板子再改要省事得多。6.3 从开发板到自研硬件的过渡要点开发板验证通过后如果要自研硬件有几个点要特别注意。第一电源设计要留余量。开发板上的电源通常比较充裕自研时如果为了省成本用了电流能力刚好的 LDO可能会在推理峰值时出现电压跌落导致芯片复位。建议电源的额定电流至少是实测峰值的 1.5 倍。第二晶振和复位电路要可靠。这两块是硬件稳定性的基础不要在这上面省钱。晶振选质量好的负载电容按手册推荐值配复位电路加合适的 RC 和二极管确保上电复位可靠。第三调试接口一定要引出。哪怕产品定型了也要留 SWD 的测试点方便后续排查问题。我见过为了省两个引脚把 SWD 去掉的板子出了问题只能拆芯片非常痛苦。第四外部存储的布线要注意信号完整性。如果用 OctoSPI 或者 SDRAM走线要等长阻抗要匹配否则高速下会出错。这块最好让有经验的硬件工程师 review 一下。第五预留传感器接口的兼容性。TinyML 项目经常需要换传感器做对比实验如果 PCB 上只留了一种传感器的接口换传感器就要重新画板。建议用排针或者 FPC 连接器把常用的接口I2S、SPI、I2C都引出来。6.4 常见选型误区与我的实际踩坑记录最后分享几个我踩过的坑希望能帮你少走弯路。误区一只看主频不看架构。我曾经选了一块 200MHz 的 M4 芯片以为比 100MHz 的 M7 快结果跑 CNN 时发现 M7 反而更快因为 M7 有双发射流水线和更大的 Cache。主频只是表象架构和 Cache 才是关键。误区二忽略 Flash 等待周期。有些芯片的 Flash 在高速下需要插入等待周期如果你把代码放在 Flash 里跑实际执行速度会比标称主频低不少。解决办法是把关键代码搬到 RAM 里跑或者选带 Cache 的芯片。误区三低估工具链的坑。TFLM 的版本更新很快不同版本之间的 API 可能有变化。我有一次用了一个新版本的 TFLM发现某个算子的实现变了导致推理结果和之前不一致。后来固定了版本问题才解决。建议在项目开始时就把工具链版本锁定不要随意升级。误区四忘记算传感器的功耗。做电池供电的设备时我只算了 MCU 的功耗忘了麦克风一直开着也要耗电。结果实测续航只有估算的一半。后来改成麦克风间歇工作续航才达标。误区五调试接口被复用。前面提过SWD 引脚被配置成 GPIO 后烧不进去。这个坑我踩过两次后来养成了习惯在代码里永远不碰 SWD 相关的引脚或者在初始化时先检查调试器是否连接。这些经验看起来琐碎但每一个都是真金白银换来的。TinyML 硬件选型没有标准答案关键是理解你的任务需求然后在这些需求之间做合理的权衡。希望这篇内容能帮你在选板子的时候少一些纠结多一些笃定。