真正把 TinyML 模型放進去時,問題馬上具體起來:模型文件由誰解析?INT8 卷積由誰加速?激活緩沖放在哪里?芯片廠商有沒有現成例程?芯片采用 Cortex-M4 或 RISC-V,只能回答其中一部分。
![]() |
圖1:國產 MCU 部署 TinyML 的四條常見路線
樂鑫給出的 ESP-DL 鏈路相對完整。訓練端先得到 PyTorch 或 ONNX 模型,ESP-PPQ 負責量化并導出 .espdl,板端由 ESP-DL 加載模型、規劃內存并執行算子。當前官方快速入門重點覆蓋 ESP32-S3 和 ESP32-P4。
這里有一個容易漏掉的細節:ESP-DL 的模型與目標平臺相關。ESP32-S3 與 ESP32-P4 的量化粒度、舍入方式和算子實現存在差異,已經導出的 .espdl 不能隨意跨平臺復用。遷移芯片時要重新指定目標、重新量化,再用固定樣本對齊 PC 與板端輸出。
HPM SDK 已經集成 TensorFlow Lite for Microcontrollers,并提供 samples/tflm 例程。開發者可以從廠商已經跑通的時鐘、串口、鏈接腳本和構建工程出發,把工作集中到算子注冊、Tensor Arena、輸入預處理與輸出校驗。
這條路線仍然需要測量內存與延遲。SDK 集成解決的是“工程怎樣編譯和啟動”,模型中的算子組合、激活峰值和板端輸入格式仍由項目決定。換一個網絡結構,原例程的 Arena 大小和算子列表往往要跟著改。
GD32、HC32、MM32、APM32、N32,以及航順、芯海、中微和東軟載波的 Cortex-M 產品,通常可以采用 TFLM 加 CMSIS-NN。TFLM 負責讀取模型、建立張量和調度算子;CMSIS-NN 提供面向 Cortex-M 的卷積、全連接、池化、Softmax 等優化內核。
CMSIS-NN 不能單獨加載 .tflite 模型。TFLM 在算子執行階段調用優化內核,二者處于不同層級。對于 Star-MC1 等兼容 Cortex-M33 的內核,建議先用 TFLM 參考內核對齊輸出,再啟用 CMSIS-NN,隨后比較數值誤差、代碼尺寸和周期數。
沁恒 CH32V 采用青稞 RISC-V 內核,CMSIS-NN 無法提供算子加速。高性能 CH32V317、CH32V407 可以移植 TFLM 參考內核,再針對乘加、卷積和激活熱點引入 RISC-V 或 RVV 優化;平臺層、編譯參數、內存對齊和優化庫都要重新核對。
經典 8051、低端 Cortex-M0/M3 和只有十幾 KB RAM 的型號,更適合把模型轉換成固定計算流程:線性分類器、邏輯回歸、小型決策樹、原型距離或手寫定點全連接網絡。權重直接保存為 C 數組,推理函數只保留乘加、比較和查表,能夠避開完整 C++ 運行時與大塊 Tensor Arena。
下面的“優先系列”用于建立第一版原型,不代表整條產品線都有相同資源。最終選型必須回到具體料號的數據手冊,確認 SRAM 分塊、連續地址空間、Flash 容量、Cache、FPU/DSP、外部存儲器接口和采樣外設。
這張表里最需要警惕的是“同內核等于同體驗”。同為 Cortex-M4,192KB SRAM 與 68KB SRAM 能容納的激活張量差異很大;同為 M33 兼容內核,編譯器宏、DSP 指令映射和 CMSIS 適配程度也可能不同。先編譯參考內核,再打開優化,能夠把平臺移植錯誤與優化內核錯誤分開排查。
以 TFLM 為例,真正可復用的部分只有模型解釋器和算子接口。時鐘、日志、計時、內存段、輸入 DMA、Cache 一致性與編譯選項都屬于平臺工程。建議先用一個只有幾層的 INT8 分類模型完成下面這條鏈路:
| PC 端固定樣本 保存量化前后輸入輸出 |
| 模型轉 C 數組 模型權重進入 Flash,只注冊實際使用的算子 |
| 參考內核跑通 確認模型版本、輸入尺度、輸出次序與 Arena |
| 啟用優化內核 重新比較輸出誤差、Flash、RAM 與周期數 |
圖2:通用 Cortex-M 移植時,先建立正確性基線,再做性能優化
模型初始化可以壓縮到下面這組核心對象。算子數量應當根據模型逐項注冊,避免 AllOpsResolver 把無關代碼帶進 Flash。Arena 需要按 16 字節對齊,并放到鏈接器能夠保證連續空間的 SRAM 段。
alignas(16) static uint8_t tensor_arena[96 * 1024];
const tflite::Model* model =
tflite::GetModel(g_model_data);
tflite::MicroMutableOpResolver<4> resolver;
resolver.AddConv2D();
resolver.AddDepthwiseConv2D();
resolver.AddFullyConnected();
resolver.AddSoftmax();
tflite::MicroInterpreter interpreter(
model, resolver,
tensor_arena, sizeof(tensor_arena));
if (interpreter.AllocateTensors() != kTfLiteOk) {
fault_report(TINYML_ARENA_TOO_SMALL);
}
TfLiteTensor* input = interpreter.input(0);
TfLiteTensor* output = interpreter.output(0);
接下來,要核對四個板端事實:
第一,input->type、維度、尺度和零點與 PC 端完全一致。第二,DMA 寫入的原始采樣不能直接當模型輸入,濾波、窗口、歸一化或 MFCC 必須逐項對齊。第三,Map 文件中權重位于 Flash,Arena 位于可讀寫 SRAM,棧與堆沒有壓住 Arena。第四,同一組固定樣本在 PC 和 MCU 上得到相同類別,并將各類別分數誤差控制在項目允許范圍。
常見失誤:AllocateTensors()、內存記錄器和 Map 文件的結果為準。 |
希望最快跑通視覺或音頻原型:優先 ESP32-S3、ESP32-P4 或 HPMicro。前者有 ESP-DL 的模型轉換與運行鏈路,后者在 SDK 中集成了 TFLM。工具鏈準備時間通常比手工移植短。
項目已經確定使用 Arm 國產 MCU:優先從 GD32H7、MM32H、APM32F465、N32G457 等高 RAM 型號建立基線。TFLM 參考內核跑通以后,再接 CMSIS-NN,并用 DWT 或 GPIO 測量真實推理時間。
成本鎖得很緊,RAM 只有幾十 KB:縮小輸入維度比盲目剪枝更有效。傳感器窗口先提取均值、方差、頻帶能量、峰值和相關系數,再使用邏輯回歸、小樹或原型距離。運行時可以只有幾百字節臨時變量。
必須使用 CH32V 或 STC:先接受工具鏈工作量。CH32V 高性能型號可以建立 RISC-V TFLM 端口并優化熱點算子;STC 與小資源 8051 更適合純 C 固定計算圖。項目排期里要單獨列出運行時移植、數值對齊和性能優化。
| 最后的判斷 |
參考資料:GD32H7 官方介紹、MM32H 官方產品頁、N32G457 官方產品頁、HPM SDK 官方說明、ESP-DL 官方文檔、CMSIS-NN 官方文檔、TensorFlow Lite Micro 項目

END
來源:玩轉單片機與嵌入式