YOLOv8优化与量化(1000+ FPS性能)

YOLO家族又添新成员了!作为目标检测领域著名的模型家族,you only look once (YOLO) 推 出新模型的速度可谓是越来越快。就在刚刚过去的1月份,YOLO又推出了最新的YOLOv8模型,其模型结构和架构上的创新以及所提供的性能提升,使得它刚刚面世,就获得了广大开发者的关注。

YOLOv8的性能到底怎么样?如果说利用OpenVINO™的量化和加速,利用英特尔®CPU、集成显卡以及独立显卡与同一代码库无缝协作,可以获得1000+ FPS的性能,你相信吗?那不妨继续往下看,我们将手把手的教你在利用OpenVINO™在英特尔®处理器上实现这一性能。

好的,让我们开始吧。

注意:以下步骤中的所有代码来自OpenVINO Notebooks开源仓库中的230-yolov8-optimization notebook 代码示例,您可以点击以下链接直达源代码。openvino_notebooks/230-yolov8-optimization.ipynb at main · openvinotoolkit/openvino_notebooks · GitHub

第一步: 安装相应工具包及加载模型

本次代码示例我们使用的是Ultralytics YOLOv8模型,因此需要首先安装相应工具包。

!pip install "ultralytics==8.0.5"

然后下载及加载相应的PyTorch模型。

1. from ultralytics import YOLO

2.

3. MODEL_NAME = "yolov8n"

4. model = YOLO(f'{MODEL_NAME}.pt')

5. label_map = model.model.names

定义测试图片的地址,获得原始PyTorch模型的推理结果

1. IMAGE_PATH = "../data/image/coco_bike.jpg"

2. results = model(IMAGE_PATH, return_outputs=True)

其运行效果如下

为将目标检测的效果以可视化的形式呈现出来,需要定义相应的函数,最终运行效果如下图所示

第二步: 将模型转换为OpenVINO IR格式

 为获得良好的模型推理加速,并更方便的部署在不同的硬件平台上,接下来我们首先将YOLO v8模型转换为OpenVINO IR模型格式。YOLOv8提供了用于将模型导出到不同格式(包括OpenVINO IR格式)的API。model.export负责模型转换。我们需要在这里指定格式,此外,我们还可以在模型中保留动态输入。

1. from pathlib import Path

2.

3. model_path = Path(f"{MODEL_NAME}_openvino_model/{MODEL_NAME}.xml")

4. if not model_path.exists():

5. model.export(format="openvino", dynamic=True, half=False)

接下来我们来测试一下转换后模型的准确度如何。运行以下代码,并定义相应的前处理、后处理函数,

1. from openvino.runtime import Core, Model

2.

3. core = Core()

4. ov_model = core.read_model(model_path)

5. device = "CPU" # GPU

6. if device != "CPU":

7. ov_model.reshape({0: [1, 3, 640, 640]})

8. compiled_model = core.compile_model(ov_model, device)

在单张测试图片上进行推理,可以得到如下推理结果

第三步: 在数据集上验证模型准确度 

YOLOv8是在COCO数据集上进行预训练的,因此为了评估模型的准确性,我们需要下载该数据集。根据YOLOv8 GitHub仓库中提供的说明,我们还需要下载模型作者使用的格式的标注,以便与原始模型评估功能一起使用。

1. import sys

2. from zipfile import ZipFile

3.

4. sys.path.append("../utils")

5. from notebook_utils import download_file

6.

7. DATA_URL = "http://images.cocodataset.org/zips/val2017.zip"

8. LABELS_URL = "https://github.com/ultralytics/yolov5/releases/download/v1.0/coco2017labels-segments.zip"

9.

10. OUT_DIR = Path('./datasets')

11.

12. download_file(DATA_URL, directory=OUT_DIR, show_progress=True)

13. download_file(LABELS_URL, directory=OUT_DIR, show_progress=True)

14.

15. if not (OUT_DIR / "coco/labels").exists():

16. with ZipFile(OUT_DIR / 'coco2017labels-segments.zip' , "r") as zip_ref:

17. zip_ref.extractall(OUT_DIR)

18. with ZipFile(OUT_DIR / 'val2017.zip' , "r") as zip_ref:

19. zip_ref.extractall(OUT_DIR / 'coco/images')

