一、OpenVINO 加速 YOLO-V8 CPU 推理
在本专栏的前面几篇文章我们使用 YOLO-V8
进行了各种任务的实验,但是针对与推理速度一直使用的 PyTorch
的格式,并且很多情况下也是在 CPU
上推理的,实际运行速度其实不是非常的理想。而OpenVINO
是一款由英特尔推出的深度学习推理引擎,可以帮助开发者高效地在各种硬件平台上部署深度学习模型,特别是英特尔的 CPU
上,因此本文借助 OpenVINO
实现对 YOLO-V8
CPU
上的推理加速。
OpenVINO GitHub 地址:https://github.com/openvinotoolkit/openvino
关于 YOLO-V8
的介绍和使用,可以参考下面这篇文章:
本文使用 ultralytics
框架进行实验,而 ultralytics
框架针对格式的转换已经做好了封装,只需要通过 model.export
方法,便可以转到多种不同格式的模型,支持的格式如下:
格式 | format | 模型 | 元数据 | 论据 |
---|---|---|---|---|
PyTorch | - | yolov8n.pt | ✅ | - |
TorchScript | torchscript | yolov8n.torchscript | ✅ | imgsz, optimize, batch |
ONNX | onnx | yolov8n.onnx | ✅ | imgsz, half, dynamic, simplify, opset, batch |
OpenVINO | openvino | yolov8n_openvino_model/ | ✅ | imgsz, half, int8, batch |
TensorRT | engine | yolov8n.engine | ✅ | imgsz, half, dynamic, simplify, workspace, int8, batch |
CoreML | coreml | yolov8n.mlpackage | ✅ | imgsz, half, int8, nms, batch |
TF SavedModel | saved_model | yolov8n_saved_model/ | ✅ | imgsz, keras, int8, batch |
TF GraphDef | pb | yolov8n.pb | ❌ | imgsz, batch |
TF 轻型 | tflite | yolov8n.tflite | ✅ | imgsz, half, int8, batch |
TF 边缘TPU | edgetpu | yolov8n_edgetpu.tflite | ✅ | imgsz |
TF.js | tfjs | yolov8n_web_model/ | ✅ | imgsz, half, int8, batch |
PaddlePaddle | paddle | yolov8n_paddle_model/ | ✅ | imgsz, batch |
NCNN | ncnn | yolov8n_ncnn_model/ | ✅ | imgsz, half, batch |
下面过程使用的依赖版本如下:
shell
ultralytics==8.1.37
opencv-python==4.7.0.68
openvino==2024.3.0
openvino-dev==2024.3.0
openvino-telemetry==2024.1.0
首先我的设备 CPU
是一款比较老的 i5-10300H
,使用 yolov8n.pt
模型实时推理速度,平均 FPS
只有 8.83
,平均每帧模型推理速度 0.078s
,处理过程如下:
python
import time
import cv2
import supervision as sv
from ultralytics import YOLO
from supervision.assets import download_assets, VideoAssets
# 如果不存在则下载视频
video_name = download_assets(VideoAssets.VEHICLES)
# 加载 YoloV8n 模型,如果不存在会自动下载
model = YOLO("yolov8n.pt")
# 初始化展现对象
corner_annotator = sv.BoxCornerAnnotator(
corner_length=15,
thickness=2,
color=sv.Color(r=255, g=255, b=0)
)
# 读取视频
cap = cv2.VideoCapture(video_name)
# 初始化计时器
prev_tick = cv2.getTickCount()
while True:
# 循环读取每一帧
ret, frame = cap.read()
# 由于原视频帧比较大,方便处理和后面展现,缩小一些
frame = cv2.resize(frame, (1280, 720))
if not ret:
break
t = time.time()
result = model(
frame,
device="cpu"
)[0]
use_time = time.time() - t
detections = sv.Detections.from_ultralytics(result)
# 绘制边框
frame = corner_annotator.annotate(frame, detections=detections)
# 计算帧率
current_tick = cv2.getTickCount()
fps = cv2.getTickFrequency() / (current_tick - prev_tick)
prev_tick = current_tick
cv2.putText(frame, ("FPS: {:.2f}".format(fps)) + ", USE_TIME: " + str(use_time), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1,
(0, 255, 0), 2)
cv2.imshow('video', frame)
cv2.waitKey(1)
下面将 yolov8n.pt
模型转为 OpenVINO
格式:
需要添加 openvino
依赖:
shell
pip install openvino-dev -i https://pypi.tuna.tsinghua.edu.cn/simple
转换:
python
from ultralytics import YOLO
# 加载 YoloV8n 模型,如果不存在会自动下载
model = YOLO("yolov8n.pt")
# 导出 openvino 模型
model.export(format="openvino", imgsz=[640,640])
可以在当前目录下看到导出的模型:
使用 OpenVINO
模型推理:
python
import time
import cv2
import supervision as sv
from ultralytics import YOLO
from supervision.assets import download_assets, VideoAssets
# 如果不存在则下载视频
video_name = download_assets(VideoAssets.VEHICLES)
model = YOLO("yolov8n_openvino_model")
# 初始化展现对象
corner_annotator = sv.BoxCornerAnnotator(
corner_length=15,
thickness=2,
color=sv.Color(r=255, g=255, b=0)
)
# 读取视频
cap = cv2.VideoCapture(video_name)
# 初始化计时器
prev_tick = cv2.getTickCount()
while True:
# 循环读取每一帧
ret, frame = cap.read()
# 由于原视频帧比较大,方便处理和后面展现,缩小一些
frame = cv2.resize(frame, (1280, 720))
if not ret:
break
t = time.time()
result = model(
frame,
device="cpu"
)[0]
use_time = time.time() - t
detections = sv.Detections.from_ultralytics(result)
# 绘制边框
frame = corner_annotator.annotate(frame, detections=detections)
# 计算帧率
current_tick = cv2.getTickCount()
fps = cv2.getTickFrequency() / (current_tick - prev_tick)
prev_tick = current_tick
cv2.putText(frame, ("FPS: {:.2f}".format(fps)) + ", USE_TIME: " + str(use_time), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1,
(0, 255, 0), 2)
cv2.imshow('video', frame)
cv2.waitKey(1)
可以明显看到 FPS
由原先的 8.83
提高到 14.26
,模型推理处理速度由之前 0.078s
降低到 0.039s
。