2、环境搭建:Python、ONNX Runtime、MicroPython/嵌入式工具链的安装与配置,以及开发板选型

TinyML 开发与传统嵌入式开发最大的差异在于:它处于“机器学习模型训练”与“微控制器资源受限部署”的交汇点。因此,环境搭建并非简单地安装一个 IDE,而是需要构建一条从 PC 端模型转换到设备端推理的完整工具链。本章将围绕 Python 基础环境、ONNX Runtime 推理引擎、MicroPython 与嵌入式交叉编译工具链的配置,以及开发板选型四个核心模块展开,帮助读者建立一套可复现、可调试的实战环境。

PC端模型开发环境 模型转换与优化层 设备端部署环境 Python 3.10+ ONNX Runtime onnx-simplifier Netron可视化 onnx2tf / onnx2c 量化校准工具 C代码生成 权重二进制导出 MicroPython固件 交叉编译链 烧录工具 串口调试器 开发板选型决策矩阵 ESP32-S3 240MHz / 512KB SRAM STM32F746 216MHz / 320KB SRAM RP2040 133MHz / 264KB SRAM nRF52840 64MHz / 256KB SRAM 选择依据:SRAM容量 > 算力 > 外设接口 > 社区生态 > 成本

2.1 Python 基础环境与虚拟环境管理

核心原理:Python 是 TinyML 工具链的粘合剂。模型训练、ONNX 导出、量化校准、固件生成等环节均依赖 Python 生态。但不同工具对 Python 版本要求各异(例如 TensorFlow 2.10 最高支持 Python 3.10,而最新版 onnxruntime 可能要求 3.11+),因此必须使用虚拟环境隔离项目依赖,避免版本冲突。

操作流程:推荐使用 Miniconda 或 Python 自带的 venv 模块。以下为基于 Miniconda 的推荐配置流程:

# 创建 Python 3.10 虚拟环境
conda create -n tinyml python=3.10 -y
conda activate tinyml

# 安装基础依赖
pip install --upgrade pip
pip install numpy==1.24.3 scipy==1.10.1
pip install onnx==1.14.0 onnxruntime==1.16.0
pip install onnx-simplifier==0.4.17 netron==7.3.4

案例拆解:某学员在 Windows 上直接使用系统 Python 安装 onnxruntime,导致与已安装的 TensorFlow 2.15 产生 protobuf 版本冲突(TensorFlow 要求 protobuf<3.21,而 onnxruntime 要求 protobuf>=3.20.3)。通过创建独立虚拟环境后,两个项目互不干扰,问题解决。这验证了虚拟环境在 TinyML 工具链中的必要性。

风险提示:不要使用系统自带的 Python 3.8 或更旧版本,部分 ONNX 算子(如 Resize-11)在旧版本中无法正确解析。建议统一使用 Python 3.10.x 作为基线版本。

2.2 ONNX Runtime 的安装与验证

核心原理:ONNX Runtime 是微软开源的跨平台推理引擎,支持 CPU、GPU、NPU 等多种执行提供程序(Execution Provider)。在 TinyML 场景中,我们主要使用其 CPU 版本进行模型正确性验证,以及通过 onnxruntime-extensions 进行自定义算子注册。

判断方法:安装完成后,通过以下脚本验证环境是否正常:

import onnxruntime as ort
print("ONNX Runtime version:", ort.__version__)
print("Available providers:", ort.get_available_providers())

# 创建一个最简单的 ONNX 模型进行推理测试
import onnx
from onnx import helper, TensorProto

# 定义输入输出
X = helper.make_tensor_value_info('input', TensorProto.FLOAT, [1, 10])
Y = helper.make_tensor_value_info('output', TensorProto.FLOAT, [1, 10])

# 定义节点(Relu)
node = helper.make_node('Relu', ['input'], ['output'])

