1. 认识MilkV Duo开发板与TPU加速

第一次拿到MilkV Duo这块开发板时,说实话有点意外——35块钱的板子居然内置了TPU加速单元。这价格比树莓派Pico还便宜,但性能却强不少。开发板采用双核RISC-V架构(C906@1Ghz + C906@700MHz),搭配64MB DDR2内存,最亮眼的是集成了CV1800B芯片的TPU模块,实测跑ResNet18这类经典模型能到30FPS以上。

硬件配置亮点

  • 摄像头支持:MIPI CSI 2-lane接口,接上200万像素摄像头就能做实时图像处理
  • 视频编码:H.264/H.265硬件编码,适合边缘视频分析场景
  • 扩展接口:26个GPIO引脚,可连接各类传感器
  • 供电方式:Type-C一线通,开发调试非常方便

这块板子的TPU算力是0.5TOPS(INT8),虽然比不上高端AI加速卡,但跑MobileNet、ResNet这类轻量级模型完全够用。我实测过用自带的TPU跑图像分类,功耗只有1.2W左右,非常适合嵌入式场景。

2. 搭建Docker开发环境

由于模型转换工具链依赖特定系统库,官方推荐用Docker隔离环境。这里有个坑要注意:Ubuntu 22.04之后apt安装的docker有问题,得用snap安装:

sudo snap install docker

接着拉取社区维护的TPU工具链镜像(约4GB,下载需要耐心):

git clone https://github.com/aceraoc/MilkV-Duo_TPU.git
cd MilkV-Duo_TPU
./getdocker.sh  # 自动解压并导入三个必备工具包

工具链包含三个核心组件:

  1. CVITEK TPU SDK:模型部署运行时环境
  2. MLIR编译器:将ONNX模型转为TPU可执行格式
  3. 示例模型库:包含预编译的CVIModel

启动容器时建议挂载工作目录,方便调试:

sudo docker run -itd -v $PWD:/work --name cvitek cvitek/cvitek_dev:1.9-ubuntu-18.04
sudo docker exec -it cvitek bash

3. PyTorch模型转换实战

3.1 导出ONNX模型

以ResNet18为例,先准备PyTorch模型。这里有个细节:TorchVision的预训练模型输入是RGB格式,均值标准差是ImageNet参数:

# getonnx.py
import torch
model = models.resnet18(pretrained=True)
dummy_input = torch.randn(1, 3, 224, 224)  # NCHW格式
torch.onnx.export(
    model, 
    dummy_input,
    'resnet18.onnx',
    opset_version=13,  # 必须≥11
    input_names=['input'],
    dynamic_axes={'input': {0: 'batch'}}  # 支持动态batch
)

3.2 ONNX转MLIR

CVITEK的model_transform.py脚本负责格式转换,关键参数要配准:

model_transform.py \
  --model_type onnx \
  --model_name resnet18 \
  --model_def ../resnet18.onnx \
  --image_resize_dims 256,256 \  # 先缩放到256x256
  --net_input_dims 224,224 \     # 再中心裁剪到224x224
  --mean 0.485,0.456,0.406 \     # ImageNet均值
  --std 0.229,0.224,0.225 \      # ImageNet标准差
  --model_channel_order "rgb" \   # 与PyTorch一致
  --mlir resnet18_fp32.mlir

这个步骤会生成:

  • resnet18_fp32.mlir:中间表示文件
  • resnet18_*_npz:测试用的输入输出数据
  • resnet18_top_outputs.npz:用于精度验证

3.3 量化部署

TPU支持BF16和INT8量化,实测INT8精度损失约2%但速度提升3倍:

BF16量化(保留浮点特性)

model_deploy.py \
  --mlir resnet18_fp32.mlir \
  --quantize BF16 \
  --chip cv180x \
  --cvimodel resnet18_bf16.cvimodel

INT8量化(需校准集): 先准备100-1000张校准图片,官方示例里自带100张:

run_calibration.py \
  resnet18_fp32.mlir \
  --dataset=./images \
  --input_num=100 \
  -o resnet18_calibration_table

接着生成INT8模型:

model_deploy.py \
  --mlir resnet18_fp32.mlir \
  --calibration_table resnet18_calibration_table \
  --quantize INT8 \
  --chip cv180x \
  --cvimodel resnet18_int8.cvimodel

4. 模型部署与性能测试

4.1 开发板环境配置

通过SSH连接Duo开发板(默认IP 192.168.42.1):

ssh root@192.168.42.1
mkdir -p /home/milkv/models

从Docker容器上传模型和SDK:

scp resnet18_*.cvimodel root@192.168.42.1:/home/milkv/models
scp -r cvitek_tpu_sdk root@192.168.42.1:/home/milkv

4.2 运行推理示例

在开发板上加载环境变量:

export TPU_ROOT=/home/milkv/cvitek_tpu_sdk
source $TPU_ROOT/envs_tpu_sdk.sh

执行图像分类测试:

cd $TPU_ROOT/samples
./bin/cvi_sample_classifier \
  /home/milkv/models/resnet18_int8.cvimodel \
  ./data/cat.jpg \
  ./data/synset_words.txt

性能对比数据

模型类型 推理时延(ms) 内存占用(MB) 准确率(TOP1)
FP32 152 48.7 69.8%
BF16 89 32.1 69.5%
INT8 53 25.4 68.1%

5. 踩坑与优化经验

问题1:模型输出异常

  • 现象:分类结果全部为同一类别
  • 排查:检查发现model_transform.py--model_channel_order设成了bgr
  • 解决:保持PyTorch的RGB顺序一致

问题2:INT8量化精度暴跌

  • 原因:校准集图片与真实场景分布差异大
  • 优化:改用业务场景真实图片做校准集,精度恢复至67.9%

问题3:TPU内存不足

  • 场景:输入分辨率提升到320x320时报错
  • 方案:修改model_deploy.py--aligned_input=false减少内存对齐开销

对于想尝试YOLO等检测模型的开发者,虽然官方没提供直接支持,但可以通过以下步骤适配:

  1. 将YOLO输出层改为单尺度输出
  2. 使用--excepts参数跳过非标准算子
  3. 后处理部分用CPU实现
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