▼點(diǎn)擊下方名片,關(guān)注公眾號(hào),獲取更多精彩內(nèi)容▼
這里是《賀老師講嵌入式AI》,我是《嵌入式AI:讓單片機(jī)學(xué)會(huì)思考》課程主理人,專注AI在MCU上的落地實(shí)踐。
關(guān)注公眾號(hào)后,回復(fù)【嵌入式AI】,可以免費(fèi)獲取更多賀老師準(zhǔn)備的專業(yè)資料。
國(guó)產(chǎn) MCU 的型號(hào)表越來越長(zhǎng)。兆易創(chuàng)新 GD32、華大 HC32、靈動(dòng) MM32、沁恒 CH32V、極海 APM32、國(guó)民 N32、先楫 HPM、樂鑫 ESP32,再加上航順、芯海、中微、東軟載波、中穎和 STC,選型表拉開以后很有氣勢(shì)。
真正把 TinyML 模型放進(jìn)去時(shí),問題馬上具體起來:模型文件由誰解析?INT8 卷積由誰加速?激活緩沖放在哪里?芯片廠商有沒有現(xiàn)成例程?芯片采用 Cortex-M4 或 RISC-V,只能回答其中一部分。
![]() |
圖 1:國(guó)產(chǎn) MCU 部署 TinyML 的四條常見路線
樂鑫給出的 ESP-DL 鏈路相對(duì)完整。訓(xùn)練端先得到 PyTorch 或 ONNX 模型,ESP-PPQ 負(fù)責(zé)量化并導(dǎo)出 .espdl,板端由 ESP-DL 加載模型、規(guī)劃內(nèi)存并執(zhí)行算子。當(dāng)前官方快速入門重點(diǎn)覆蓋 ESP32-S3 和 ESP32-P4。
這里有一個(gè)容易漏掉的細(xì)節(jié):ESP-DL 的模型與目標(biāo)平臺(tái)相關(guān)。ESP32-S3 與 ESP32-P4 的量化粒度、舍入方式和算子實(shí)現(xiàn)存在差異,已經(jīng)導(dǎo)出的 .espdl 不能隨意跨平臺(tái)復(fù)用。遷移芯片時(shí)要重新指定目標(biāo)、重新量化,再用固定樣本對(duì)齊 PC 與板端輸出。
HPM SDK 已經(jīng)集成 TensorFlow Lite for Microcontrollers,并提供 samples/tflm 例程。開發(fā)者可以從廠商已經(jīng)跑通的時(shí)鐘、串口、鏈接腳本和構(gòu)建工程出發(fā),把工作集中到算子注冊(cè)、Tensor Arena、輸入預(yù)處理與輸出校驗(yàn)。
這條路線仍然需要測(cè)量?jī)?nèi)存與延遲。SDK 集成解決的是“工程怎樣編譯和啟動(dòng)”,模型中的算子組合、激活峰值和板端輸入格式仍由項(xiàng)目決定。換一個(gè)網(wǎng)絡(luò)結(jié)構(gòu),原例程的 Arena 大小和算子列表往往要跟著改。
GD32、HC32、MM32、APM32、N32,以及航順、芯海、中微和東軟載波的 Cortex-M 產(chǎn)品,通常可以采用 TFLM 加 CMSIS-NN。TFLM 負(fù)責(zé)讀取模型、建立張量和調(diào)度算子;CMSIS-NN 提供面向 Cortex-M 的卷積、全連接、池化、Softmax 等優(yōu)化內(nèi)核。
CMSIS-NN 不能單獨(dú)加載 .tflite 模型。TFLM 在算子執(zhí)行階段調(diào)用優(yōu)化內(nèi)核,二者處于不同層級(jí)。對(duì)于 Star-MC1 等兼容 Cortex-M33 的內(nèi)核,建議先用 TFLM 參考內(nèi)核對(duì)齊輸出,再啟用 CMSIS-NN,隨后比較數(shù)值誤差、代碼尺寸和周期數(shù)。
沁恒 CH32V 采用青稞 RISC-V 內(nèi)核,CMSIS-NN 無法提供算子加速。高性能 CH32V317、CH32V407 可以移植 TFLM 參考內(nèi)核,再針對(duì)乘加、卷積和激活熱點(diǎn)引入 RISC-V 或 RVV 優(yōu)化;平臺(tái)層、編譯參數(shù)、內(nèi)存對(duì)齊和優(yōu)化庫都要重新核對(duì)。
經(jīng)典 8051、低端 Cortex-M0/M3 和只有十幾 KB RAM 的型號(hào),更適合把模型轉(zhuǎn)換成固定計(jì)算流程:線性分類器、邏輯回歸、小型決策樹、原型距離或手寫定點(diǎn)全連接網(wǎng)絡(luò)。權(quán)重直接保存為 C 數(shù)組,推理函數(shù)只保留乘加、比較和查表,能夠避開完整 C++ 運(yùn)行時(shí)與大塊 Tensor Arena。
下面的“優(yōu)先系列”用于建立第一版原型,不代表整條產(chǎn)品線都有相同資源。最終選型必須回到具體料號(hào)的數(shù)據(jù)手冊(cè),確認(rèn) SRAM 分塊、連續(xù)地址空間、Flash 容量、Cache、FPU/DSP、外部存儲(chǔ)器接口和采樣外設(shè)。
這張表里最需要警惕的是“同內(nèi)核等于同體驗(yàn)”。同為 Cortex-M4,192KB SRAM 與 68KB SRAM 能容納的激活張量差異很大;同為 M33 兼容內(nèi)核,編譯器宏、DSP 指令映射和 CMSIS 適配程度也可能不同。先編譯參考內(nèi)核,再打開優(yōu)化,能夠把平臺(tái)移植錯(cuò)誤與優(yōu)化內(nèi)核錯(cuò)誤分開排查。
以 TFLM 為例,真正可復(fù)用的部分只有模型解釋器和算子接口。時(shí)鐘、日志、計(jì)時(shí)、內(nèi)存段、輸入 DMA、Cache 一致性與編譯選項(xiàng)都屬于平臺(tái)工程。建議先用一個(gè)只有幾層的 INT8 分類模型完成下面這條鏈路:
| PC 端固定樣本 保存量化前后輸入輸出 |
| 模型轉(zhuǎn) C 數(shù)組 模型權(quán)重進(jìn)入 Flash,只注冊(cè)實(shí)際使用的算子 |
| 參考內(nèi)核跑通 確認(rèn)模型版本、輸入尺度、輸出次序與 Arena |
| 啟用優(yōu)化內(nèi)核 重新比較輸出誤差、Flash、RAM 與周期數(shù) |
圖 2:通用 Cortex-M 移植時(shí),先建立正確性基線,再做性能優(yōu)化
模型初始化可以壓縮到下面這組核心對(duì)象。算子數(shù)量應(yīng)當(dāng)根據(jù)模型逐項(xiàng)注冊(cè),避免 AllOpsResolver 把無關(guān)代碼帶進(jìn) Flash。Arena 需要按 16 字節(jié)對(duì)齊,并放到鏈接器能夠保證連續(xù)空間的 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);
接下來要核對(duì)四個(gè)板端事實(shí)。第一,input->type、維度、尺度和零點(diǎn)與 PC 端完全一致。第二,DMA 寫入的原始采樣不能直接當(dāng)模型輸入,濾波、窗口、歸一化或 MFCC 必須逐項(xiàng)對(duì)齊。第三,Map 文件中權(quán)重位于 Flash,Arena 位于可讀寫 SRAM,棧與堆沒有壓住 Arena。第四,同一組固定樣本在 PC 和 MCU 上得到相同類別,并將各類別分?jǐn)?shù)誤差控制在項(xiàng)目允許范圍。
常見失誤:AllocateTensors()、內(nèi)存記錄器和 Map 文件的結(jié)果為準(zhǔn)。 |
希望最快跑通視覺或音頻原型:優(yōu)先 ESP32-S3、ESP32-P4 或 HPMicro。前者有 ESP-DL 的模型轉(zhuǎn)換與運(yùn)行鏈路,后者在 SDK 中集成了 TFLM。工具鏈準(zhǔn)備時(shí)間通常比手工移植短。
項(xiàng)目已經(jīng)確定使用 Arm 國(guó)產(chǎn) MCU:優(yōu)先從 GD32H7、MM32H、APM32F465、N32G457 等高 RAM 型號(hào)建立基線。TFLM 參考內(nèi)核跑通以后,再接 CMSIS-NN,并用 DWT 或 GPIO 測(cè)量真實(shí)推理時(shí)間。
成本鎖得很緊,RAM 只有幾十 KB:縮小輸入維度比盲目剪枝更有效。傳感器窗口先提取均值、方差、頻帶能量、峰值和相關(guān)系數(shù),再使用邏輯回歸、小樹或原型距離。運(yùn)行時(shí)可以只有幾百字節(jié)臨時(shí)變量。
必須使用 CH32V 或 STC:先接受工具鏈工作量。CH32V 高性能型號(hào)可以建立 RISC-V TFLM 端口并優(yōu)化熱點(diǎn)算子;STC 與小資源 8051 更適合純 C 固定計(jì)算圖。項(xiàng)目排期里要單獨(dú)列出運(yùn)行時(shí)移植、數(shù)值對(duì)齊和性能優(yōu)化。
| 最后的判斷 |
參考資料:GD32H7 官方介紹、MM32H 官方產(chǎn)品頁、N32G457 官方產(chǎn)品頁、HPM SDK 官方說明、ESP-DL 官方文檔、CMSIS-NN 官方文檔、TensorFlow Lite Micro 項(xiàng)目

END