# 创建图
graph = helper.make_graph([node], 'test_graph', [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
onnx.save(model, 'test_relu.onnx')

# 推理
sess = ort.InferenceSession('test_relu.onnx')
import numpy as np
result = sess.run(None, {'input': np.random.randn(1, 10).astype(np.float32)})
print("Inference OK, output shape:", result[0].shape)

常见误区:许多初学者直接使用 pip install onnxruntime 安装 GPU 版本,但在无 NVIDIA GPU 的机器上会导致推理失败。应明确安装 onnxruntime(CPU 版)或 onnxruntime-gpu(GPU 版),两者不可共存。

2.3 MicroPython 与嵌入式工具链配置

核心原理:MicroPython 是 Python 3 的精简实现,专为微控制器设计。它允许在资源受限设备上直接运行 Python 代码,但推理性能远低于 C 语言。因此,TinyML 部署通常采用“混合模式”:模型权重以 C 数组形式嵌入固件,而控制逻辑(如音频采集、预处理、结果输出)使用 MicroPython 编写。

操作流程:以 ESP32-S3 为例,配置 MicroPython 环境需要以下步骤:

  1. 下载官方 MicroPython 固件(.bin 文件)
  2. 使用 esptool 擦除 Flash 并烧录固件
  3. 安装 ampy 或 rshell 工具用于文件传输
  4. 使用 Thonny IDE 进行交互式开发
# 安装 esptool 和 ampy
pip install esptool adafruit-ampy

# 擦除 Flash
esptool.py --port COM3 erase_flash

# 烧录 MicroPython 固件
esptool.py --port COM3 --baud 460800 write_flash -z 0x1000 ESP32_GENERIC_S3-20231005-v1.21.0.bin

# 上传 Python 文件到开发板
ampy --port COM3 put main.py

案例拆解:某项目需要部署一个 20KB 的唤醒词检测模型到 ESP32-S3。由于 MicroPython 的浮点运算速度较慢(约 10 倍于 C 语言),直接使用 MicroPython 加载 ONNX 模型推理耗时 800ms,远超实时要求。解决方案是:使用 onnx2c 将模型转换为 C 数组,编译进固件,而 MicroPython 仅负责 I2S 音频采集和结果回调。最终推理耗时降至 45ms,满足实时性要求。

经验提醒:对于 Cortex-M 系列(如 STM32),推荐使用 ARM 官方工具链 arm-none-eabi-gcc,配合 STM32CubeProgrammer 烧录。对于 RISC-V 架构(如 K210),则需要使用平头哥的 riscv-none-embed-gcc 工具链。务必确认开发板架构后再选择工具链。

2.4 开发板选型决策

核心原理:开发板选型是 TinyML 项目成败的关键。核心约束包括:SRAM 容量(模型权重和中间特征图必须驻留 SRAM)、Flash 容量(固件+模型存储)、算力(MACs/s)、外设接口(I2S 麦克风、DMA 通道)以及功耗预算。

对比分析:以下为常见 TinyML 开发板的对比表:

开发板MCUSRAMFlash算力I2SMicroPython典型场景
ESP32-S3-DevKitCXtensa LX7 240MHz512KB8MB~600 MACs/cycle支持官方支持唤醒词、关键词识别
STM32F746G-DISCOCortex-M7 216MHz320KB1MB~400 MACs/cycle支持社区移植工业级语音、振动分析
Raspberry Pi PicoRP2040 133MHz264KB2MB~200 MACs/cycle需外扩官方支持教育、原型验证
nRF52840-DKCortex-M4F 64MHz256KB1MB~100 MACs/cycle支持官方支持BLE 低功耗唤醒

判断方法:选型时遵循“SRAM 优先”原则。首先估算模型所需 SRAM:权重大小 + 最大中间特征图大小 × 2(输入输出缓冲)。例如,一个 20KB 的 int8 量化模型,中间特征图最大 10KB,则至少需要 40KB SRAM。其次考虑算力:若需实时处理 16kHz 音频,每帧 20ms,则需在 20ms 内完成推理,即算力需大于 模型MACs / 0.02s。

案例拆解:某智能门锁项目需部署 3 个唤醒词(“你好小智”、“打开门锁”、“关闭门锁”),模型为 DS-CNN 架构,int8 量化后 35KB。选择 ESP32-S3 后,实际测试 SRAM 占用 68KB(含音频缓冲),推理耗时 32ms,满足 50ms 实时要求。若选择 nRF52840,则 SRAM 可能不足(35KB 权重 + 15KB 特征图 + 音频缓冲 16KB = 66KB,接近极限),且推理耗时可能超过 100ms。

总结复盘:环境搭建的核心是“分层隔离”:Python 虚拟环境隔离 PC 端工具链,MicroPython 与 C 固件隔离设备端逻辑。开发板选型则需从 SRAM、算力、外设三个维度建立量化评估表,避免凭经验或价格选型。建议初学者从 ESP32-S3 起步,因其社区资源丰富、MicroPython 支持完善、且具备向量指令加速(PIE),是 TinyML 入门的最佳平衡点。