端侧 AI · 15 天工程路线
目录首页 English
DAY 05

端侧模型部署

把非 LLM 视觉、音频与传感器模型真正烧进设备

建议阅读:约 19 分钟

学习目标

完成数据、训练、导出、量化、部署、验证的闭环,重点覆盖 MCU 常见小模型。

本章关键词

关键词解释ESP32 工程类比
代表性数据覆盖真实设备工况的数据集合。像整机测试必须覆盖温湿度、电源和负载边界。
Tensor arena为 MCU 推理预分配输入、输出和中间张量的内存区。像启动时规划好的静态工作区。
前处理将原始传感器数据变成模型输入的步骤。像协议栈的 framing、字节序和校验。
混淆矩阵按真实类别与预测类别统计的表。像按故障类型统计误报和漏报。

承上:回顾与定位

前四章已经建立模型数学、产物契约、量化与 kernel 基础;本章把它们放进真实 TinyML 项目的训练—转换—固件闭环。

从源头看今天

历史发展脉络

把小模型放进 MCU,并不是把桌面推理代码缩小后复制过去。它经历了“结构更省算力—kernel 更贴硬件—runtime 更少依赖—产品验证更可重复”的共同演进,最终才形成今天从数据到固件的闭环。

1989

结构化卷积网络走向真实任务

LeCun 等人把局部连接、权重共享与反向传播用于邮政编码识别,说明可以让网络直接处理像素,同时用结构约束压低参数与计算需求。

LeCun 等原始论文 ↗
2017

MobileNet 把硬件预算写进网络设计

MobileNet 以深度可分离卷积和宽度、分辨率系数显式交换准确率与延迟,“先定设备预算再选模型”由经验做法变成可调设计方法。

MobileNet 原始论文 ↗
2017

生产级 ML 开始强调系统测试

Google 的 ML Test Score 将数据、特征、模型、基础设施与监控拆成具体测试项,指出离线指标只是上线准备度的一部分。

Google Research 原始论文 ↗
2018

CMSIS-NN 让量化模型贴近 Cortex-M

CMSIS-NN 提供面向 Cortex-M 的卷积、全连接等优化 kernel,并用部分 im2col 等办法同时降低运行时间和峰值内存。

CMSIS-NN 原始论文 ↗
2020

TFLite Micro 固化微控制器运行时范式

TFLite Micro 面向没有虚拟内存、资源紧张且平台碎片化的设备,采用小型解释器和预规划工作区,让同一模型能进入多种 MCU。

TFLite Micro 原始论文 ↗
现在

ESP-DL 串起量化、格式、内存规划与分析

当前 ESP-DL 用 ESP-PPQ、.espdl 格式、静态内存规划和设备侧 profiling 把模型转换、加载、执行与测量放进同一工具链。

ESP-DL 官方介绍 ↗
今天为什么仍然重要: 这条脉络留下的工程结论很明确:模型结构只决定“可能跑多快”,前处理契约、量化导出、kernel 覆盖、任务调度和板端回归测试才决定它是否真的成为产品功能。
借熟悉的系统建立直觉

类比图解

一座把鲜果变成果汁的微型工厂

果园每天送来的果子并不整齐:大小、成熟度、泥点都不同。实验室先制定验收样本和清洗配方,再训练“质检员”;量产线必须照同一配方切块、称重,质检结果还要经过阈值与复核,才会真正打开装瓶阀门。

果筐与留样 真实设备采集、标签规范、训练/验证/测试切分
清洗切块配方 采样、resize、归一化、量化输入等前处理契约
微型质检员 量化后的模型、设备 kernel 与 tensor arena
装瓶放行灯 阈值、去抖、fallback 与业务事件

类比的边界: 类比能解释闭环和契约,却不能把模型当成固定规则质检机:它输出的是依赖数据分布的概率或分数。现场出现训练集未覆盖的新工况时,配方完全一致也不保证判断正确,仍需漂移监控、拒识与安全状态机。

本章讲解

从产品事件反推数据,而不是从现成数据集寻找用途