接下来,我们配置DetectionValidator并创建DataLoader。原始模型存储库使用DetectionValidator包装器,它表示精度验证的过程。它创建DataLoader和评估标准,并更新DataLoader生成的每个数据批的度量标准。此外,它还负责数据预处理和结果后处理。对于类初始化,应提供配置。我们将使用默认设置,但可以用一些参数替代,以测试自定义数据,代码如下。

1. from ultralytics.yolo.utils import DEFAULT_CONFIG

2. from ultralytics.yolo.configs import get_config

3. args = get_config(config=DEFAULT_CONFIG)

4. args.data = "coco.yml"


5. validator = model.ValidatorClass(args)

6. data_loader = validator.get_dataloader("datasets/coco", 1)

Validator配置代码如下

1. from tqdm.notebook import tqdm

2. from ultralytics.yolo.utils.metrics import ConfusionMatrix

3.

4. validator.is_coco = True

5. validator.class_map = ops.coco80_to_coco91_class()

6. validator.names = model.model.names

7. validator.metrics.names = validator.names

8. validator.nc = model.model.model[-1].nc

定义验证函数,以及打印相应测试结果的函数,结果如下

第四步: 利用NNCF POT 量化 API进行模型优化 

Neural network compression framework (NNCF) 为OpenVINO中的神经网络推理优化提供了一套先进的算法,精度下降最小。我们将在后训练(Post-training)模式中使用8位量化(无需微调)来优化YOLOv8。

优化过程包括以下三个步骤:

  1. 建立量化数据集Dataset;
  2. 运行nncf.quantize来得到优化模型
  3. 使用串行化函数openvino.runtime.serialize来得到OpenVINO IR模型。

建立量化数据集代码如下

1. import nncf # noqa: F811

2. from typing import Dict

3.

4.

5. def transform_fn(data_item:Dict):

6. """

7. Quantization transform function. Extracts and preprocess input data from dataloader item for quantization.

8. Parameters:

9. data_item: Dict with data item produced by DataLoader during iteration

10. Returns:

11. input_tensor: Input data for quantization

12. """

13. input_tensor = validator.preprocess(data_item)['img'].numpy()

14. return input_tensor

15.

16.

17. quantization_dataset = nncf.Dataset(data_loader, transform_fn)

运行nncf.quantize代码如下

1. quantized_model = nncf.quantize(

2. ov_model,

3. quantization_dataset,

4. preset=nncf.QuantizationPreset.MIXED,

5. ignored_scope=nncf.IgnoredScope(

6. types=["Multiply", "Subtract", "Sigmoid"], # ignore operations

7. names=["/model.22/dfl/conv/Conv", # in the post-processing subgraph

8. "/model.22/Add",

9. "/model.22/Add_1",

10. "/model.22/Add_2",

11. "/model.22/Add_3",

12. "/model.22/Add_4",

13. "/model.22/Add_5",

14. "/model.22/Add_6",

15. "/model.22/Add_7",

16. "/model.22/Add_8",

17. "/model.22/Add_9",

18. "/model.22/Add_10"]

19. ))

最终串行化函数代码如下

1. from openvino.runtime import serialize

2. int8_model_path = Path(f'{MODEL_NAME}_openvino_int8_model/{MODEL_NAME}.xml')

3. print(f"Quantized model will be saved to {int8_model_path}")

4. serialize(quantized_model, str(int8_model_path))

运行后得到的优化的YOLOv8模型保存在以下路径

yolov8n_openvino_int8_model/yolov8n.xml

接下来,运行以下代码在单张测试图片上验证优化模型的推理结果

1. if device != "CPU":

2. quantized_model.reshape({0, [1, 3, 640, 640]})

3. quantized_compiled_model = core.compile_model(quantized_model, device)

4. input_image = np.array(Image.open(IMAGE_PATH))

5. detections = detect(input_image, quantized_compiled_model)[0]

6. image_with_boxes = draw_boxes(detections, input_image)

7.

8. Image.fromarray(image_with_boxes)

运行结果如下

验证下优化后模型的精度,运行如下代码:

1. print("FP32 model accuracy")

2. print_stats(fp_stats, validator.seen, validator.nt_per_class.sum())

3.

4. print("INT8 model accuracy")

