一.前置准备
由于我主机用的是win系统,而模型转化容器需在Linux架构下部署,因此需要安装虚拟机,本人所使用的虚拟机环境为:(具体虚拟机安装可见b站教程)
此处对环境的配置见官方要求:
yolov8模型训练得到的.pt文件转成.onnx模型文件步骤不再赘述,此处提供源码:
注:model后为.pt文件的路径 由于我想要在CAM上运行时获得较高的帧率,因此图片尺寸设置为224*224
之后在输入命令中可能会遇到权限不够的问题,可通过输入命令:
su root
来转换至超级用户
二.在Ubantu中安装ducker
此处详见官方代码,由于我是第一次安装,因此只需依次在命令行中输入以下代码即可
# 安装docker依赖的基础软件
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
# 添加官方来源
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 安装 docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
安装好后需拉去docker镜像
可选择在命令行中输入:
docker pull sophgo/tpuc_dev:latest
但该方法速度较慢,因此更推荐以下方法下载:
wget https://sophon-file.sophon.cn/sophon-prod-s3/drive/24/06/14/12/sophgo-tpuc_dev-v3.2_191a433358ad.tar.gz
docker load -i sophgo-tpuc_dev-v3.2_191a433358ad.tar.gz
三.运行docker
在命令行中输入:sudo docker run --privileged --name tpu-env -v /home/$USER/data:/home/$USER/data -it sophgo/tpuc_dev:v3.2
根据官方描述,在输入该命令后会创建一个名为tpu-env的容器,并将虚拟机的~/data目录挂载到容器的~/data从而实现文件共享,并且容器该文件夹路径与虚拟机中该文件夹路径相同(这点很重要,之后安装tpu命令及后续命令会用到)
下次启动容器用docker start tpu-env && docker attach tpu-env
即可。
四.安装tpu-mlir
注:由于上述步骤会使得已经在容器中,因此可以先退出命令行后重新进入
首先到github上下载.whl文件,并放在~/data目录下
下载网址为:
https://github.com/sophgo/tpu-mlir/releases/tag/v1.7
并在该网址下下载: tpu-mlir-resource.tar 和 tpu_mlir-1.7-py3-none-any.whl
下载过程可能比较漫长,本人通过aria2实现加速下载:
首先下载aria2:sudo apt-get install aria2
之后输入: aria2c -c (后面为文件链接) https://github.com/sophgo/tpu-mlir/releases/download/v1.7/tpu_mlir-1.7-py3-none-any.whl
在将下载好后的文件放置到~/data中,具体命令可用:
mv file dir #将文件file移动到dir目录中
之后重新进入容器
docker start tpu-env && docker attach tpu-env
再进入容器中data目录所在文件夹
由于与虚拟机中data目录所在路径相同,因此只需输入:(以下为本人路径,需根据具体情况作出调整)
cd /home/zbt/data
然后安装tpu-mlir,输入:
pip install tpu_mlir*.whl # 这里就是下载文件的名字
五.编写模型转换脚本
以下为官方源码:(官方文档:将 ONNX 模型转换为 MaixCAM MaixPy 可以使用的模型(MUD) - MaixPy (sipeed.com))
#!/bin/bash
set -e
net_name=yolov5s
input_w=640
input_h=640
# mean: 0, 0, 0
# std: 255, 255, 255
# mean
# 1/std
# mean: 0, 0, 0
# scale: 0.00392156862745098, 0.00392156862745098, 0.00392156862745098
mkdir -p workspace
cd workspace
# convert to mlir
model_transform.py \
--model_name ${net_name} \
--model_def ../${net_name}.onnx \
--input_shapes [[1,3,${input_h},${input_w}]] \
--mean "0,0,0" \
--scale "0.00392156862745098,0.00392156862745098,0.00392156862745098" \
--keep_aspect_ratio \
--pixel_format rgb \
--channel_format nchw \
--output_names "/model.24/m.0/Conv_output_0,/model.24/m.1/Conv_output_0,/model.24/m.2/Conv_output_0" \
--test_input ../dog.jpg \
--test_result ${net_name}_top_outputs.npz \
--tolerance 0.99,0.99 \
--mlir ${net_name}.mlir
# export bf16 model
# not use --quant_input, use float32 for easy coding
model_deploy.py \
--mlir ${net_name}.mlir \
--quantize BF16 \
--processor cv181x \
--test_input ${net_name}_in_f32.npz \
--test_reference ${net_name}_top_outputs.npz \
--model ${net_name}_bf16.cvimodel
echo "calibrate for int8 model"
# export int8 model
run_calibration.py ${net_name}.mlir \
--dataset ../images \
--input_num 200 \
-o ${net_name}_cali_table
echo "convert to int8 model"
# export int8 model
# add --quant_input, use int8 for faster processing in maix.nn.NN.forward_image
model_deploy.py \
--mlir ${net_name}.mlir \
--quantize INT8 \
--quant_input \
--calibration_table ${net_name}_cali_table \
--processor cv181x \
--test_input ${net_name}_in_f32.npz \
--test_reference ${net_name}_top_outputs.npz \
--tolerance 0.9,0.6 \
--model ${net_name}_int8.cvimodel
由于我的为yolov8模型,因此需要对脚本做出些许修改
1.net_name需改为自己的.onnx前的文件名(如我的文件名为yolov8.onnx,因此net_name改为yolov8)
2.input_w和input_h,由于我之前转换模型时转出选择为224*224,因此此处也需改成224
3.output_names 网络节点,详见官方文章:为 MaixCAM MaixPy 离线训练 YOLOv8 模型,自定义检测物体、关键点检测 - MaixPy (sipeed.com)其中有提到yolov8模型的节点为:/model.22/dfl/conv/Conv_output_0,/model.22/Sigmoid_output_0
4.test_input 是转换时用来测试的图像,此处需更改为自己测试图像的路径(一张即可)
5.dataset表示用来量化的数据集,也是放在转换脚本同目录下,比如这里是images
文件夹,里面放数据即可,对于 YOLOv8 来说就是图片
6.--input_num可以指定实际使用图片的数量(需小于等于 images 目录下实际的图片)
其他参数可具体见官方文档(将 ONNX 模型转换为 MaixCAM MaixPy 可以使用的模型(MUD) - MaixPy (sipeed.com))
以下附上我的脚本以供参考
#!/bin/bash
set -e
net_name=yolov8
input_w=224
input_h=224
# mean: 0, 0, 0
# std: 255, 255, 255
# mean
# 1/std
# mean: 0, 0, 0
# scale: 0.00392156862745098, 0.00392156862745098, 0.00392156862745098
mkdir -p workspace
cd workspace
# convert to mlir
model_transform.py \
--model_name ${net_name} \
--model_def ../${net_name}.onnx \
--input_shapes [[1,3,${input_h},${input_w}]] \
--mean "0,0,0" \
--scale "0.00392156862745098,0.00392156862745098,0.00392156862745098" \
--keep_aspect_ratio \
--pixel_format rgb \
--channel_format nchw \
--output_names "/model.22/dfl/conv/Conv_output_0,/model.22/Sigmoid_output_0" \
--test_input ../test.jpg \
--test_result ${net_name}_top_outputs.npz \
--tolerance 0.99,0.99 \
--mlir ${net_name}.mlir
# export bf16 model
# not use --quant_input, use float32 for easy coding
model_deploy.py \
--mlir ${net_name}.mlir \
--quantize BF16 \
--processor cv181x \
--test_input ${net_name}_in_f32.npz \
--test_reference ${net_name}_top_outputs.npz \
--model ${net_name}_bf16.cvimodel
echo "calibrate for int8 model"
# export int8 model
run_calibration.py ${net_name}.mlir \
--dataset ../images \
--input_num 50 \
-o ${net_name}_cali_table
echo "convert to int8 model"
# export int8 model
# add --quant_input, use int8 for faster processing in maix.nn.NN.forward_image
model_deploy.py \
--mlir ${net_name}.mlir \
--quantize INT8 \
--quant_input \
--calibration_table ${net_name}_cali_table \
--processor cv181x \
--test_input ${net_name}_in_f32.npz \
--test_reference ${net_name}_top_outputs.npz \
--tolerance 0.9,0.6 \
--model ${net_name}_int8.cvimodel
六:执行转换脚本
chmod +x convert_yolov8_to_cvimodel.sh && ./convert_yolov8_to_cvimodel.sh
注:官方的这句代码少了个. 同时这里要改成自己的文件名
七:编写mud文件
以下为官方源码:
[basic]
type = cvimodel
model = yolov5s.cvimodel
[extra]
model_type = yolov5
input_type = rgb
mean = 0, 0, 0
scale = 0.00392156862745098, 0.00392156862745098, 0.00392156862745098
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
labels = person, bicycle, car, motorcycle, airplane, bus, train, truck, boat, traffic light, fire hydrant, stop sign, parking meter, bench, bird, cat, dog, horse, sheep, cow, elephant, bear, zebra, giraffe, backpack, umbrella, handbag, tie, suitcase, frisbee, skis, snowboard, sports ball, kite, baseball bat, baseball glove, skateboard, surfboard, tennis racket, bottle, wine glass, cup, fork, knife, spoon, bowl, banana, apple, sandwich, orange, broccoli, carrot, hot dog, pizza, donut, cake, chair, couch, potted plant, bed, dining table, toilet, tv, laptop, mouse, remote, keyboard, cell phone, microwave, oven, toaster, sink, refrigerator, book, clock, vase, scissors, teddy bear, hair drier, toothbrush
其中,model后需改为自己转换后的.cvimodel文件的文件名
model_type改为yolov8
labels改为自己的标签
附上我的代码以供参考:
[basic]
type = cvimodel
model = yolov8_int8.cvimodel
[extra]
model_type = yolov8
input_type = rgb
mean = 0, 0, 0
scale = 0.00392156862745098, 0.00392156862745098, 0.00392156862745098
labels = red
八:部署模型
部署.mud和.cvimodel文件在cam上即可
参考文章:
将 ONNX 模型转换为 MaixCAM MaixPy 可以使用的模型(MUD) - MaixPy (sipeed.com)
为 MaixCAM MaixPy 离线训练 YOLOv8 模型,自定义检测物体、关键点检测 - MaixPy (sipeed.com)