先写出设备最终要发布的事件、允许的漏报和误报、响应时限以及无法判断时的动作,再据此定义采样窗口和标签。训练集要按设备或采集批次切分,避免同一段连续信号泄漏到训练与测试两侧;负类不能只有“安静背景”,还要包含容易混淆的动作、噪声和传感器异常。每条样本应保留固件版本、采样率与环境元数据,才能在回归时定位数据漂移。

把前处理做成可校验的二进制契约

PC 训练管线与固件必须对采样率、通道顺序、裁剪窗口、插值方式、颜色空间、归一化常数、舍入和饱和规则逐项一致。不要只比较最终类别;选若干黄金样本,在原始 buffer、预处理浮点张量、量化整数张量三个边界计算摘要并抽查元素。若部署工具要求 int8 输入,还要确认 scale 与 zero-point 的方向,避免把已经量化的数据再次量化。

把导出和转换看作编译链,而不是文件另存为

训练 checkpoint 先切换推理语义,再导出含固定 I/O 契约的图;转换器随后折叠常量、替换算子、量化并生成目标格式。每一阶段都可能改变布局或数值,因此要锁定工具版本,保存算子清单、输入输出名称和量化参数,并用同一批输入做逐阶段差分。转换成功只证明文件可生成;目标 runtime 没有对应 kernel、发生浮点 fallback 或 shape 超界时仍会失败。

让推理成为受调度约束的固件任务

设备端需要同时安排传感器生产者、DMA、预处理、推理和事件消费者。采用有界队列并明确满队列策略:实时任务通常丢旧帧比无限等待更合理;推理期间若占用长时间 CPU,应分片、降低频率或喂狗,但不能用喂狗掩盖死锁。arena、模型和 I/O buffer 尽量在初始化期分配,稳态路径避免碎片化;错误分支必须归还帧并发布可观察的降级状态。

用四层证据完成部署验收

验收依次比较源框架、导出模型、目标 runtime 和真实板端,既测固定黄金向量,也回放整段原始采集。结果至少包含混淆矩阵、按类别阈值曲线、p50/p95 延迟、峰值 arena、长时间运行与异常输入。业务层还要验证迟滞、连续命中次数和冷却时间,避免分数在阈值附近抖动成事件风暴。升级模型或 SDK 后重跑同一清单,才能区分精度回归与系统回归。

让数据真正跑起来

动态过程演示

一条样本如何变成设备事件

播放器逐步点亮数据形态和责任边界,并在最后把现场失败样本送回数据集。

步骤 1 / 6

采集与标注 · raw window + label + metadata

按设备与场景记录原始样本,冻结标签规则

观察点

数据来源决定模型能识别的世界

循环 / 返回条件: 现场回流的样本经过人工复核后重新进入“采集与标注”,但旧测试集保持冻结,用来判断新版本是否真的改善。

查看静态全景图
Sensor → DMA/RingBuffer → Preprocess → Inference → Postprocess → Event/Actuator

代码或命令示例

idf.py build flash monitor
# 设备端关注:arena、tensor arena、输入归一化、推理耗时
ESP_LOGI(TAG, "latency=%d ms", elapsed_ms);

动手实验

用 IMU/声音/图像任选其一,做一个 2~4 类分类器;在 PC 与 ESP32 上对比输入归一化、延迟和混淆矩阵。
实验记录与导出

工程陷阱

避免误判: PC 端把 float 图像直接喂给模型而固件端错误地喂 RGB565 或漏掉归一化,是设备准确率突然下降的高频原因。

核心测试

完成 3 道单选题后提交;提交前不会显示答案。

1. 设备端精度明显低于 PC 时,最先比对什么?
2. Tensor arena 不足通常意味着什么?
3. 何时应把通用 LLM 放到 Linux Edge Host?

一起把本章讲清楚

在 GitHub 上讨论本章

登录 GitHub 后提问、补充实测或分享你的实现;评论会保存在本课程的 GitHub Discussions 中。

评论区需要 JavaScript;也可以直接打开 GitHub 讨论区: 打开 GitHub 讨论区 ↗

延伸阅读

启下:下一章如何使用本章能力

下一章合并资源预算与视觉流水线,在 Flash、SRAM、PSRAM、DMA、前处理和事件后处理之间完成稳态验收。

下一天: Day 6 · 端侧视觉流水线