5. print_stats(int8_stats, validator.seen, validator.nt_per_class.sum())

 得到结果如下:

可以看到模型精度相较于优化前,并没有明显的下降。

第五步: 比较优化前后模型的性能

 接着,我们利用OpenVINO 基线测试工具Benchmark Python Tool — OpenVINO™ documentation 来比较优化前(FP32)和优化后(INT8)模型的性能。在这里,我们分别在英特尔®至强®第三代处理器(Xeon Ice Lake Gold Intel 6348 2.6 GHz 42 MB 235W 28 cores)上运行CPU端的性能比较。针对优化前模型的测试代码和运行结果如下

1. # Inference FP32 model (OpenVINO IR)

2. !benchmark_app -m $model_path -d CPU -api async -shape "[1,3,640,640]"

FP32模型性能:

INT8模型性能:

已经达到了1400+ FPS!

在英特尔®独立显卡上的性能又如何呢?我们在Arc™ A770m上测试效果如下:

 

也超过了1000 FPS

需要注意的是要想获得如此的高性能,需要将推理运行在吞吐量模式下,并使用多流和多个推理请求(即并行运行多个)。同样,仍然需要确保对预处理和后处理管道进行微调,以确保没有性能瓶颈。

第六步: 利用网络摄像头运行实时测试 

 除了基线测试工具外,如果你想利用自己的网络摄像头,体验一下实时推理的效果,可以运行我们提供的实时运行目标检测函数

1.	run_object_detection(source=0, flip=True, use_popup=False, model=ov_model, device="AUTO")

第七步: 进一步提升性能的小技巧

  • 非同步推理流水线 :在进行目标检测的推理时,推理性能常常会因为数据输入量的限制而受到影响。此时,采用异步推理的模型,可以进一步提升推理的性能。异步API的主要优点是,当设备忙于推理时,应用程序可以并行执行其他任务(例如填充输入或调度其他请求),而不是等待当前推理首先完成。要了解如何使用openvino执行异步推理,请参阅AsyncAPI教程https://github.com/openvinotoolkit/openvino_notebooks/blob/97f25b16970b6fe2287ca47bba64f31cff98e795/notebooks/115-async-api/115-async-api.ipynb
  • 使用预处理API: 预处理API允许将预处理作为模型的一部分,从而减少应用程序代码和对其他图像处理库的依赖。预处理API的主要优点是将预处理步骤集成到执行图中,并将在选定的设备(CPU/GPU/VPU/等)上执行,而不是作为应用程序的一部分始终在CPU上执行。这将提高所选设备的利用率。更详细的预处理API信息,请参阅预处理教程 Optimize Preprocessing — OpenVINO™ documentation 。

对于本次YOLOv8示例来说,预处理API的使用包含以下几个步骤:

  1. 初始化PrePostProcessing对象
1. from openvino.preprocess import PrePostProcessor

2.

3. ppp = PrePostProcessor(quantized_model)

     2. 定义输入数据格式

1. from openvino.runtime import Type, Layout

2.

3. ppp.input(0).tensor().set_shape([1, 640, 640, 3]).set_element_type(Type.u8).set_layout(Layout('NHWC'))

4. pass

    3. 描述预处理步骤

        预处理步骤主要包括以下三步:

  • 将数据类型从U8转换为FP32
  • 将数据布局从NHWC转换为NCHW格式
  • 通过按比例因子255进行除法来归一化每个像素

代码如下:

1. ppp.input(0).preprocess().convert_element_type(Type.f32).convert_layout(Layout('NCHW')).scale([255., 255., 255.])

2.

3. print(ppp)

    4. 将步骤集成到模型中

1. quantized_model_with_preprocess = ppp.build()

2. serialize(quantized_model_with_preprocess, str(int8_model_path.with_name(f"{MODEL_NAME}_with_preprocess.xml")))

具有集成预处理的模型已准备好加载到设备。现在,我们可以跳过检测函数中的这些预处理步骤,直接运行如下推理

1. def detect_without_preprocess(image:np.ndarray, model:Model):

2. """

3. OpenVINO YOLOv8 model with integrated preprocessing inference function. Preprocess image, runs model inference and postprocess results using NMS.

4. Parameters:

5. image (np.ndarray): input image.

6. model (Model): OpenVINO compiled model.

7. Returns:

8. detections (np.ndarray): detected boxes in format [x1, y1, x2, y2, score, label]

9. """

