一、OpenVINO 加速 YOLO-V8 CPU 推理
在本专栏的前面几篇文章我们使用YOLO-V8进行了各种任务的实验,但是针对与推理速度一直使用的PyTorch的格式,并且很多情况下也是在CPU上推理的,实际运行速度其实不是非常的理想。而OpenVINO是一款由英特尔推出的深度学习推理引擎,可以帮助开发者高效地在各种硬件平台上部署深度学习模型,特别是英特尔的CPU上,因此本文借助OpenVINO实现对YOLO-V8CPU上的推理加速。
OpenVINO GitHub 地址:https://github.com/openvinotoolkit/openvino
关于YOLO-V8的介绍和使用,可以参考下面这篇文章:
https://xiaobichao.blog.csdn.net/article/details/137140038
本文使用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 |
下面过程使用的依赖版本如下:
ultralytics==8.1.37 opencv-python==4.7.0.68openvino==2024.3.0 openvino-dev==2024.3.0 openvino-telemetry==2024.1.0首先我的设备CPU是一款比较老的i5-10300H,使用yolov8n.pt模型实时推理速度,平均FPS只有8.83,平均每帧模型推理速度0.078s,处理过程如下:
importtimeimportcv2importsupervisionassvfromultralyticsimportYOLOfromsupervision.assetsimportdownload_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()whileTrue:# 循环读取每一帧ret,frame=cap.read()# 由于原视频帧比较大,方便处理和后面展现,缩小一些frame=cv2.resize(frame,(1280,720))ifnotret:breakt=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依赖:
pipinstallopenvino-dev-ihttps://pypi.tuna.tsinghua.edu.cn/simple转换:
fromultralyticsimportYOLO# 加载 YoloV8n 模型,如果不存在会自动下载model=YOLO("yolov8n.pt")# 导出 openvino 模型model.export(format="openvino",imgsz=[640,640])可以在当前目录下看到导出的模型:
使用OpenVINO模型推理:
importtimeimportcv2importsupervisionassvfromultralyticsimportYOLOfromsupervision.assetsimportdownload_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()whileTrue:# 循环读取每一帧ret,frame=cap.read()# 由于原视频帧比较大,方便处理和后面展现,缩小一些frame=cv2.resize(frame,(1280,720))ifnotret:breakt=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。