当前位置:首页 > 中国芯 > 端侧AI
[导读]导读: 一份在 Cortex-M4F 上部署的唤醒词对比里,最小的 DS-CNN 权重 11 968 字节,准确率 44.78%;50 kB 级的 Inception 做到 91.95%。更值得看的是内存:11.7 kB 的模型要用 102 400 字节的缓冲才跑得起来,差 8.6 倍。权重是给 Flash 看的,内存是给激活看的。

一份在 Cortex-M4F 上部署的唤醒词对比里,最小的 DS-CNN 权重 11 968 字节,准确率 44.78%;50 kB 级的 Inception 做到 91.95%。更值得看的是内存:11.7 kB 的模型要用 102 400 字节的缓冲才跑得起来,差 8.6 倍。权重是给 Flash 看的,内存是给激活看的。

25 ms 一帧的地板

这份工作的输入口径定得很死:16 kHz 采样、25 ms 一帧、40 个梅尔滤波器、40×40 的频谱图、每条音频 1 秒、35 个关键词、105 829 条录音。

25 ms 一帧,意味着每秒要出 40 次判决。这个数是所有后续算账的地板,模型再小也不能让它变慢,否则唤醒就有可感知的延迟。

102 400 字节怎么来的

论文在 Arduino Nano 33 BLE 上部署了量化后的 DS-CNN,TensorFlow Lite Micro 的 arena 设成 102 400 字节。这个数不是拍出来的,是算出来的。

第一层卷积把 40×40 的单通道输入铺成多通道特征图。按 64 通道、int8 每元素一字节计,一张特征图占

A = H × W × C × 1 B = 40 × 40 × 64 = 102 400 B

正好等于 arena 的大小。这不是巧合,是张量 arena 的定义:它要能同时装下当前层的输入、输出和卷积用的临时缓冲,而 40×40×64 就是峰值。

把两个数放在一起:权重 11 968 字节,运行缓冲 102 400 字节,比值 8.6。这颗模型的 RAM 需求是 Flash 需求的八倍半。

图 1 权重与运行缓冲的对比(依据原文第 4 节绘制)

参数量不决定内存

把这件事拆开看,端侧模型占两类存储。权重放在 Flash 里,掉电不丢,容量大、读取慢;激活放在 RAM 里,读写快、容量小、按峰值分配。参数量只决定前者,激活只决定后者,两个数之间没有换算关系。

卷积层的激活大小由特征图的三个维度乘出来,与卷积核里有多少参数无关。DS-CNN 用深度可分离卷积把参数量压到极低,但每一层仍然要输出 40×40 的特征图,通道数一多,激活就上去了。

所以剪枝和权重量化救的是 Flash,救不了 RAM。要降 RAM,只有三条路:降输入分辨率、降首层通道数、改成逐块流式处理。前两条直接砍精度,第三条要求编译器支持算子融合与内存复用,工具链不一定给。

这条结论在实际选型里经常被搞反。采购看的是“模型 12 kB,256 kB RAM 的 MCU 绰绰有余”,实际跑起来 arena 就吃掉 100 kB,再加协议栈、音频缓冲、应用逻辑,RAM 见底。

体积与准确率不是一条直线

同一份工作里训了 70 个模型,覆盖 6 种架构,量化方案 4 种。几个关键点值得摆出来:

11.7 kB 的 DS-CNN,准确率 44.78%;25 kB 附近的 ResNet 78.34%,DenseNet 61.83%;50 kB 以上的 Inception 91.95%。

从 11.7 到 50 kB,体积涨 4.3 倍,准确率涨 47 个百分点,平均每 kB 换 1.2 个百分点。这个斜率不能外推,因为 25 kB 上两个架构差了 16.5 个百分点,说明在这个区间里架构比体积更重要。

44.78% 是什么概念。35 个关键词的分类任务,随机猜是 2.9%,44.78% 离可用差得远。论文自己也承认,DS-CNN 这个最小模型只是证明“能塞进去”,不是“能用”。真正能上产品的是 25 kB 以上的档位。

25 kB 这条线不是随便画的。70 个模型扫下来,50 kB 以上准确率普遍过 90%,25 kB 附近落在 62% 到 78%,12 kB 级直接掉到 45%。拐点在 25 到 50 kB 之间,往右走收益变缓,往左走是断崖。产品选型把工作点放在拐点右侧一点,是这类任务的经验值。

图 2 模型体积与准确率(依据原文第 3 节绘制)

量化不是免费的

全整型量化在整体上掉了约 20 个百分点,这个数字比多数人预期的重。