10. output_layer = model.output(0)

11. img = letterbox(image)[0]

12. input_tensor = np.expand_dims(img, 0)

13. input_hw = img.shape[:2]

14. result = model(input_tensor)[output_layer]

15. detections = postprocess(result, input_hw, image)

16. return detections

17.

18.

19. compiled_model = core.compile_model(quantized_model_with_preprocess, device)

20. input_image = np.array(Image.open(IMAGE_PATH))

21. detections = detect_without_preprocess(input_image, compiled_model)[0]

22. image_with_boxes = draw_boxes(detections, input_image)

23.

24. Image.fromarray(img_with_boxes)

由此推理速度又能进一步得到提升啦。

总结:

整个的步骤就是这样!现在就开始跟着我们提供的代码和步骤,动手试试用Open VINO优化和加速YOLOv8吧。

关于英特尔OpenVINOTM开源工具套件的详细资料,包括其中我们提供的三百多个经验证并优化的预训练模型的详细资料,请您点击https://www.intel.com/content/www/us/en/developer/tools/openvino-toolkit/overview.html

除此之外,为了方便大家了解并快速掌握OpenVINOTM的使用,我们还提供了一系列开源的Jupyter notebook demo。运行这些notebook,就能快速了解在不同场景下如何利用OpenVINOTM实现一系列、包括计算机视觉、语音及自然语言处理任务。OpenVINOTM notebooks的资源可以在Github这里下载安装:https://github.com/openvinotoolkit/openvino_notebooks 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/161443.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电子电器架构 —— 车载网关边缘节点路由转发策略

电子电器架构 —— 车载网关边缘节点路由转发策略 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 PS:小细节,本文字数5000+,详细描述了网关在车载框架中的具体性能设置。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无…

035、目标检测-物体和数据集

之——物体检测和数据集 目录 之——物体检测和数据集 杂谈 正文 1.目标检测 2.目标检测数据集 3.目标检测和边界框 4.目标检测数据集示例 杂谈 目标检测是计算机视觉中应用最为广泛的,之前所研究的图片分类等都需要基于目标检测完成。 在图像分类任务中&am…

动手学深度学习——循环神经网络的从零开始实现(原理解释+代码详解)

文章目录 循环神经网络的从零开始实现1. 独热编码2. 初始化模型参数3. 循环神经网络模型4. 预测5. 梯度裁剪6. 训练 循环神经网络的从零开始实现 从头开始基于循环神经网络实现字符级语言模型。 # 读取数据集 %matplotlib inline import math import torchfrom torch import …

机器学习算法——集成学习

目录 1. Bagging 1. Bagging Bagging(bootstrap aggregating:自举汇聚法)也叫装袋法,其思想是通过将许多相互独立的学习器的结果进行结合,从而提高整体学习器的泛化能力,是一种并行集成学习方法。 工作流…

计算机msvcp120.dll丢失?msvcp120.dll丢失5种简单的解决方法分享

你们是否在电脑操作过程中常看到一段类似“msvcp120.dll缺失或损坏”的报错信息?这可能会干扰大家的日常应用程序使用,怎么办呢?别担心,接下来就是一篇详细的步骤来教你如何应对这种情况,让你们的电脑运作如初&#xf…

Cadence virtuoso drc lvs pex 无法输入

问题描述:在PEX中的PEX options中 Ground node name 无法输入内容。 在save runset的时候也出现无法输入名称的情况 解决办法: copy一个.bashrc文件到自己的工作目录下 打开.bashrc文件 在.bashrc中加一行代码:unset XMODIFIERS 在终端sour…

无需API开发,伯俊科技实现电商与客服系统的无缝集成

伯俊科技的无代码开发实现系统连接 自1999年成立以来,伯俊科技一直致力于为企业提供全渠道一盘货的服务。凭借其24年的深耕零售行业的经验,伯俊科技推出了一种无需API开发的方法,实现电商系统和客服系统的连接与集成。这种无代码开发的方式不…

