9. 通用yolov10模型部署

9.1. 引言

本文档介绍了如何将yolov10架构的模型部署在cv181x开发板的操作流程,主要的操作步骤包括:

  • yolov10模型pytorch版本转换为onnx模型

  • onnx模型转换为cvimodel格式

  • 最后编写调用接口获取推理结果

9.2. pt模型转换为onnx

首先获取yolov10官方仓库代码 [THU-MIG/yolov10](https://github.com/THU-MIG/yolov10)

git clone https://github.com/THU-MIG/yolov10.git

再下载对应的 yolov10 模型文件,以[yolov10n](https://github.com/THU-MIG/yolov10.git)为例,将下载的yolov10n.pt放在./weights/目录下,如下命令行所示

mkdir weights
cd weights
wget https://github.com/THU-MIG/yolov10/releases/download/v1.1/yolov10n.pt

调整yolov10输出分支,去掉forward函数的解码部分,并将三个不同的feature map的box以及cls分开,得到6个分支,这一步可以直接使用yolo_export的脚本完成

yolo_export中的脚本可以通过SFTP获取:下载站台:sftp://218.17.249.213 帐号:cvitek_mlir_2023 密码:7&2Wd%cu5k

通过SFTP找到下图对应的文件夹:

/home/公版深度学习SDK/yolo_export.zip

将yolo_export/yolov10_export.py代码复制到yolov10仓库根目录下,然后使用以下命令导出分支版本的onnx模型:

python yolov10_export.py --weights ./weights/yolov10.pt

运行上述代码之后,可以在./weights/目录下得到 yolov10n.onnx 文件,之后就是将onnx模型转换为cvimodel模型

小技巧

如果输入为1080p的视频流,建议将模型输入尺寸改为384x640,可以减少冗余计算,提高推理速度,如下:

python yolov10_export.py --weights ./weights/yolov10.pt --img-size 384 640

9.3. onnx模型转换cvimodel

cvimodel转换操作可以参考cvimodel转换操作可以参考yolo-v5移植章节的onnx模型转换cvimodel部分。

9.4. TDL_SDK接口说明

yolov10的预处理设置参考如下:

// set preprocess and algorithm param for yolov8 detection
// if use official model, no need to change param
CVI_S32 init_param(const cvitdl_handle_t tdl_handle) {
  // setup preprocess
  cvtdl_pre_param_t preprocess_cfg =
      CVI_TDL_GetPreParam(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV10_DETECTION);

  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 yolov10 param \n");
  CVI_S32 ret =
      CVI_TDL_SetPreParam(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV10_DETECTION, preprocess_cfg);
  if (ret != CVI_SUCCESS) {
    printf("Can not set yolov10 preprocess parameters %#x\n", ret);
    return ret;
  }

  // setup yolo algorithm preprocess
  cvtdl_det_algo_param_t yolov10_param =
      CVI_TDL_GetDetectionAlgoParam(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV10_DETECTION);
  yolov10_param.cls = 80;
  yolov10_param.max_det = 100;

  printf("setup yolov10 algorithm param \n");
  ret = CVI_TDL_SetDetectionAlgoParam(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV10_DETECTION,
                                      yolov10_param);
  if (ret != CVI_SUCCESS) {
    printf("Can not set yolov10 algorithm parameters %#x\n", ret);
    return ret;
  }

  // set theshold
  CVI_TDL_SetModelThreshold(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV10_DETECTION, 0.5);

  printf("yolov10 algorithm parameters setup success!\n");
  return ret;
}

推理测试代码:

ret = CVI_TDL_OpenModel(tdl_handle, CVI_TDL_SUPPORTED_MODEL_YOLOV10_DETECTION, argv[1]);

if (ret != CVI_SUCCESS) {
  printf("open model failed with %#x!\n", ret);
  return ret;
}
printf("---------------------to do detection-----------------------\n");

VIDEO_FRAME_INFO_S bg;
ret = CVI_TDL_ReadImage(strf1.c_str(), &bg, PIXEL_FORMAT_RGB_888_PLANAR);
if (ret != CVI_SUCCESS) {
  printf("open img failed with %#x!\n", ret);
  return ret;
} else {
  printf("image read,width:%d\n", bg.stVFrame.u32Width);
  printf("image read,hidth:%d\n", bg.stVFrame.u32Height);
}
std::string str_res;
cvtdl_object_t obj_meta = {0};
CVI_TDL_YOLOV10_Detection(tdl_handle, &bg, &obj_meta);

std::cout << "objnum:" << obj_meta.size << std::endl;
std::stringstream ss;
ss << "boxes=[";
for (uint32_t i = 0; i < obj_meta.size; i++) {
  ss << "[" << 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].classes << "," << obj_meta.info[i].bbox.score << "],";
}
ss << "]\n";
std::cout << ss.str();

9.5. 测试结果

转换测试了官网的yolov10n模型,在COCO2017数据集上进行了测试,其中阈值设置为:

  • conf: 0.001

  • max_det: 100

所有分辨率均为640 x 640

yolov10n模型的官方导出方式性能:

测试平台

推理耗时 (ms)

带宽 (MB)

ION(MB)

MAP 0.5

MAP 0.5-0.95

pytorch

N/A

N/A

N/A

N/A

38.5

cv180x

量化失败

量化失败

量化失败

量化失败

量化失败

cv181x

量化失败

量化失败

量化失败

量化失败

量化失败

cv182x

量化失败

量化失败

量化失败

量化失败

量化失败

cv183x

量化失败

量化失败

量化失败

量化失败

量化失败

cv186x

量化失败

量化失败

量化失败

量化失败

量化失败

目前 yolov10n 官方导出版本中存在 mod 算子,tpu-mlir工具链暂时不支持该算子

yolov10n模型的TDL_SDK导出方式性能:

测试平台

推理耗时 (ms)

带宽 (MB)

ION(MB)

MAP 0.5

MAP 0.5-0.95

onnx

N/A

N/A

N/A

52.9

38.0

cv180x

245

83.98

11.47

40.126

29.118

cv181x

45.3

42.86

7.08

48.7

35.2

cv182x

20.6

41.86

7.72

48.7

48.7

cv183x

N/A

N/A

6.77

N/A

N/A

cv186x

5.362

49.38

11.20

44.9

33.0