ESP-DL — 把小模型塞进 ESP32 的推理库
待复核ESP-DL 是 Espressif 给 ESP32 系列芯片准备的神经网络推理库:它把训练好的模型压成 .espdl 文件,再让小板子在本地跑识别、检测、传感器判断。
日常类比:像把一位大厨的菜谱改写成露营炉可执行的版本。原菜谱可以很复杂,但露营炉火力小、锅也小,所以要先改分量、换步骤、安排锅具,最后才能在户外稳定做出来。
最小使用感大概是这样:
#include "dl_model_base.hpp"
extern const uint8_t model_espdl[] asm("_binary_model_espdl_start");dl::Model *model = new dl::Model((const char *)model_espdl, fbs::MODEL_LOCATION_IN_FLASH_RODATA);model->run();这段代码背后的前提是:模型已经用 ESP-PPQ 量化并导出为 .espdl,然后作为二进制资源放进 ESP-IDF 工程。
不理解 ESP-DL,下面这些事会很难解释:
- 为什么不能把 PyTorch 的
.pth文件直接拷进 ESP32-S3,然后期待它像电脑上一样运行。 - 为什么模型要先量化成 8bit 或 16bit;小芯片缺的不是“会不会算”,而是内存、带宽和算力余量。
- 为什么同一个模型给 ESP32、ESP32-S3、ESP32-P4 要用不同导出配置;底层算子和舍入策略不完全一样。
- 为什么部署时总在 FLASH、PSRAM、internal RAM 之间纠结;模型不仅要“放得下”,还要“跑得动”。
-
先换成板子能读的菜谱:ESP-DL 不直接吃训练框架文件,而是吃
.espdl。它类似 ONNX 的“模型描述”,但用 FlatBuffers 做得更轻,适合嵌入式加载。 -
算子是厨房里的工具:Conv、Gemm、Add、Mul 这些算子相当于刀、锅、烤盘。ESP-DL 把常见工具做了 ESP32-S3 / ESP32-P4 优化,还支持部分双核调度,让重活尽量两只手一起做。
-
内存规划像收纳箱:模型输入、中间结果、输出会挤在有限 RAM 里。静态内存规划器会按你给的 internal RAM 上限安排位置,在速度和省内存之间做取舍。
案例 1:把一个 sin 小模型量化成 .espdl
Section titled “案例 1:把一个 sin 小模型量化成 .espdl”官方教程用 quantize_sin_model 演示 PTQ:先训练一个拟合 sin 函数的小 PyTorch 模型,再导出 ONNX,最后用 ESP-PPQ 量化。
python sin_model.pypython quantize_torch_model.py# 或者:python quantize_onnx_model.py逐部分解释:
sin_model.py:在电脑上训练小模型,并导出权重 / ONNX,等于先把原始菜谱写出来。quantize_torch_model.py:从 PyTorch 模型入口量化,适合你还保留训练代码的情况。quantize_onnx_model.py:从 ONNX 入口量化,适合其他框架先统一转成 ONNX 的情况。- 输出通常包含
.espdl、.info、.json:一个给板子跑,一个给人检查,一个保存量化信息。
案例 2:把模型嵌进固件并做板端自测
Section titled “案例 2:把模型嵌进固件并做板端自测”最简单的加载方式是把 .espdl 嵌到应用的 .rodata 区。这样工程一烧录,模型也跟着进 FLASH。
set(embed_files your_model_path/model_name.espdl)idf_component_register(...)target_add_aligned_binary_data(${COMPONENT_LIB} ${embed_files} BINARY)#include "dl_model_base.hpp"
extern const uint8_t model_espdl[] asm("_binary_model_espdl_start");dl::Model *model = new dl::Model((const char *)model_espdl, fbs::MODEL_LOCATION_IN_FLASH_RODATA);ESP_ERROR_CHECK(model->test());model->profile(true);逐部分解释:
target_add_aligned_binary_data:把模型当二进制资源塞进固件,并保证对齐。_binary_model_espdl_start:链接器生成的符号,C++ 用它找到模型开头。model->test():用导出时保存的测试输入输出,确认板端结果没有跑偏。profile(true):同时看内存和耗时,并按耗时排序,方便先优化最慢层。
案例 3:部署 YOLO11n 这类检测模型
Section titled “案例 3:部署 YOLO11n 这类检测模型”YOLO11n 示例展示了更接近真实产品的路线:选模型、量化、看误差,再把模型接到检测应用里。
from ppq import QuantizationSettingFactory
quant_setting = QuantizationSettingFactory.espdl_setting()quant_setting.quantize_activation_setting.calib_algorithm = "percentile"quant_setting.tqt_optimization = Trueidf.py set-target esp32s3idf.py flash monitor -p /dev/ttyUSB0逐部分解释:
espdl_setting():选择和 ESP-DL 对齐的量化规则,而不是随便用通用量化配置。percentile:校准激活值范围,减少少数极端值把量化区间拉歪。tqt_optimization:用训练式的阈值微调降低精度损失,尤其适合检测模型。idf.py set-target esp32s3:告诉 ESP-IDF 这次要按 ESP32-S3 编译,目标芯片不能含糊。
- 把平台混用:ESP32、ESP32-S3、ESP32-P4 的
.espdl不能随便互换,否则推理结果可能不准。 - 忘记看算子支持表:模型里有不支持的算子,量化或部署会卡住;先查表比事后排错省很多时间。
- 以为 batch 可以随便开:ESP-DL 当前按 batch size 1 的部署方式来设计,新手从训练代码照搬多 batch 会踩坑。
- 把输入输出指针长期保存:推理时中间结果会复用同一块内存,
model_input里的数据可能被后续输出覆盖。
适用 vs 不适用场景
Section titled “适用 vs 不适用场景”适用:
- ESP32-S3 / ESP32-P4 上的轻量视觉、语音、传感器分类、目标检测。
- 已有 ONNX / PyTorch / TensorFlow 模型,愿意先做量化和板端验证。
- 对云端延迟、联网依赖、隐私传输敏感,希望设备本地先做判断。
- 需要和 ESP-IDF、Espressif BSP、组件注册表一起工作的项目。
不适用:
- 大语言模型、扩散模型、超大视觉模型;这类模型超出微控制器资源边界。
- 需要动态 batch、复杂动态图、训练时推理混合的场景。
- 算子很冷门且没人愿意实现;ESP-DL 的优势来自已优化算子。
- 完全不想碰量化、编译、烧录、串口日志的纯 Web / 纯 App 项目。
历史小故事(可跳过)
Section titled “历史小故事(可跳过)”- 2018 年前后:Espressif 开始围绕 ESP 系列芯片建设 AIoT 软件栈,ESP-DL 成为本地推理这块拼图。
- 2024 年 12 月:ESP-DL v3.0.0 发布,项目进入更系统的模型格式、算子和部署流程阶段。
- 2025 年:模型 zoo、YOLO11n、猫检测示例和 ESP-PPQ 包名迁移陆续出现,说明它不只服务玩具 demo。
- 2026 年:AutoQuant、TQT、operator agent、PIE SIMD 相关工具进入文档,优化重心从“能跑”走向“更准、更快、更少手调”。
- 社区状态:GitHub 上约 1.1k stars,语言组成里 Assembly / C++ / C 占大头,很能说明它贴近芯片底层。
- 嵌入式 AI 的核心不是“把模型复制过去”,而是“把模型改造成目标芯片能稳定执行的形状”。
.espdl是部署边界:训练框架在电脑端,ESP-DL 在板端,中间靠量化和模型格式交接。- 速度来自一串工程选择:算子优化、双核调度、8bit LUT 激活、静态内存规划,而不是单一魔法开关。
- 真正上线前要同时看三件事:精度是否还能接受、内存是否放得下、最慢层是否值得优化。
- 官方仓库:espressif/esp-dl
- 官方文档:ESP-DL User Guide
- 入门流程:Getting Started
- 量化教程:How to quantize model
- pytorch —— 训练端常见来源,最后通常要导出或转成 ONNX 再量化。
- onnx —— ESP-PPQ 常用的中间模型入口。
- pytorch —— 负责训练和导出,ESP-DL 负责板端推理。
- onnx —— 多框架模型进入 ESP-PPQ 的常见中转格式。
- tensorflow-lite —— 同样面向端侧推理,但生态和模型格式不同。
- esp-idf —— ESP-DL 工程编译、烧录、组件管理依赖它。
- quantization —— 8bit / 16bit 量化是小芯片跑模型的关键前置步骤。
- edge-ai —— ESP-DL 是边缘设备本地智能的具体实现之一。