【Proteus仿真】【STM32单片机】防火防盗GSM智能家居设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器,使用声光报警模块、LCD1602显示模块、DS18B20温度、烟雾传感器模块、按键模块、PCF8591 ADC模块、红外检测模块等。 主要功能: 系统运行…

Linux--初识和几个简单的指令(1)

目录 前言 0.什么是操作系统 0.1 搭建 Linux 环境 0.2搭建 Linux 环境小结 1.使用 XShell 远程登录 Linux 1.1关于 Linux 桌面 1.2下载安装 XShell 1.3查看 Linux 主机 ip 1.4XShell 下的复制粘贴 2.Linux下基本指令 2.1 pwd命令 2.2 ls命令 2.3 mkdir指令 2.4 cd…

vue2项目封装axios(vite打包)

1.安装 npm i axios 2.封装axios 说明:request.js文件 //对axios进行二次封装 import axios from "axios" import "nprogress/nprogress.css"// 当前模块中引入store // import store from "/store"// 引入进度条import nprogress f…

【C++】泛型编程 ⑥ ( 类模板 | 类模板语法 | 代码示例 )

文章目录 一、类模板1、类模板引入2、声明类模板语法3、调用类模板语法 二、代码示例 - 类模板1、代码示例2、执行结果 一、类模板 1、类模板引入 类模板 与 函数模板 的 作用类似 , 当 多个类 功能相同 , 只是数据类型不同 , 此时可以 定义一个类模板 代替 定义多个类 ; 借助…

Python (十) 元组

元组 元组与列表类似,不同之处在于元组的元素不能修改。 元组使用小括号 ( ),列表使用方括号 [ ]。 元组创建只需要在括号中添加元素,并使用逗号隔开即可。 访问 tup1 (hello,Java,Python,123,456) print(type(tup1)) print(tup1[1])#输出 …

微信个人号api

简要描述: 登录E云平台 请求URL: http://域名地址/member/login域名地址开发者账号密码:后台系统自助开通 请求方式: POST 请求头Headers: Content-Type:application/json 参数: 参数名必选类型说…

F. Alex‘s whims Codeforces Round 909 (Div. 3) 1899F

Problem - F - Codeforces 题目大意:有q次询问,每次询问给出一个数x,要求构造一棵n个点的树,使得对于每次询问,树上都有一条简单路径的长度等于x,同时每次询问前可以对树进行一次操作,即将一个…

ForkLift:macOS文件管理器/FTP客户端

ForkLift 是一款macOS下双窗口的文件管理器,可以代替本地的访达。ForkLift同时具备连接Ftp、SFtp、WebDav以及云服务器。 ForkLift还具备访达不具备的小功能,比如从文件夹位置打开终端,显示隐藏文件,制作替换等功能。ForkLift 是一…

css继承属性

在css中,继承是指的是给父元素设置一些属性,后代元素会自动拥有这些属性 关于继承属性,可以分成: 字体系列属性文本系列属性元素可见性表格布局属性列表属性引用光标属性 继承中比较特殊的几点: a 标签的字体颜色不…

Python采集智联招聘网站数据实现可视化数据

嗨喽~大家好呀,这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 环境使用: Python Pycharm模块使用: selenium --> pip install selenium3.141.0 time csv驱动下载地址: https://googlechromelabs.github.io/chrome-for-te…

MATLAB中std函数用法

目录 语法 说明 示例 矩阵列的标准差 三维数组的标准差 指定标准差权重 矩阵行的标准差 数组页的标准差 排除缺失值的标准差 标准差和均值 标准差 std函数的功能是得到标准差。 语法 S std(A) S std(A,w) S std(A,w,"all") S std(A,w,dim) S std(A…

ExcelBDD PHP Guideline

在PHP里面支持利用Excel的BDD,也支持利用Excel进行参数化测试 ExcelBDD Use Excel file as BDD feature file, get example data from Excel files, support automation tests. Features The main features provided by this library are: Read test data acco…

1334. 阈值距离内邻居最少的城市/Floyd 【leetcode】

1334. 阈值距离内邻居最少的城市 有 n 个城市,按从 0 到 n-1 编号。给你一个边数组 edges,其中 edges[i] [fromi, toi, weighti] 代表 fromi 和 toi 两个城市之间的双向加权边,距离阈值是一个整数 distanceThreshold。 返回能通过某些路径…