4. 通用yolov6模型部署¶
4.1. 引言¶
本文档介绍了如何将yolov6架构的模型部署在cv181x开发板的操作流程,主要的操作步骤包括:
yolov6模型pytorch版本转换为onnx模型
onnx模型转换为cvimodel格式
最后编写调用接口获取推理结果
4.2. pt模型转换为onnx¶
下载yolov6官方仓库 [meituan/YOLOv6](https://github.com/meituan/YOLOv6),下载yolov6权重文件,在yolov6文件夹下新建一个目录weights,并将下载的权重文件放在目录yolov6-main/weights/下
然后将yolo_export/yolov6_eport.py复制到yolov6-main/deploy/onnx目录下
yolo_export中的脚本可以通过SFTP获取:下载站台:sftp://218.17.249.213 帐号:cvitek_mlir_2023 密码:7&2Wd%cu5k
通过SFTP找到下图对应的文件夹:

通过以下命令导出onnx模型
python ./deploy/ONNX/yolov6_export.py \
--weights ./weights/yolov6n.pt \
--img-size 640 640
weights 为pytorch模型文件的路径
img-size 为模型输入尺寸
然后得到onnx模型
小技巧
如果输入为1080p的视频流,建议将模型输入尺寸改为384x640,可以减少冗余计算,提高推理速度,如下所示
python yolov6_export.py --weights path/to/pt/weights --img-size 384 640
4.3. onnx模型转换cvimodel¶
cvimodel转换操作可以参考yolo-v5移植章节的onnx模型转换cvimodel部分。
4.4. yolov6接口说明¶
提供预处理参数以及算法参数设置,其中参数设置:
YoloPreParam 输入预处理设置
$y=(x-mean)times factor$
factor 预处理方差的倒数
mean 预处理均值
use_quantize_scale 预处理图片尺寸
format 图片格式
YoloAlgParam
cls 设置yolov6模型的分类
> yolov6是anchor-free的目标检测网络,不需要传入anchor
另外是yolov6的两个参数设置:
CVI_TDL_SetModelThreshold 设置置信度阈值,默认为0.5
CVI_TDL_SetModelNmsThreshold 设置nms阈值,默认为0.5
// set preprocess and algorithm param for yolov6 detection
// if use official model, no need to change param
CVI_S32 init_param(const cvitdl_handle_t tdl_handle) {
// setup preprocess
YoloPreParam preprocess_cfg =
CVI_TDL_Get_YOLO_Preparam(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV6);
for (int i = 0; i < 3; i++) {
printf("asign val %d \n", i);
preprocess_cfg.factor[i] = 0.003922;
preprocess_cfg.mean[i] = 0.0;
}
preprocess_cfg.format = PIXEL_FORMAT_RGB_888_PLANAR;
printf("setup yolov6 param \n");
CVI_S32 ret =
CVI_TDL_Set_YOLO_Preparam(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV6, preprocess_cfg);
if (ret != CVI_SUCCESS) {
printf("Can not set yolov6 preprocess parameters %#x\n", ret);
return ret;
}
// setup yolo algorithm preprocess
YoloAlgParam yolov6_param = CVI_TDL_Get_YOLO_Algparam(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV6);
yolov6_param.cls = 80;
printf("setup yolov6 algorithm param \n");
ret = CVI_TDL_Set_YOLO_Algparam(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV6, yolov6_param);
if (ret != CVI_SUCCESS) {
printf("Can not set yolov6 algorithm parameters %#x\n", ret);
return ret;
}
// set thershold
CVI_TDL_SetModelThreshold(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV6, 0.5);
CVI_TDL_SetModelNmsThreshold(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV6, 0.5);
printf("yolov6 algorithm parameters setup success!\n");
return ret;
}
推理代码如下:
推理代码如下:
通过本地或者流获取图片,并通过CVI_TDL_ReadImage函数读取图片,然后调用Yolov6推理接口CVI_TDL_Yolov6。推理的结果存放在obj_meta结构体中,遍历获取边界框bbox的左上角以及右下角坐标点以及object score(x1, y1, x2, y2, score),另外还有分类classes
ret = CVI_TDL_OpenModel(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV6, model_path.c_str());
if (ret != CVI_SUCCESS) {
printf("open model failed %#x!\n", ret);
return ret;
}
printf("cvimodel open success!\n");
std::cout << "model opened:" << model_path << std::endl;
VIDEO_FRAME_INFO_S fdFrame;
ret = CVI_TDL_ReadImage(str_src_dir.c_str(), &fdFrame, PIXEL_FORMAT_RGB_888);
std::cout << "CVI_TDL_ReadImage done!\n";
if (ret != CVI_SUCCESS) {
std::cout << "Convert out video frame failed with :" << ret << ".file:" << str_src_dir
<< std::endl;
}
cvtdl_object_t obj_meta = {0};
CVI_TDL_Yolov6(tdl_handle, &fdFrame, &obj_meta);
printf("detect number: %d\n", obj_meta.size);
for (uint32_t i = 0; i < obj_meta.size; i++) {
printf("detect res: %f %f %f %f %f %d\n", obj_meta.info[i].bbox.x1, obj_meta.info[i].bbox.y1,
obj_meta.info[i].bbox.x2, obj_meta.info[i].bbox.y2, obj_meta.info[i].bbox.score,
obj_meta.info[i].classes);
}
4.5. 测试结果¶
转换了yolov6官方仓库给出的yolov6n以及yolov6s,测试数据集为COCO2017
其中阈值参数设置为:
conf_threshold: 0.03
nms_threshold: 0.65
分辨率均为640x640
yolov6n模型的官方导出方式性能:
测试平台 |
推理耗时 (ms) |
带宽 (MB) |
ION(MB) |
MAP 0.5 |
MAP 0.5-0.95 |
---|---|---|---|---|---|
pytorch |
N/A |
N/A |
N/A |
53.1 |
37.5 |
cv180x |
ion分配失败 |
ion分配失败 |
15.59 |
量化失败 |
量化失败 |
cv181x |
ion分配失败 |
ion分配失败 |
11.58 |
量化失败 |
量化失败 |
cv182x |
39.17 |
47.08 |
11.56 |
量化失败 |
量化失败 |
cv183x |
量化失败 |
量化失败 |
量化失败 |
量化失败 |
量化失败 |
cv186x |
4.74 |
51.28 |
14.04 |
量化失败 |
量化失败 |
yolov6n模型的TDL_SDK导出方式性能:
测试平台 |
推理耗时 (ms) |
带宽 (MB) |
ION(MB) |
MAP 0.5 |
MAP 0.5-0.95 |
---|---|---|---|---|---|
onnx |
N/A |
N/A |
N/A |
51.6373 |
36.4384 |
cv180x |
ion分配失败 |
ion分配失败 |
14.74 |
ion分配失败 |
ion分配失败 |
cv181x |
49.11 |
31.35 |
8.46 |
49.8226 |
34.284 |
cv182x |
34.14 |
30.53 |
8.45 |
49.8226 |
34.284 |
cv183x |
10.89 |
21.22 |
8.49 |
49.8226 |
34.284 |
cv186x |
4.02 |
36.26 |
12.67 |
41.53 |
27.63 |
yolov6s模型的官方导出方式性能:
测试平台 |
推理耗时 (ms) |
带宽 (MB) |
ION(MB) |
MAP 0.5 |
MAP 0.5-0.95 |
---|---|---|---|---|---|
pytorch |
N/A |
N/A |
N/A |
61.8 |
45 |
cv180x |
模型转换失败 |
模型转换失败 |
模型转换失败 |
模型转换失败 |
模型转换失败 |
cv181x |
ion分配失败 |
ion分配失败 |
27.56 |
量化失败 |
量化失败 |
cv182x |
131.1 |
115.81 |
27.56 |
量化失败 |
量化失败 |
cv183x |
量化失败 |
量化失败 |
量化失败 |
量化失败 |
量化失败 |
cv186x |
14.67 |
100.02 |
29.66 |
量化失败 |
量化失败 |
yolov6s模型的TDL_SDK导出方式性能:
测试平台 |
推理耗时 (ms) |
带宽 (MB) |
ION(MB) |
MAP 0.5 |
MAP 0.5-0.95 |
---|---|---|---|---|---|
onnx |
N/A |
N/A |
N/A |
60.1657 |
43.5878 |
cv180x |
ion分配失败 |
ion分配失败 |
45.27 |
ion分配失败 |
ion分配失败 |
cv181x |
ion分配失败 |
ion分配失败 |
25.33 |
ion分配失败 |
ion分配失败 |
cv182x |
126.04 |
99.16 |
25.32 |
56.2774 |
40.0781 |
cv183x |
38.55 |
57.26 |
23.59 |
56.2774 |
40.0781 |
cv186x |
13.89 |
85.96 |
29.57 |
46.02 |
31.61 |