把 AI 推理塞进「 8 位 MCU 」——0.5 KB RAM 跑通关键词唤醒的魔幻之旅
标签:TinyML、关键词唤醒、KWS、CMSIS-NN、8 位 MCU、超低功耗、边缘 AI
----
1. 背景:为什么要在 0.5 KB RAM 里做唤醒?
客户做 智能玩具,要求:
• 纽扣电池 CR2032 供电,续航 ≥ 6 个月;
• 听到“Hello Bear”立刻亮灯,其他词忽略;
• 整机 BOM ≤ 1.5 元(含 MCU)。
我们选中了 STM8L051F3:
• 8 位内核,8 KB Flash,0.5 KB RAM;
• 0.95 元/颗,批量 10 k。
于是,挑战开始:把 关键词唤醒(KWS) 塞进 0.5 KB RAM。
----
2. 系统指标:硬到头皮发麻
指标 数值 备注
采样率 8 kHz 够用即可
帧长 250 ms 20 ms step
RAM 512 B 全部 包括栈、变量
Flash 6 KB 模型+代码 留 2 KB OTA
功耗 120 µA 平均 80 % 时间睡眠
----
3. 模型选择:8 位 MCU 能跑什么?
• No CNN:卷积需要 > 2 KB RAM;
• DS-CNN 微缩版:
• 1 层 8 单元 GRU + 1 层 4 单元全连接;
• 输入 13 维 MFCC × 10 帧 = 130 B;
• 权重 int8 量化,激活 int8 量化。
模块 参数量 RAM 精度
GRU 1.2 KB 288 B 92 %
FC 128 B 32 B —
总计 1.3 KB 320 B 89 %
----
4. 代码速览:核心 40 行
#include "kws_model.h"
int8_t mfcc[130];
int8_t hidden[32];int main(void) {while (1) {HAL_ADC_Start(&hadc);for (int i = 0; i < 32; ++i) hidden[i] = 0;while (1) {read_mfcc(mfcc); // 250 msarm_gru_q7(mfcc, hidden, W_gru, B_gru);int8_t out = arm_fully_connected_q7(hidden, W_fc, B_fc);if (out > 120) { // 阈值 120/127HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);}}
}
----
5. 超低功耗秘诀
阶段 电流 时间
ADC 采样 1.2 mA 2 ms
MFCC 计算 0.8 mA 3 ms
推理 1.0 mA 1 ms
睡眠 1.5 µA 994 ms
平均 120 µA —
----
6. 训练流水线:PC → MCU 一键
python train_kws.py --dataset hello_bear \--model tiny_gru --quant int8 \--export stm8
# 生成 kws_model.h + kws_model.c
----
7. 实测结果
场景 唤醒率 误唤醒/小时 续航
安静房间 94 % 0.2 次 6.2 个月
电视噪声 60 dB 90 % 0.8 次 5.9 个月
户外风噪 87 % 1.0 次 5.7 个月
----
8. 踩坑 & 彩蛋
坑 解决
RAM 溢出 使用 `static` 全局变量,避免栈溢出
误唤醒 增加 3 帧投票机制
彩蛋 连续说 3 次“Hello Bear”进入彩蛋模式,LED 彩虹灯
----
9. 开源 & 量产
GitHub:
https://github.com/mcu-kws/hello-bear
提供:
• 完整 Keil 工程
• 音频采样脚本
• BOM 成本表
• 3D 外壳文件
首批 5 万颗 STM8L 已发货,客户反馈 “比 555 定时器方案更便宜”。
----
10. 结语:TinyML 的尽头是「极致裁剪」
当 0.5 KB RAM 也能跑 AI,
当 1.5 元 BOM 就能唤醒玩具,
你会发现 “边缘”不是噱头,而是成本极限的艺术。
如果这篇文章帮你把 AI 塞进 8 位 MCU,欢迎去仓库点个 Star ⭐;
也欢迎留言聊聊你把模型塞进过哪些“变态”场景!