7. 示例——YOLOv5s量化

在本章节将以YOLOv5s为例,分别介绍使用auto-cali一键量化工具和分步量化的方式对YOLOv5s模型进行量化及调优。

7.1. 使用auto-cali一键量化工具量化

以下章节将以量化Pytorch框架下的yolov5s网络为例,说明auto-cali量化步骤

7.1.1. 准备量化数据集

auto-cali可使用图片数据集和lmdb数据集,在本章节我们以图片数据集为例进行讲解,对于lmdb数据集的具体制作步骤可参考 # TODO

首先下载量化数据集coco128,可使用 SDK/examples/calibration/create_lmdb_demo 下的脚本进行下载

cd SDK/examples/calibration/create_lmdb_demo
bash ./download_coco128.sh

7.1.2. 使用auto-cali编译模型并进行调优

进入 SDK/examples/calibration/auto_cali_demo/yolov5s_demo/auto_cali_demo,使用如下命令进行量化,auto-cali会自动处理图片数据集将其转为lmdb数据集,并使用不同量化策略量化多次,自动生成bmodel。

python3 -m ufw.cali.cali_model \
   --net_name 'yolov5s' \
   --model ./yolov5s_jit.pt \
   --cali_image_path ../../create_lmdb_demo/coco128/images/train2017/ \
   --cali_image_preprocess 'resize_h=640,resize_w=640;scale=0.003921569,bgr2rgb=True' \
   --input_shapes '[1,3,640,640]'

等待量化结束后即可在 ./yolov5s_bmnetp_test_fp32/ 目录下看到生成的 compilation.bmodel。

我们可以使用可视化工具初步查看量化精度

python3 -m ufw.tools.app --port 8001

在浏览器中打开localhost:8001,点击forward,等待程序运行完成,可以看到如下结果:

../_images/ch6_004.png

以余弦相似度看精度较好,但这个结果仅供参考,具体精度还是得以测试程序以及相关测试指标为准。

下面进行精度测试,首先安装测试用的Python包,并下载标注文件

pip3 install pycocotools
bash ./download_from_nas.sh http://219.142.246.77:65000/sharing/ivVtP2yIg

运行精度测试的命令,要特别注意的是,本次精度测试数据集使用coco128,所得出的mAP的结果并不能与YOLOv5s论文中的mAP精度完全等价。

bash ./regression.sh ./yolov5s_bmnetp_test_fp32/compilation.bmodel ./result.json

运行结束之后可得到如下结果(可能会与实际结果略有偏差,以实际结果为准):

../_images/auto_int8.png

可以看到精度较差,这是因为YOLOv5s网络最后三层卷积结构输出得分以及坐标点等关键信息,对精度要求较高。下面我们将最后三个卷积及之后的层使用fp32进行量化。

下列命令中的 try_cali_accuracy_opt 代表将后面fpfwd_outputs参数传入 calibration_use_pb 工具,可以使用 calibration_use_pb -help查看具体参数说明。

python3 -m ufw.cali.cali_model \
   --net_name 'yolov5s' \
   --model ./yolov5s_jit.pt \
   --cali_image_path ../../create_lmdb_demo/coco128/images/train2017/ \
   --cali_image_preprocess 'resize_h=640,resize_w=640;scale=0.003921569,bgr2rgb=True' \
   --input_shapes '[1,3,640,640]' \
   --postprocess_and_calc_score_clas=feature_similarity \
   --try_cali_accuracy_opt='-fpfwd_outputs=< 24 >14,< 24 >51,< 24 >82'

# 或直接运行下列脚本,结果等价
bash ./auto_cali.sh

运行精度测试的命令。

bash ./regression.sh ./yolov5s_bmnetp_test_fp32/compilation.bmodel ./result.json

得到下列结果:

../_images/auto_fp32.png

可以看到相比于最后三个卷积层使用int8量化,使用fp32推理提升了精度。

7.2. 分步量化YOLOv5s

7.2.1. 准备量化数据集

分步量化时只能使用lmdb作为量化数据集,在此章节同样使用coco128作为量化数据集。

首先参考 准备量化数据集 下载数据集,然后在SDK/examples/calibraton/create_lmdb_demo/目录下,调用脚本直接生成

python3 convert_imageset.py \
  --imageset_rootfolder=./coco128/images/train2017 \
  --imageset_lmdbfolder=./lmdb \
  --resize_height=640 \
  --resize_width=640 \
  --shuffle=True \
  --bgr2rgb=False \
  --gray=False

7.2.2. pt文件转fp32umodel

进入SDK/examples/calibraton/pt_to_fp32umodel_demo/

python3 ./yolov5s_to_umodel.py

程序运行结束之后会在当前文件夹下生成compilation文件夹,compilation文件夹下即为fp32umodel和prototxt。

7.2.3. 修改prototxt

下面我们将修改上一步生成的prototxt,此处要对其YOLOv5s模型的前处理,并将数据输入指向lmdb文件,要注意,此处lmdb文件的路径要写绝对路径。具体修改内容如下:

../_images/ch6_005.png

7.2.4. 量化生成int8umodel

上一步我们修改了prototxt,这一步我们将使用修改后的prototxt和fp32umodel,量化生成int8umodel。由 使用auto-cali一键量化工具量化 的经验可知,我们需要将最后三层卷积及之后的层使用fp32推理。

calibration_use_pb quantize \
   --model=./compilation/yolov5s_jit_bmnetp_test_fp32.prototxt --weights=./compilation/yolov5s_jit_bmnetp.fp32umodel \
   -save_test_proto=true --bitwidth=TO_INT8 -fpfwd_outputs="< 24 >14,< 24 >51,< 24 >82"

量化程序运行结束之后可以在compilation文件夹得到 yolov5s_jit_bmnetp_deploy_int8_unique_top.prototxt和yolov5s_jit_bmnetp.int8umodel。

7.2.5. 生成int8bmodel

使用bmnetu工具,以上一步得到的为输入:

bmnetu --model=./compilation/yolov5s_jit_bmnetp_deploy_int8_unique_top.prototxt --weight=./compilation/yolov5s_jit_bmnetp.int8umodel

运行结束之后得到compilation.bmodel。

7.2.6. 精度测试

参照 使用auto-cali一键量化工具量化 的测试mAP步骤,可以得到如下结果,可以看到精度损失较小。

../_images/steps_fp32.png