1. 一块能跑AI模型的TinyML开发板硬件选型到底在选什么TinyML这个词这两年热度上来了但很多人第一次接触时都会有个误区觉得只要MCU主频够高、内存够大就能跑AI模型。实际做过几个项目之后你会发现事情远没有这么简单。一块能跑AI模型的TinyML开发板硬件选型本质上是在做一场“在针尖上跳舞”的平衡术——算力、内存、功耗、外设、成本五个维度互相拉扯任何一个短板都会让模型跑不起来或者跑得很难受。我最早接触TinyML是在一个语音唤醒关键词识别的项目上当时选了一颗主频不低的Cortex-M4芯片满心欢喜地把训练好的模型转成C数组烧进去结果一跑就HardFault。排查了半天才发现模型推理过程中的中间张量把RAM撑爆了。从那以后我就明白了一个道理TinyML开发板的硬件选型不能只看主频得从模型的计算图和内存布局反推硬件需求。这篇文章主要面向两类人一类是嵌入式工程师想转型做TinyML手里有开发板但不知道怎么评估能不能跑AI另一类是算法工程师想把模型部署到端侧但对硬件参数没概念。我会从实际项目出发把TinyML开发板需要的核心硬件拆开来讲包括MCU选型、内存架构、外设接口、功耗设计、调试工具链这几个维度每个维度都会给出具体的参数参考和选型逻辑。看完之后你至少能判断一块开发板能不能跑你的模型以及如果要自己画板子哪些地方不能省。2. TinyML开发板的核心硬件架构拆解2.1 MCU选型为什么STM32H743成了热门参考聊TinyML开发板的MCU选型STM32H743是一个绕不开的型号。这颗芯片在TinyML社区里被大量用作参考平台原因很直接Cortex-M7内核主频480MHz带双精度浮点单元FPU还有指令和数据缓存。这几个特性凑在一起刚好卡在TinyML的甜点位上。先看主频。TinyML模型推理本质上是大量的乘加运算MAC主频直接决定了每秒能完成多少次MAC。以关键词识别常用的DS-CNN模型为例参数量大概在2万到5万之间每次推理需要的MAC数量在百万级别。480MHz的M7内核配合FPU和CMSIS-NN库优化跑一次推理大概在10到30毫秒之间这个延迟对于语音唤醒场景是可以接受的。如果换成主频80MHz的Cortex-M0同样的模型可能要跑几百毫秒实时性就没了。再看FPU。很多人觉得TinyML模型都是量化成int8的不需要浮点。这个想法对了一半。推理阶段确实可以用int8但模型的前处理和后处理往往涉及浮点运算比如音频的MFCC特征提取、图像的归一化。没有硬件FPU的话这些操作会吃掉大量CPU周期。STM32H743带的是双精度FPU虽然TinyML主要用单精度但有总比没有强。缓存这个点容易被忽略。Cortex-M7有I-Cache和D-Cache对于模型权重存放在外部Flash、运行时搬运到内部RAM的场景缓存能显著减少访问延迟。我实测过开启D-Cache之后一个图像分类模型的推理速度提升了将近40%。当然缓存也带来了一致性问题DMA传输和缓存刷新要特别小心这个后面会细说。除了STM32H743市面上常见的TinyML开发板MCU还有几个梯队。第一梯队是Cortex-M7和Cortex-M55M55带Helium向量扩展对int8和int16的SIMD支持更好但开发板价格偏高。第二梯队是Cortex-M4和M33主频在80到200MHz之间适合中小型模型。第三梯队是Cortex-M0和M3基本只能跑极小的模型比如简单的异常检测。MCU内核典型主频FPU适合模型规模典型开发板Cortex-M048-80MHz无极小10KB参数低功耗传感器节点Cortex-M480-200MHz单精度中小10-100KB通用TinyML入门板Cortex-M7400-600MHz双精度中大型100KB-1MBSTM32H743/H750Cortex-M55200-400MHz带Helium中大型向量加速Alif EnsembleCortex-M33100-200MHz单精度中小安全带TrustZone的板子选MCU的时候还有一个隐藏参数Flash和RAM的容量以及总线架构。STM32H743有2MB Flash和1MB RAM而且RAM分成了多个块有DTCM、AXI SRAM、SRAM1-4等。DTCM紧耦合内存访问延迟最低适合放模型推理时的中间张量。AXI SRAM容量大适合放模型权重。这种多块内存的架构给了你很大的优化空间但也意味着你需要手动规划内存布局不能像PC上那样随便malloc。2.2 内存架构模型能不能跑起来的关键TinyML开发板上跑AI模型内存是比算力更常见的瓶颈。一个模型占用的内存分三部分权重weights、激活值activations和中间缓冲区scratch buffer。权重是静态的可以放在Flash里运行时按需加载到RAM。激活值是每层计算的输入输出必须放在RAM里。中间缓冲区是某些算子比如卷积的im2col需要的临时空间。以STM32H743为例1MB的RAM听起来不少但实际能用的没那么多。DTCM有128KBAXI SRAM有512KBSRAM1-4加起来有384KB。如果你用TensorFlow Lite Micro作为推理引擎它本身会占用一部分内存作为tensor arena。这个arena的大小需要你根据模型的最大中间张量来估算。我一般会这样估算先看模型每一层的输出张量大小取最大值再乘以2到3倍的余量。比如一个模型的最大中间张量是50KB那tensor arena至少设150KB。如果模型权重也放在RAM里还要加上权重的大小。STM32H743的1MB RAM跑一个100KB权重、150KB arena的模型是绰绰有余的但如果你想把整个模型都塞进DTCM那就不够了。外部内存扩展是另一个思路。有些TinyML开发板会带HyperRAM或者SDRAM容量从几MB到几十MB。但外部内存的访问延迟比内部RAM高一个数量级对于需要频繁访问的激活值来说放在外部内存会严重拖慢推理速度。我的经验是权重可以放外部Flash运行时按层加载激活值必须放内部RAM中间缓冲区如果内部RAM不够可以放外部RAM但要接受性能损失。还有一个容易踩的坑是内存对齐。Cortex-M7的D-Cache是按cache line32字节操作的如果DMA传输的目标地址没有32字节对齐缓存刷新的时候会把相邻数据也刷掉导致数据损坏。我在一个摄像头项目里就遇到过这个问题图像数据通过DMA搬到RAM结果每隔几行就出现花屏。后来把缓冲区地址强制32字节对齐问题就消失了。所以画板子的时候外部内存的地址映射要留好对齐余量。2.3 外设接口传感器和调试的通道TinyML开发板的外设接口决定了它能接什么传感器以及调试起来方不方便。常见的外设包括I2C、SPI、UART、I2S、PDM、ADC、DCMI等。不同的AI应用场景需要的外设不一样。语音类应用需要I2S或者PDM接口接数字麦克风。PDM麦克风便宜且布线简单但需要MCU做抽取滤波会消耗CPU。I2S麦克风输出的是PCM数据MCU直接读就行但价格贵一些。STM32H743的SAI接口支持I2S和PDM配合DMA可以做到零CPU开销采集音频。我一般推荐用I2S麦克风省下来的CPU周期可以留给模型推理。图像类应用需要DCMI或者SPI接口接摄像头。DCMI是并口速度快适合高分辨率摄像头。SPI接口的摄像头布线简单但带宽有限适合低分辨率场景。TinyML的图像模型输入通常是96x96或者128x128的灰度图SPI摄像头的带宽勉强够用。如果要做160x160以上的彩色图最好用DCMI。调试接口方面SWD是标配但TinyML开发板最好带一个高速UART或者USB CDC用来输出推理结果和性能数据。我习惯在代码里加一个性能计数器每次推理完通过UART打印耗时和内存占用这样调优的时候心里有数。另外如果开发板带ETM或者SWO引脚可以用指令追踪功能分析热点函数对优化推理速度很有帮助。应用场景必需外设推荐外设注意事项语音唤醒I2S/PDM麦克风SAIDMAPDM需CPU抽取I2S更省资源图像分类DCMI/SPI摄像头DCMIDMASPI带宽有限高分辨率用DCMI振动检测ADC/I2C加速度计SPI加速度计采样率要满足Nyquist手势识别I2C/SPI IMUSPI IMU注意中断引脚和FIFO异常检测ADC硬件触发ADC用定时器触发保证采样率2.4 功耗设计电池供电场景的硬约束TinyML的一大卖点是端侧低功耗推理所以开发板的功耗设计很关键。功耗分动态功耗和静态功耗。动态功耗跟主频和电压有关静态功耗主要是漏电流和外围器件的待机功耗。STM32H743在480MHz全速运行的时候电流大概在200mA左右这个功耗对于电池供电的设备来说太高了。实际部署的时候一般会用动态调频推理的时候升到高频推理完降回低频或者进入Stop模式。Stop模式下电流可以降到几十微安配合RTC定时唤醒平均功耗可以做到毫安级别。但这里有个坑从Stop模式唤醒的时间。STM32H743从Stop模式唤醒大概需要几十微秒如果推理本身只要10毫秒唤醒开销占比不大。但如果你的应用是每秒推理一次那大部分时间都在Stop模式平均功耗就很低。我做过一个振动异常检测的项目用加速度计的中断唤醒MCU推理完立刻回Stop模式平均电流只有1.2mA用CR2032纽扣电池能撑好几个月。开发板上的外围器件也会吃电。LDO的静态电流、电平转换芯片的漏电流、LED指示灯这些加起来可能比MCU待机电流还大。自己画板子的时候不用的外设要彻底断电LED要能通过跳线断开。我见过一个开发板MCU待机电流只有5微安但板载的USB转串口芯片待机电流有500微安直接把低功耗优势抵消了。3. 从模型到硬件实操选型流程3.1 第一步确定模型的资源需求在选硬件之前你得先知道模型要吃什么。如果你用的是TensorFlow Lite Micro可以用它的分析工具输出每层的张量大小和算子类型。我一般会关注三个数字模型权重大小、最大中间张量大小、算子类型分布。模型权重大小决定了Flash需求。int8量化的模型权重大小约等于参数量乘以1字节。比如一个5万参数的模型权重大概50KB。加上推理引擎的代码Flash至少留256KB比较稳妥。最大中间张量大小决定了RAM需求。这个数字在TFLite Micro的模型分析里能看到叫“arena size”。但实际分配的时候要留余量因为不同版本的推理引擎可能有差异。我的经验是乘以1.5倍。算子类型分布决定了MCU的指令集需求。如果模型里全是卷积和全连接那带FPU和DSP扩展的M4/M7就很合适。如果模型里有大量element-wise操作那内存带宽可能成为瓶颈需要关注总线的位宽和频率。3.2 第二步匹配MCU的算力和内存拿到模型的资源需求后就可以对照MCU的参数来匹配了。算力方面我一般用“MAC数量除以主频”来估算推理时间。比如模型需要100万次MACMCU主频480MHz理论上每次MAC一个周期那推理时间约2毫秒。但实际上因为内存访问、循环开销、算子实现效率实际时间可能是理论值的3到5倍。所以100万MAC的模型在STM32H743上大概跑6到10毫秒。内存方面把权重大小、arena大小、推理引擎开销、栈空间加起来跟MCU的可用RAM对比。注意MCU的RAM不是全部可用的启动文件、堆栈、外设缓冲区都要占一部分。STM32H743的1MB RAM实际能留给模型的大概800KB左右。如果算下来发现MCU跑不动有几个优化方向一是进一步量化模型比如从int8降到int4二是用剪枝或者知识蒸馏缩小模型三是换更高性能的MCU比如带Helium的M55四是把模型拆成多段用外部Flash存储权重运行时按层加载。3.3 第三步验证外设和调试通道模型能跑起来之后还要确认外设能不能满足数据采集的需求。比如语音唤醒需要麦克风以16kHz采样每次推理需要1秒的音频数据那就是16000个采样点。如果用的是PDM麦克风MCU需要做抽取滤波这个计算量要算进CPU预算里。调试通道也很重要。我习惯在开发板上留一个UART接口专门用来输出推理日志。日志内容包括推理耗时、内存占用、输入数据的统计特征、输出置信度。这些数据对于调优模型和排查问题非常有用。如果开发板带USB可以用USB CDC虚拟串口速度比UART快很多适合传输大量数据。3.4 第四步功耗预算和电源设计如果是电池供电的场景功耗预算要提前算。假设设备用1000mAh的锂电池期望续航一年那平均电流要控制在0.11mA以下。这个要求很苛刻意味着MCU大部分时间必须在Stop模式推理占空比要非常低。我一般会这样设计用传感器的事件中断唤醒MCUMCU采集数据、推理、输出结果然后立刻回Stop模式。整个活跃时间控制在几十毫秒以内占空比低于1%。这样平均电流可以做到毫安级别续航几个月到一年。电源设计方面如果输入电压和MCU电压接近用LDO就行。如果压差大用DC-DC效率更高。但DC-DC的开关噪声可能影响模拟外设比如ADC和麦克风。我一般会在DC-DC输出后面加一级LDO给模拟部分供电数字部分直接用DC-DC。4. 常见问题与排查技巧实录4.1 模型跑不起来HardFault和内存溢出HardFault是TinyML部署中最常见的问题十有八九是内存相关。可能的原因包括tensor arena太小、栈溢出、内存对齐问题、DMA和缓存冲突。排查HardFault的第一步是看LR和PC寄存器的值定位出错指令的地址。如果地址在memcpy或者memset里基本可以确定是内存越界。这时候把tensor arena调大试试如果问题消失那就是arena不够。栈溢出也很常见。TFLite Micro的推理函数调用层次比较深局部变量多默认的栈大小可能不够。我一般会把栈设到8KB以上如果模型复杂设到16KB。在STM32CubeMX里可以调整栈大小但要注意栈和堆的总和不能超过RAM容量。内存对齐问题在Cortex-M7上特别突出。D-Cache的cache line是32字节如果DMA的目标缓冲区没有32字节对齐缓存刷新会破坏相邻数据。解决方法是用__attribute__((aligned(32)))修饰缓冲区或者在DMA传输前后做cache clean/invalidate。4.2 推理速度慢性能瓶颈定位推理速度慢的原因可能有很多主频没跑满、缓存没开、算子实现效率低、内存带宽不够。我一般会按这个顺序排查。先确认主频。STM32H743默认的时钟配置可能不是480MHz需要手动配置PLL。用SystemCoreClock变量确认实际主频。如果主频不对检查时钟树配置和电源电压。STM32H743跑480MHz需要把电压调到Scale 1模式否则会不稳定。再确认缓存。I-Cache和D-Cache默认可能是关闭的需要在启动代码里开启。开启缓存后记得配置MPU把外部内存区域设为Non-cacheable避免缓存一致性问题。然后看算子实现。TFLite Micro的参考算子是没有优化的跑得慢很正常。CMSIS-NN提供了针对Cortex-M优化的算子速度能快好几倍。把TFLite Micro的算子替换成CMSIS-NN的是提升推理速度最直接的方法。最后看内存带宽。如果模型权重放在外部Flash每次推理都要从Flash读权重SPI Flash的带宽可能成为瓶颈。解决方法是用内存映射模式XIP读Flash或者把权重预加载到RAM。4.3 功耗降不下来待机电流排查低功耗项目最头疼的就是待机电流比预期高。排查方法是一步步断开外设看电流变化。先把所有GPIO设为模拟输入或者输出低避免浮空输入导致的漏电流。然后关闭不用的外设时钟比如ADC、SPI、I2C。如果板子上有LDO或者DC-DC确认它们的静态电流。有些LDO的静态电流有几百微安换成低静态电流的型号能省不少。调试接口也会吃电。SWD接口在待机时如果保持连接调试器可能会给MCU供电或者拉高某些引脚。量产的时候可以把SWD引脚复用成GPIO或者加跳线断开。还有一个隐蔽的坑是Flash的待机电流。有些外部Flash芯片在待机时电流有几十微安如果不需要存储数据可以把Flash的片选拉高让它进入深度睡眠。4.4 常见问题速查表问题现象可能原因排查方法解决方案HardFaultarena太小增大arena看是否消失调整arena大小HardFault栈溢出查看SP是否越界增大栈空间推理结果错误内存对齐检查缓冲区地址32字节对齐推理结果错误缓存一致性关闭D-Cache测试配置MPU或手动刷新推理速度慢主频未跑满查看SystemCoreClock配置PLL和电压推理速度慢算子未优化对比CMSIS-NN替换算子实现待机电流高外设未关逐个关闭外设关闭时钟和电源待机电流高GPIO浮空设为模拟输入配置GPIO模式麦克风无数据PDM时钟不对示波器看时钟调整SAI配置摄像头花屏DMA带宽不够降低分辨率测试优化DMA优先级4.5 几个容易忽略的实操心得第一个心得是关于模型转换的。TensorFlow Lite的转换器有很多参数比如representative_dataset、inference_type、supported_ops。如果转换的时候没有指定representative dataset量化后的模型精度可能掉得很厉害。我一般会准备几百张代表性样本覆盖各种场景这样量化后的精度损失能控制在1%以内。第二个心得是关于内存布局的。STM32H743的DTCM和AXI SRAM在地址空间上是连续的但访问速度不一样。把频繁访问的数据放在DTCM把大块的权重放在AXI SRAM能明显提升性能。在链接脚本里可以指定变量放到哪个内存段比如__attribute__((section(.DTCM)))。第三个心得是关于调试的。TinyML的调试比普通嵌入式开发麻烦因为你看不到中间张量的值。我的做法是在模型里插入几个输出节点把中间层的统计特征均值、方差、最大值打印出来跟PC上跑的结果对比。如果差异大说明量化或者算子实现有问题。第四个心得是关于开发板选择的。如果只是学习和验证买现成的开发板就行STM32H743I-EVAL或者Nucleo-H743ZI都不错。如果要量产建议自己画板子把不需要的外设去掉优化功耗和成本。自己画板子的时候MCU的电源引脚一定要加足够的去耦电容STM32H743的电源引脚有十几对每对都要加100nF和10uF的电容否则高速运行时可能不稳定。第五个心得是关于工具链的。STM32CubeMX和CubeIDE是标配但TFLite Micro的集成需要手动配置。我一般会用Makefile或者CMake管理项目把TFLite Micro的源码和CMSIS-NN的库加进去。编译的时候注意优化等级-O3比-Os快不少但代码体积会大一些。如果Flash够用优先用-O3。5. 自己画一块TinyML开发板的硬件清单参考如果你看完上面的内容想自己画一块专门跑TinyML的开发板这里给一个硬件清单参考。这个清单是基于STM32H743的适合中大型模型兼顾性能和功耗。核心器件方面MCU选STM32H743VIT6LQFP100封装2MB Flash1MB RAM。电源用TPS62840或者类似的低静态电流DC-DC输出3.3V和1.8V。如果对噪声敏感1.8V可以用LDO。外部Flash选W25Q128或者IS25LP128128MbitSPI接口支持XIP。外部RAM可选如果模型大加一颗APS6404 HyperRAM8MB用来放权重。传感器接口方面留一个I2S接口接数字麦克风比如INMP441。留一个DCMI接口接摄像头比如OV7670或者OV2640。留一个SPI接口接IMU比如LSM6DSO。留一个I2C接口接环境传感器比如BME280。调试接口用SWD加一个USB CDC虚拟串口。功耗管理方面MCU的电源域要分开VBAT、VDD、VDDA都要有去耦。不用的外设电源要能通过跳线断开。LED指示灯要能通过跳线断开。SWD引脚要能通过跳线断开。PCB布局方面MCU的电源引脚去耦电容要尽量靠近引脚。晶振要靠近MCU负载电容要匹配。高速信号线比如DCMI、I2S要等长避免反射。模拟部分和数字部分要分开地平面要完整。这个清单只是一个参考具体选型要根据你的模型和应用场景调整。比如如果你的模型很小用Cortex-M4就够了成本和功耗都更低。如果你的模型需要向量加速可以考虑带Helium的M55。如果你的应用需要无线连接可以加一颗Wi-Fi或者蓝牙芯片但要注意射频部分的布局和认证。我在实际画板子的过程中踩过不少坑最大的教训是不要为了省成本而砍掉调试接口。TinyML的调试本来就麻烦如果没有方便的调试通道排查问题会非常痛苦。另外电源的去耦电容不要省STM32H743在480MHz运行时对电源噪声很敏感去耦不够会导致随机死机。最后如果要做低功耗一定要在画板子之前把功耗预算算清楚每个器件的静态电流都要查数据手册确认不要想当然。
阅读完成 · 觉得有帮助?