跳到主要内容

YOLOv5

YOLOv5

本教程将引导你如何通过 CPU 或 NPU 在 RevyOS 系统上运行 YOLOv5 模型。

初始环境配置

在按照本教程操作前,请确保你已经完成了环境配置部分的内容。

示例代码获取

本教程配套的示例代码已更新到 Github 中,使用 git 命令将其克隆到本地。

$ git clone https://github.com/zhangwm-pt/lpi4a-example.git

适用于本教程的代码位于 detection/yolov5 目录下。

模型获取

本教程中使用的模型来自 yolov5 模型仓库,可通过其 export.py 脚本导出。

$ git clone https://github.com/ultralytics/yolov5.git
$ cd yolov5
$ pip3 install ultralytics
$ python3 export.py --weights yolov5n.pt --include onnx --imgsz 384 640
关于 Github 的网络代理

如果你在中国大陆访问 GitHub 时遇到网络问题,可以考虑使用网络代理工具来加速访问。

转换和编译模型

环境配置完成后,即可使用 HHB 编译模型为 c920 上的可执行程序。

本教程中使用的检测模型是 yolov5n,针对 yolov5n,hhb 命令中截取到最后的卷积层为止,卷积层之后的后处理,交由示例中已准备好的 yolov5n.c 文件处理。

进入 detection/yolov5 目录,执行以下命令:

$ hhb -D --model-file yolov5n.onnx --data-scale-div 255 \
--board th1520 --input-name "images" --output-name \
"/model.24/m.0/Conv_output_0;/model.24/m.1/Conv_output_0;/model.24/m.2/Conv_output_0" \
--input-shape "1 3 384 640" --calibrate-dataset kite.jpg \
--quantization-scheme "int8_asym"
关于参数
  • -D:指定 HHB 流程执行到生成可执行文件的阶段为止
  • --model-file:指定输入模型文件
  • --data-mean:指定均值
  • --data-scale:指定缩放值
  • --board:指定目标平台为 C920(CPU) 或 TH1520(NPU)
  • --input-name: 模型的输入 tensor 名
  • --output-name:模型的输出 tensor 名
  • --input-shape:模型的输入 tensor 形状
  • --postprocess:指定 HHB 生成的胶水代码的后处理行为。save_and_top5 表示保存输出结果,并且打印 top5 结果
  • --quantization-scheme:指定量化类型

你可以通过运行 hhb --help 查看所有可用的参数和选项。

关于 HHB 生成的文件

命令执行完成后,会在当前目录生成 hhb_out 子目录,里面的包括了 hhb_runtime model.c 等多个文件:

  • hhb.bm:HHB 的模型文件,包括了量化后的权重数据等信息
  • hhb_runtime:适用于开发板的可执行文件,由目录中的C文件编译而成
  • main.c:HHB 生成的示例程序的参考入口
  • model.c:HHB 模型结构表示文件,与模型结构相关
  • model.params:模型权重文件
  • io.c:HHB 生成的示例程序,包含读写文件的辅助函数
  • io.h:HHB 生成的示例程序,包含读写文件的辅助函数声明
  • process.c:HHB 生成的示例程序,包含图像预处理函数
  • process.h:HHB 生成的示例程序,包含图像预处理函数声明

gcc 编译后处理

本教程中,使用了 c 代码实现模型的后半部分和 NMS,后处理输出图片对应的检测结果。

