ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OpenVINO 2022.1 实战指南:YOLOv5s 导出 ONNX、转换 IR 并完成 INT8 量化与 CPU 基准测试

OpenVINO 2022.1 实战指南:YOLOv5s 导出 ONNX、转换 IR 并完成 INT8 量化与 CPU 基准测试 示例工程【免费下载链接】deep-learning-for-image-processingdeep learning for image processing including classification and object-detection etc.项目地址https://gitcode.com/gh_mirrors/de/deep-learning-for-image-processing点击查看免费下载本篇技术指南基于本仓库中deploying_service/deploying_pytorch/convert_openvino/convert_yolov5模块完整讲解 YOLOv5以 YOLOv5s 为例在 OpenVINO 2022.1 工具套件下的端到端部署流水线PyTorch 权重 → ONNX → OpenVINO IRFP32→ INT8 量化 → benchmark_app 基准测试并附上量化前后 CPU 推理的吞吐与延迟实测数据。读者按照本文步骤即可在自己的 COCO2017 数据集上复现导出—转换—量化—评测—测速全流程并了解quantization_int8.py、evaluation.py、predict.py、utils.py等脚本的实现细节。一、整体流程概览整个 YOLOv5 的 OpenVINO 部署链路包含以下五个阶段每个阶段在本模块中都有对应的脚本或命令行工具支撑环境配置按照requirements.txt安装依赖关键依赖为openvino-dev2022.1.0其中自带模型优化器mo与量化所需的 POT 工具链。YOLOv5 → ONNX使用 YOLOv5 官方仓库自带的export.py导出仅导出 ONNXYOLOv5 官方也提供直接导出 OpenVINO 的方法但本流程只使用 ONNX 作为中间格式。ONNX → IR使用 OpenVINO 模型优化器mo命令将 ONNX 转为 OpenVINO 的 IR 格式.xml.bin并在此阶段声明输入形状与像素归一化方式。INT8 量化运行quantization_int8.py基于 COCO2017 验证集子集统计激活值分布使用 OpenVINO POT 的DefaultQuantization算法产出量化模型。验证与基准测试使用benchmark_app对比 FP32 与 INT8 的吞吐/延迟使用evaluation.py计算量化前后 mAP 精度使用predict.py完成单图推理可视化。二、环境配置requirements.txt 依赖解析convert_yolov5/requirements.txt中列出的依赖及版本如下torch1.13.1 torchvision0.12.0 onnx1.13.0 onnxruntime1.8.0 protobuf3.19.5 openvino-dev2022.1.0 matplotlib torchmetrics0.9.1其中需要特别说明的几点openvino-dev2022.1.0是整套流程的核心该发行包不仅包含 OpenVINO 运行时openvino.runtime.Core还集成了模型优化器mo、benchmark_app等部署工具以及compressionPOT 后训练量化工具包模块后者是quantization_int8.py依赖的基础。onnxruntime用于在导出后对 ONNX 模型做一致性校验与单独测速见compare_onnx_and_ir.py与compare_fps.py。torchmetrics0.9.1提供目标检测的MeanAveragePrecision实现utils.py中的MAPMetric即是对它的封装。protobuf3.19.5属于 ONNX 解析的间接依赖固定版本以避免与 onnx 1.13.0 出现兼容性问题。安装方式在模块目录下执行pip install -r requirements.txt注意openvino-dev的各组件版本绑定较紧建议严格按 requirements 固定版本安装以避免mo工具与 POTcompression包之间出现 API 不匹配。三、将 YOLOv5 导出为 ONNXYOLOv5 官方仓库提供了导出 ONNX 以及 OpenVINO 的方法本流程只使用 ONNX 作为中间产物。以 YOLOv5s 为例在 YOLOv5 官方项目目录下执行python export.py --weights yolov5s.pt --include onnx导出后会得到yolov5s.onnx将其放置到convert_yolov5模块目录下后续mo转换、quantization_int8.py、compare_onnx_and_ir.py均默认在模块当前目录查找yolov5s.onnx。export.py默认将 ONNX 输入导出为动态形状但后续mo转换时会通过--input_shape将其固定为[1,3,640,640]。四、使用 mo 工具将 ONNX 转换为 OpenVINO IR使用 OpenVINO 模型优化器mo将 ONNX 转为 IR 格式mo --input_model yolov5s.onnx \ --input_shape [1,3,640,640] \ --scale 255 \ --data_type FP32 \ --output_dir ir_output各参数含义与取值说明参数本流程取值作用--input_modelyolov5s.onnx指定输入的 ONNX 模型文件路径--input_shape[1,3,640,640]固定输入张量形状1 张图、3 通道、高宽 640×640固定后模型输入节点名称为images输出节点名称为output与后续量化脚本中的inputs/outputs配置对应--scale 255255将像素从 [0,255] 缩放到 [0,1]即把归一化操作折叠进 IR 模型内部推理时可直接喂入 0~255 的原始图像数据--data_typeFP32中间表示权重精度为 FP32--output_dirir_outputIR 输出目录生成yolov5s.xml网络结构与yolov5s.bin权重二进制这里有一个值得注意的预处理对齐细节mo通过--scale 255把归一化熔入模型因此后续推理无需再手动除以 255。这一约定在源码中得到了印证compare_onnx_and_ir.py中ONNX 推理传入的是normalized_image已除以 255main.py的normalize函数中image / 255.0而 IR 推理直接传入原始input_image未归一化两者通过np.testing.assert_allclose(onnx_res, ir_res, rtol1e-03, atol1e-05)校验输出一致predict.py中letterbox处理后的图像直接astype(np.float32)送入 IR 模型全程不除 255。五、INT8 量化脚本入口与 COCO2017 数据集量化脚本为quantization_int8.py执行前需要准备COCO2017 数据集并将脚本开头的data_path指向coco2017根目录data_path /data/coco2017 # 指向 coco2017 根目录 ir_model_xml ir_output/yolov5s.xml ir_model_bin ir_output/yolov5s.bin save_dir quant_ir_output # 量化模型输出目录 model_name quantized_yolov5s # 量化模型文件名 img_w 640 img_h 640COCO2017 数据集的标准目录结构如下├── coco2017: 数据集根目录 ├── train2017: 所有训练图像文件夹(118287张) ├── val2017: 所有验证图像文件夹(5000张) └── annotations: 对应标注文件夹 ├── instances_train2017.json: 对应目标检测、分割任务的训练集标注文件 ├── instances_val2017.json: 对应目标检测、分割任务的验证集标注文件 ├── captions_train2017.json: 对应图像描述的训练集标注文件 ├── captions_val2017.json: 对应图像描述的验证集标注文件 ├── person_keypoints_train2017.json: 对应人体关键点检测的训练集标注文件 └── person_keypoints_val2017.json: 对应人体关键点检测的验证集标注文件夹量化阶段实际使用的是val20175000 张验证图像与instances_val2017.jsonquantization_int8.py中通过MyDataLoader(data_path, val, (img_h, img_w))加载验证集从中采样 300 张图像见下文stat_subset_size用于统计每层激活值的分布从而确定 INT8 量化参数。六、量化脚本源码解析POT 管线的 8 个步骤quantization_int8.py基于 OpenVINO 2022.1 的 POTPost-Training Optimization Toolkit接口编写核心代码结构如下。1. 配置模型、引擎与量化算法from addict import Dict from compression.engines.ie_engine import IEEngine from compression.graph import load_model, save_model from compression.graph.model_utils import compress_model_weights from compression.pipeline.initializer import create_pipeline model_config Dict({ model_name: yolov5s, model: ir_model_xml, # ir_output/yolov5s.xml weights: ir_model_bin, # ir_output/yolov5s.bin inputs: images, # 输入节点名与 mo 转换后的节点名一致 outputs: output # 输出节点名 }) engine_config Dict({device: CPU}) algorithms [ { name: DefaultQuantization, params: { target_device: CPU, preset: performance, # 追求性能优先的量化参数组合 stat_subset_size: 300 # 用于统计激活分布的图像子集大小 } } ]关键参数说明inputs/outputs必须与mo转换所得 IR 的输入输出张量名一致即images/output否则加载模型会失败。preset: performancePOT 提供的预设之一选择偏向推理性能的量化策略另一个可选值为accuracy更偏向精度保持。多数场景下performance已足够若精度损失明显可切换为accuracy重新量化。stat_subset_size: 300从数据加载器中取前 300 个样本统计激活值分布。增大该值可提升量化精度估计的稳定性但会线性增加量化耗时。2. 加载模型、构建数据加载器与指标、执行量化管线脚本按以下 8 个步骤组织# Step 1: Load the model. model load_model(model_config) # Step 2: Initialize the data loader. data_loader MyDataLoader(data_path, val, (img_h, img_w)) # Step 3: initialize the metricDefaultQuantization 中指标为可选可为 None metric MAPMetric(map_valuemap) # Step 4: Initialize the engine for metric calculation and statistics collection. engine IEEngine(configengine_config, data_loaderdata_loader, metricmetric) # Step 5: Create a pipeline of compression algorithms. pipeline create_pipeline(algorithms, engine) # Step 6: Execute the pipeline to quantize the model compressed_model pipeline.run(model) # Step 7 (Optional): Compress model weights to quantized precision # 以减小最终 .bin 文件体积 compress_model_weights(compressed_model) # Step 8: Save the compressed model to the desired path. compressed_model_paths save_model( modelcompressed_model, save_pathsave_dir, # quant_ir_output model_namemodel_name, # quantized_yolov5s ) print(The quantized model is stored at, compressed_model_paths[0][model])执行完毕后量化模型保存在quant_ir_output/quantized_yolov5s.xml与quant_ir_output/quantized_yolov5s.bin。其中compress_model_weights将权重压缩为量化精度可显著减小.bin体积属于可选的优化步骤。3. 量化前后精度对比脚本尾部同时加载原始 IR 模型与量化模型在同一数据加载器上评估并打印 mAP用于观察量化引入的精度损失ir_model load_model(model_configmodel_config) evaluation_pipeline create_pipeline(algo_configdict(), engineengine) original_metric evaluation_pipeline.evaluate(ir_model) # 原始 FP32 IR 的 mAP quantized_metric pipeline.evaluate(compressed_model) # 量化 INT8 模型的 mAP运行日志示例The map score of the original model is 0.xxxxx The map score of the quantized INT8 model is 0.xxxxx七、支撑源码数据加载器与指标实现utils.pyutils.py是量化与评测脚本的公共支撑模块包含以下关键实现1.MyDataLoaderPOTDataLoader子类class MyDataLoader(DataLoader): def __init__(self, root, datasettrain, size(640, 640)): # dataset 仅允许 train 或 val anno_file instances_{}2017.json.format(dataset) self.img_root os.path.join(root, {}2017.format(dataset)) self.anno_path os.path.join(root, annotations, anno_file) self.coco COCO(self.anno_path) # pycocotools 解析标注加载器内部通过_coco_remove_images_without_annotations剔除没有目标或目标面积过小bbox 宽高 ≤ 1 像素的图片__getitem__中先对原图执行letterbox等比例缩放 灰边填充到 640×640autoFalse表示不做最小矩形自适应直接补齐到目标尺寸再用parse_targets把 COCO 的[x,y,w,h]标注转换为[xmin,ymin,xmax,ymax]并同步缩放、平移同时将 COCO 91 类 id 映射到 YOLOv5 的 80 类索引。2.MAPMetricPOTMetric子类封装 torchmetricsclass MAPMetric(Metric): def __init__(self, map_valuemap, conf_thres0.001, iou_thres0.6): self.metric MeanAveragePrecision(box_formatxyxy)在update()中模型输出的原始张量先经non_max_suppression置信度阈值conf_thres0.001、IoU 阈值iou_thres0.6、multi_labelTrue后处理再转换为 torchmetrics 期望的preds/targets格式。avg_value属性返回mean_average_precision.compute()[map]作为 POT 管线的精度反馈。可返回的指标值包括mar_1、mar_10、mar_100、map、map_50、map_75、map_small、map_medium、map_large等。3. 后处理工具函数non_max_suppression标准 NMS 实现来自 YOLOv5支持conf_thres、iou_thres、agnostic、multi_label、max_det等参数letterbox等比例缩放并填充到模型输入尺寸scale_coords/clip_coords将模型输出坐标从 640×640 尺度映射回原图尺度并裁剪到图像边界内coco80_namesCOCO 80 类名称列表person、bicycle、car … toothbrush用于predict.py的类别标注。八、量化模型精度验证evaluation.py量化完成后可用evaluation.py在 COCO val2017 上独立复算量化模型的 mAPdata_path /data/coco2017 ir_model_xml quant_ir_output/quantized_yolov5s.xml img_size (640, 640) data_loader MyDataLoader(data_path, val, sizeimg_size) coco80_to_91 data_loader.coco_id80_to_id91 metrics EvalCOCOMetric(cocodata_loader.coco, classes_mappingcoco80_to_91) ie Core() model_ir ie.read_model(modelir_model_xml) compiled_model ie.compile_model(modelmodel_ir, device_nameCPU)其流程为遍历 val2017 → 推理 →non_max_suppression(conf_thres0.001, iou_thres0.6, multi_labelTrue)后处理 →EvalCOCOMetric.update收集预测 → 最后metrics.evaluate()调用 pycocotools 的COCOeval输出标准 COCO 指标汇总IoU metric: bbox及 summarize 结果。EvalCOCOMetric内部会把 YOLOv5 的 80 类索引通过coco80_to_91映射回 COCO 91 类 idutils.py中的coco_id80_to_id91并将模型输出的xyxy坐标转换回 COCO 需要的[x,y,w,h]格式后写入 JSON 再加载评估。九、单图推理predict.py 完整调用链predict.py演示了用 OpenVINO 运行时在 CPU 上对单张图片执行量化前 IR 模型推理的完整调用链图像预处理letterbox(origin_img, img_size, autoFalse)将任意尺寸图像等比例缩放到 640×640 并填充灰边随后转NCHW布局并astype(np.float32)不除 255与mo --scale 255的约定一致模型加载与编译Core().read_model(modelir_model_xml)读取 IRcompile_model(model_ir, device_nameCPU)编译异步推理请求create_infer_request()创建推理请求request.infer(inputs{inputs_names[0]: input_img})执行推理request.get_output_tensor(outputs_names[0].index).data取回输出张量后处理与可视化non_max_suppression(torch.Tensor(result))得到检测框 →scale_coords映射回原图坐标 →draw_box_utils.draw_objs用 80 类名称列表绘制边界框与置信度最终保存predict.jpg。draw_box_utils.py中的draw_objs负责绘制边界框、类别文本如person: 85%等支持自动根据框位置调整文字上/下摆放。十、基准测试benchmark_app 实测对比OpenVINO 自带的benchmark_app可直接对 IR 模型进行同步/异步推理压测。以下实测数据以CPU: Intel(R) Core(TM) i7-6700 CPU 3.40GHz设备为例。FP32 IR 模型量化前benchmark_app -m ir_output/yolov5s.xml -d CPU -api sync输出Latency: Median: 59.56 ms AVG: 63.30 ms MIN: 57.88 ms MAX: 99.89 ms Throughput: 16.79 FPSINT8 量化模型benchmark_app -m quant_ir_output/quantized_yolov5s.xml -d CPU -api sync输出Latency: Median: 42.97 ms AVG: 46.56 ms MIN: 41.18 ms MAX: 95.75 ms Throughput: 23.27 FPS对比结论在同一 CPUi7-6700上INT8 量化后中位延迟由 59.56 ms 降至 42.97 ms降低约 28%吞吐从 16.79 FPS 提升到 23.27 FPS提升约 38.6%。需要说明的是这些数据是本文档所在运行环境的单次实测结果实际收益会因 CPU 架构是否支持 VNNI/AVX-512 等指令、核数、批大小及-apisync/async模式不同而变化请以各自环境的实测为准。若想观察 async 模式或多线程下的吞吐可加-api async或-nstreams等参数。补充compare_fps.py三格式横向对比模块还提供了compare_fps.py用同一张随机图640×640×3分别跑 PyTorchtorch.hub.load(ultralytics/yolov5, yolov5s)、ONNXonnxruntime与 IROpenVINO Runtime各 100 次推理输出每张图的耗时与 FPS并绘制fps_vs.jpg柱状图横轴为 model format纵轴为 fps便于直观对比 PyTorch / ONNX / IR 三种形态在同一 CPU 上的推理性能差异。注意 PyTorch 分支会在线下载权重需要网络可用。十一、一致性校验compare_onnx_and_ir.pycompare_onnx_and_ir.py用于验证 ONNX 导出与 IR 转换未引入数值错误对同一随机输入分别用 onnxruntime 运行yolov5s.onnx输入归一化到 [0,1]和 OpenVINO 运行ir_output/yolov5s.xml输入保持 [0,255]归一化已由--scale 255折叠进 IR然后断言两个输出逐元素接近np.testing.assert_allclose(onnx_res, ir_res, rtol1e-03, atol1e-05) print(Exported model has been tested with OpenvinoRuntime, and the result looks good!)运行通过即说明 ONNX 与 IR 的数值结果一致可放心进入量化环节。十二、使用注意事项总结路径与节点名对齐mo转换参数--input_shape、--scale与quantization_int8.py中的inputs: images、outputs: output必须匹配data_path必须指向包含train2017/val2017/annotations三个子目录的coco2017根目录。量化成本与精度stat_subset_size控制激活统计子集大小默认 300preset可在performance与accuracy之间选择量化前务必用quantization_int8.py或evaluation.py记录原始 IR 的 mAP 基线量化后再对比 INT8 mAP。版本约束整套流程基于 OpenVINO 2022.1.0POT 接口若使用更新的 OpenVINO 版本compression包的导入方式与DefaultQuantization的配置写法可能变化请以对应版本的官方 API 为准。性能数据是环境相关的本文中 FPS/Latency 为文档作者的 i7-6700 CPU 实测不同硬件尤其是支持 VNNI 的现代 CPU上 INT8 加速比会有明显差异建议用benchmark_app在自己的目标设备上重新测量。十三、相关资源索引本仓库中与 OpenVINO 部署相关的其他可参考内容convert_yolov5/requirements.txt完整依赖清单convert_yolov5/quantization_int8.pyPOT 量化主脚本convert_yolov5/utils.py数据加载器、NMS、mAP 指标等公共实现convert_yolov5/evaluation.py量化模型 COCO mAP 独立评测convert_yolov5/predict.py单图推理与结果可视化convert_yolov5/compare_onnx_and_ir.pyONNX 与 IR 输出一致性校验convert_yolov5/compare_fps.pyPyTorch / ONNX / IR 三格式 FPS 对比convert_resnet34/README.md同一套流程在 ResNet34 图像分类模型上的应用示例含--mean_values/--scale_values的预处理写法。赞分享示例工程【免费下载链接】deep-learning-for-image-processingdeep learning for image processing including classification and object-detection etc.项目地址https://gitcode.com/gh_mirrors/de/deep-learning-for-image-processing点击查看免费下载相关推荐基于 OpenVINO 部署 ResNet34从 PyTorch 到 ONNX、IR 格式与 INT8 量化的完整实战指南基于 OpenVINO 部署 ResNet34从 PyTorch 到 ONNX、IR 格式与 INT8 量化的完整实战指南 导读 本文以 deep learn示例工程OpenMed OpenVINO Runtime 指南将临床 NER 的 ONNX 模型导出为 IR、INT8 量化与 Intel CPU/GPU/NPU 端侧推理OpenMed OpenVINO Runtime 指南将临床 NER 的 ONNX 模型导出为 IR、INT8 量化与 Intel CPU/GPU/NPU 端人工智能NLP医疗健康数据脱敏本地部署大模型AI 应用MCP 服务联邦学习Ultralytics ONNX INT8 量化导出解析基于 ONNX Runtime 静态量化的校准与实现指南Ultralytics ONNX INT8 量化导出解析基于 ONNX Runtime 静态量化的校准与实现指南 本指南以 Ultralytics 仓库中的人工智能深度学习计算机视觉预训练上一篇ComfyUI自定义脚本终极指南20功能让AI工作流程效率翻倍下一篇如何快速掌握Scan Tailor面向初学者的完整扫描文档处理指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表