分架构看更清楚。ResNet 最小模型从 78.34% 掉到 76.67%,只掉 1.7 点;DenseNet 从 61.83% 掉到 54.24%,掉 7.6 点。同样是 int8,深度可分离结构与密集连接结构的耐受度不一样,因为逐通道的动态范围差异大,一个缩放因子盖不住所有通道。

论文试了四种量化方案:16 位浮点、动态范围量化、整型浮点混合、全整型。模型体积从大到小排下来,正好是这个顺序。内存占用却是另一回事,CENet 在全整型下占未量化版本的 85.4%,在 16 位浮点下反而到 103.5%。

16 位浮点比不量化还费内存,原因是反量化与算子开销。这条细节说明“量化一定省资源”是个过于粗的判断,省的是权重,涨的可能是运行时。

于是“先量化再压参数”这个顺序会双重打折。压参数把模型推到 44.78% 那一档,量化再砍 20 点,剩下的就不是唤醒词识别了。可行的顺序是先在浮点下把架构定到 25 kB 以上,再试量化,掉点超过 3 个就换架构。

内存预算还要算整机。板子是 Arduino Nano 33 BLE,Cortex-M4F 跑 64 MHz,Flash 1 MB,RAM 256 kB。arena 拿走 102 400 字节,剩 153.6 kB。

听起来够。但 1 秒 16 kHz 16 位单声道音频就是 32 kB,做双缓冲 64 kB,剩 89.6 kB 给协议栈、文件系统、传感器驱动与应用逻辑。蓝牙协议栈在 nRF52840 上常吃掉 30 到 50 kB,剩下三四十 kB 给业务代码,刚好够跑一个状态机。

这就是端侧语音的真实预算。模型 11.7 kB 看着轻,整机 RAM 里它带来的连锁占用是 100 kB 起,再加音频缓冲 64 kB。选 MCU 时按模型大小配 RAM 的算法会直接翻车。正确的算法倒过来:先按峰值激活、音频缓冲、协议栈三项倒推 RAM,再回头定模型能有多大。顺序换一下,选型就不用反复。

架构的选择也有现成结论。论文的推荐很清楚:设备没有浮点单元、只能走全整型量化时,选 Inception 或 ResNet,看内存还是存储更紧;DS-CNN 体积最小但精度最低,只适合做粗筛。

产品里常见的是两级结构。第一级用 12 kB 级的模型常开,命中后再拉起 50 kB 级的模型确认。内存要按大的那个算,不能相加,因为两级不同时驻留。这套结构的好处是平均功耗按小模型走,误唤醒由大模型兜住,代价是两级之间要多一次内存换入,延迟加几十毫秒。这一步的代价在多轮对话里会累加,唤醒后的第一句响应最容易感觉到。

还有一块开销与模型无关。每 25 ms 要做一次 FFT,再乘 40 个梅尔滤波器,压成 40×40 的频谱图。这部分在 64 MHz 的 M4F 上要几百微秒,模型压到 12 kB 它也一分不少。

所以端侧语音的功耗曲线不随模型线性下降。压到某个点之后,前端与常开逻辑成了底噪,再压模型只是在噪声里找数。

25 ms 是硬约束

64 MHz 的 Cortex-M4F 上,量化后的模型推理在 1 ms 以内。一次推理 64 000 个周期,一帧 25 ms 对应 1 600 000 个周期,占空比 4%。这个余量很大,说明在这类任务上,通用 MCU 的算力不是瓶颈。

换成软核就完全不是一回事。论文在 Artix-7 上用 75 MHz 的 RISC-V 软核加自定义功能单元跑同一个模型,单次推理 26 777 075 个周期,357 ms。帧周期只有 25 ms,一次推理要 14 帧的时间。

两个数放在一起,结论很清楚:算力不是靠主频堆出来的,指令集与数据通路的差别能到两个数量级。做端侧语音的团队如果拿 FPGA 软核做原型验证,测出来的延迟不能当成产品指标。

这条对比还有一个用法。做算法验证时,先在 PC 上量化、再直接上目标板看延迟,中间那一步不要用软核顶替。软核的数字既不代表 MCU,也不代表 NPU,它只代表那颗软核。论文把 357 ms 写出来,价值就在这里:它把一个常被忽略的中间态摆到了台面上。

一句话:端侧模型的体积写在 Flash 上,能不能跑写在 RAM 上,两个数差 8.6 倍,选型时看错一个就白算。

内容来源:Future Internet(MDPI),开放获取

原文标题:Neural Network Exploration for Keyword Spotting on Edge Devices

作者:Jacob Bushur, Chao Chen

DOI:10.3390/fi15060219

链接:https://doi.org/10.3390/fi15060219

配图说明:自行绘制,为原理示意,非原文原图复制

改动声明:对开放获取文献的技术编译与解读,标题、行文与配图为原创

来源:21ic电子网

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