$ riscv64-unknown-linux-gnu-gcc yolov5n.c -o yolov5n_example hhb_out/io.c \
hhb_out/model.c -Wl,--gc-sections -O2 -g -mabi=lp64d -I hhb_out/ -L \
/usr/local/lib/python3.8/dist-packages/hhb/install_nn2/th1520/lib/ \
-lshl -L /usr/local/lib/python3.8/dist-packages/hhb/prebuilt/decode/install/lib/rv \
-L /usr/local/lib/python3.8/dist-packages/hhb/prebuilt/runtime/riscv_linux \
-lprebuilt_runtime -ljpeg -lpng -lz -lstdc++ -lm -I \
/usr/local/lib/python3.8/dist-packages/hhb/install_nn2/th1520/include/ -mabi=lp64d \
-march=rv64gcv0p7_zfh_xtheadc -Wl,-unresolved-symbols=ignore-in-shared-libs -I \
/usr/local/lib/python3.8/dist-packages/hhb/install_nn2/th1520/include/shl_public/ \
-I /usr/local/lib/python3.8/dist-packages/hhb/install_nn2/th1520/include/csinn/

本教程的示例代码中链接了 shl 库,比如 shl 的安装目录在 /usr/local/lib/python3.8/dist-packages/shl

选项说明
  • -Ihhb_out -I/usr/local/lib/python3.8/dist-packages/shl/install_nn2/c920/include/:头文件的搜索路径,指定到 shl 的头文件路径
  • -L/usr/local/lib/python3.8/dist-packages/shl/install_nn2/c920/lib:库的搜索路径,指定到预编译好的 shl 的二进制库路径
  • -static:指定为静态链接
  • -o yolov5n_example:指定生成名为 yolov5n_example 的可执行文件

编译命令正确执行完成后会在示例目录生成 yolov5n_example 文件。

执行

交叉编译完成后,即可将程序执行所需的文件复制到开发板的目录中。

以开发板 ip 为 10.63.x.x,使用 /demo 目录为例,主机上将示例程序的目录通过 scp 复制到目录中:

scp -r yolov5n th1520@10.63.x.x:/demo/

linux 命令行执行时,开发板的命令行终端上,到示例目录执行命令。执行完成后,会在终端上提示执行到的各个阶段:

  1. 预处理:将原图填充缩放到 384 * 640 的大小
  2. 模型执行和后处理:执行模型推理,并做 nms 等后处理
  3. 画框:将检测结果画在 384 * 640 尺寸的图上,并输出新图片
执行需要的文件
  • kite.jpg:输入图片
  • image_preprocessed.bin:预处理阶段,根据输入图片生成的中间结果
  • yolov5n_example:模型执行阶段使用的文件,由x86主机上 gcc 编译生成
  • hhb_out/hhb.bm:模型执行阶段使用的文件,由x86主机上 HHB 生成
  • detect.txt:后处理阶段的输出文件,包括了图片中检测出来的 4 个目标
  • kite_result.jpg:输出图片,将检测框加入到输入图上的结果

参考结果

本教程中输入如下图,是一个一家三口放风筝的图片,预期 yolov5 的检测结果是检测到三个人和一个风筝。 输入图像 检测图像

示例正常执行时,会有类似如下打印:

$ python3 inference.py
********** preprocess image **********
******* run yolov5 and postprocess *******
INFO: NNA clock:1001624 [kHz]
INFO: Heap :anonymous (0x2)
INFO: Heap :dmabuf (0x2)
INFO: Heap :unified (0x5)
WARNING: Mapping to the on chip ram failed (128 > 0), continuing...
FATAL: Importing 737280 bytes of CPU memory has failed (Invalid argument)
Run graph execution time: 11.96299ms, FPS=83.59
detect num: 4
id: label score x1 y1 x2 y2
[0]: 0 0.895277 273.492188 161.245056 359.559814 330.644257
[1]: 0 0.887368 79.860062 179.181244 190.755692 354.304474
[2]: 0 0.815214 222.054565 224.477600 279.828979 333.717285
[3]: 33 0.563324 67.625580 173.948883 201.687988 219.065765
********** draw bbox **********
[273.492188, 161.245056, 359.559814, 330.644257, 0.895277, 0]
[79.860062, 179.181244, 190.755692, 354.304474, 0.887368, 0]
[222.054565, 224.4776, 279.828979, 333.717285, 0.815214, 0]
[67.62558, 173.948883, 201.687988, 219.065765, 0.563324, 33]