在嵌入式设备上部署机器学习模型正变得越来越普遍。根据Arm的调研数据,到2025年将有超过75%的边缘设备需要运行某种形式的ML推理。Cortex-M系列处理器凭借其低功耗特性,已成为物联网和嵌入式ML应用的主力平台。而Ethos-U NPU的加入,则让这些资源受限的设备能够运行更复杂的神经网络模型。
我最近在一个工业预测性维护项目中使用了Cortex-M55和Ethos-U55的组合。这个项目需要在设备端实时分析振动传感器数据,预测电机故障。相比传统的Cortex-M4方案,使用Ethos-U55后推理速度提升了8倍,而功耗仅增加了15%。这种性能提升使得我们能够在设备端运行更复杂的异常检测模型,而不再需要将所有数据上传到云端处理。
SDS(同步数据流)框架是Arm专门为嵌入式ML开发设计的数据采集和处理系统。它的核心价值在于解决了真实世界数据采集的三大难题:
框架包含四个关键组件:
在实际项目中配置SDS Recorder时,传输通道的选择至关重要。根据我的经验,不同接口的实测性能如下:
| 开发板型号 | 接口类型 | 实测速度 | 适用场景 |
|---|---|---|---|
| NXP IMXRT1050-EVKB | TCP/IP以太网 | 2 MB/s | 实验室环境调试 |
| NXP IMXRT1050-EVKB | 高速VCOM | 11.8 MB/s | 高速数据采集 |
| ST B-U585I-IOT02A | UART | 80 kB/s | 低功耗现场部署 |
提示:在工业现场部署时,建议优先考虑VCOM接口。我们在一个电机监测项目中,使用VCOM接口成功实现了10个振动传感器+1个温度传感器的同步数据采集。
配置示例代码:
c复制// 初始化SDS Recorder
sds_recorder_init(&config);
// 添加传感器源
sds_add_source(SDS_SOURCE_GYROSCOPE, &gyro_config);
sds_add_source(SDS_SOURCE_MICROPHONE, &mic_config);
// 设置存储路径
sds_set_storage_path("/sd_card/sensor_data");
// 启动记录
sds_start_recording();
多传感器数据采集最大的挑战是时钟同步。在同一个项目中,我们遇到过音频数据(8kHz)和MEMS传感器数据(3.5kHz)采样率不同步的问题。这会导致后续的特征提取和模型推理出现偏差。
SDS框架通过两种机制解决这个问题:
我们最终采用的解决方案是:
Arm ML Zoo包含了针对Cortex-M和Ethos-U优化的各类模型。根据项目经验,我总结了常用模型的适用场景:
| 模型类型 | 推荐模型 | 量化方式 | 适用硬件 | 典型精度 |
|---|---|---|---|---|
| 异常检测 | MicroNet-Small | INT8 | Cortex-M55+U55 | 92% |
| 关键词识别 | DS-CNN-Large | INT8 | Ethos-U65 | 94% |
| 图像分类 | MobileNetV2 | UINT8 | Cortex-M7 | 89% |
| 物体检测 | YOLOv3-Tiny | FP32 | Cortex-M55 | 75% |
注意:模型精度数据基于Arm提供的测试数据集,实际项目中可能会有所不同。建议在目标数据集上重新验证。
从ML Zoo获取模型后的标准部署流程:
bash复制vela your_model.tflite --accelerator-config ethos-u55-256
c复制// 在工程中声明模型数据
extern const uint8_t g_your_model_data[];
extern const size_t g_your_model_size;
// 初始化解释器
tflite::MicroInterpreter interpreter(
tflite::GetModel(g_your_model_data),
resolver,
tensor_arena,
kTensorArenaSize,
error_reporter);
ML Zoo中的模型通常需要针对具体场景进行微调。以关键词识别为例,我们的优化过程如下:
python复制# 使用TensorFlow Lite Model Maker进行微调
model = tflite_model_maker.audio_classifier.create(
train_data=train_data,
model_spec=model_spec,
validation_data=validation_data,
epochs=20,
batch_size=32)
python复制# 动态范围量化
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
quantized_model = converter.convert()
基于Keil MDK的推荐配置:
完整的CI流程包括三个关键阶段:
yaml复制- name: Run static checks
run: |
python3 ./scripts/check_code_style.py
python3 ./scripts/run_clang_tidy.py
yaml复制- name: Build all targets
run: |
python3 ./build_all.py --toolchain arm --npu-config-name ethos-u55-256
yaml复制- name: Run on AVH
uses: arm-software/[email protected]
with:
fvp: Corstone-300
image: ${{ steps.build.outputs.artifact }}
经验分享:在配置CI时,我们发现缓存第三方库可以显著缩短构建时间。推荐使用actions/cache缓存以下路径:
在资源受限的Cortex-M设备上,内存管理至关重要。我们采用的优化方案:
c复制// 链接脚本中的关键配置
MEMORY {
ITCM (rx) : ORIGIN = 0x00000000, LENGTH = 256K
DTCM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K
SRAM (rwx) : ORIGIN = 0x30000000, LENGTH = 2M
}
// 将模型权重放在ITCM
.weights : {
*(.model_weights)
} > ITCM
Ethos-U NPU的性能受多种因素影响。我们的调优过程发现:
配置参数影响:
| 参数 | 选项 | 性能影响 |
|------|------|----------|
| MAC数量 | 32/64/128/256 | 线性提升 |
| 内存模式 | 共享/专用 | 专用提升15% |
| 数据布局 | NHWC/NCHW | 影响5-10% |
最佳实践:
在电池供电的设备中,我们通过以下方式优化功耗:
c复制// 根据工作负载调整CPU频率
if (inference_running) {
HAL_PWR_SetCPUFreq(PWR_CPU_FREQ_200MHZ);
} else {
HAL_PWR_SetCPUFreq(PWR_CPU_FREQ_50MHZ);
}
c复制#include "EventRecorder.h"
void StartInference() {
EventStartA(1); // 推理开始标记
// ...推理代码...
EventStopA(1); // 推理结束标记
}
在实际项目中,我们发现80%的问题都与内存配置有关。建议在项目初期就建立完善的内存使用监控机制。