7. 示例——YOLOv5s量化¶
在本章节将以YOLOv5s为例,分别介绍使用auto-cali一键量化工具和分步量化的方式对YOLOv5s模型进行量化及调优。
对于auto-cali一键量化工具的详细介绍可参考 auto-cali量化
对于分步量化详细介绍可参考 分步量化
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,等待程序运行完成,可以看到如下结果:
以余弦相似度看精度较好,但这个结果仅供参考,具体精度还是得以测试程序以及相关测试指标为准。
下面进行精度测试,首先安装测试用的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
运行结束之后可得到如下结果(可能会与实际结果略有偏差,以实际结果为准):
可以看到精度较差,这是因为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
得到下列结果:
可以看到相比于最后三个卷积层使用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文件的路径要写绝对路径。具体修改内容如下:
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步骤,可以得到如下结果,可以看到精度损失较小。