!作為目標檢測領域著名的模型家族,you only look once (YOLO) 推 出新模型的速度可謂是越來越快。
就在剛剛過去的1月份,YOLO又推出了最新的YOLOv8模型,其模型結構和架構上的創(chuàng)新以及所提供的性能提升,使得它剛剛面世,就獲得了廣大開發(fā)者的關注。
YOLOv8的性能到底怎么樣?如果說利用OpenVINO的量化和加速,利用英特爾CPU、集成顯卡以及獨立顯卡與同一代碼庫無縫協(xié)作,可以獲得1000+ FPS的性能,你相信嗎?
那不妨繼續(xù)往下看,我們將手把手的教你在利用OpenVINO在英特爾處理器上實現(xiàn)這一性能。
| 圖1. YOLOv8推理結果示例 好的,讓我們開始吧。 注意:以下步驟中的所有代碼來自OpenVINO Notebooks開源倉庫中的230-yolov8-optimization notebook 代碼示例。
01安裝相應工具包及加載模型
本次代碼示例我們使用的是Ultralytics YOLOv8模型,因此需要首先安裝相應工具包。
1.!pipinstall"ultralytics==8.0.5"
1.fromultralyticsimportYOLO
2.
3.MODEL_NAME="yolov8n"
4.
5.model=YOLO(f'{MODEL_NAME}.pt')
6.
7.label_map=model.model.names
定義測試圖片的地址,獲得原始PyTorch模型的推理結果:
1.IMAGE_PATH="../data/image/coco_bike.jpg"
2.results=model(IMAGE_PATH,return_outputs=True)
其運行效果如下
?
為將目標檢測的效果以可視化的形式呈現(xiàn)出來,需要定義相應的函數,最終運行效果如下圖所示:
?
02將模型轉換為OpenVINOIR格式
為獲得良好的模型推理加速,并更方便的部署在不同的硬件平臺上,接下來我們首先將YOLO v8模型轉換為OpenVINO IR模型格式。
YOLOv8提供了用于將模型導出到不同格式(包括OpenVINO IR格式)的API。
model.export負責模型轉換。
我們需要在這里指定格式,此外,我們還可以在模型中保留動態(tài)輸入。
1.frompathlibimportPath
2.
3.model_path=Path(f"{MODEL_NAME}_openvino_model/{MODEL_NAME}.xml")
4.ifnotmodel_path.exists():
5.model.export(format="openvino",dynamic=True,half=False)
接下來我們來測試一下轉換后模型的準確度如何。運行以下代碼,并定義相應的前處理、后處理函數。
1.fromopenvino.runtimeimportCore,Model
2.
3.core=Core()
4.ov_model=core.read_model(model_path)
5.device="CPU"#GPU
6.ifdevice!="CPU":
7.ov_model.reshape({0:[1,3,640,640]})
8.compiled_model=core.compile_model(ov_model,device)
在單張測試圖片上進行推理,可以得到如下推理結果:
? ?
03在數據集上驗證模型準確度
YOLOv8是在COCO數據集上進行預訓練的,因此為了評估模型的準確性,我們需要下載該數據集。
根據YOLOv8 GitHub倉庫中提供的說明,我們還需要下載模型作者使用的格式的標注,以便與原始模型評估功能一起使用。
1.importsys
2.fromzipfileimportZipFile
3.
4.sys.path.append("../utils")
5.fromnotebook_utilsimportdownload_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.ifnot(OUT_DIR/"coco/labels").exists():
16.withZipFile(OUT_DIR/'coco2017labels-segments.zip',"r")aszip_ref:
17.zip_ref.extractall(OUT_DIR)
18.withZipFile(OUT_DIR/'val2017.zip',"r")aszip_ref:
19.zip_ref.extractall(OUT_DIR/'coco/images')
接下來,我們配置DetectionValidator并創(chuàng)建DataLoader。原始模型存儲庫使用DetectionValidator包裝器,它表示精度驗證的過程。
它創(chuàng)建DataLoader和評估標準,并更新DataLoader生成的每個數據批的度量標準。
此外,它還負責數據預處理和結果后處理。對于類初始化,應提供配置。
我們將使用默認設置,但可以用一些參數替代,以測試自定義數據,代碼如下。
1.fromultralytics.yolo.utilsimportDEFAULT_CONFIG
2.fromultralytics.yolo.configsimportget_config
3.args=get_config(config=DEFAULT_CONFIG)
4.args.data="coco.yml"
1.validator=model.ValidatorClass(args)
2.
3.data_loader=validator.get_dataloader("datasets/coco",1)
Validator配置代碼如下:
1.fromtqdm.notebookimporttqdm
2.fromultralytics.yolo.utils.metricsimportConfusionMatrix
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
定義驗證函數,以及打印相應測試結果的函數,結果如下: ?
04利用NNCFPOT量化API進行模型優(yōu)化
Neural network compression framework (NNCF) 為OpenVINO中的神經網絡推理優(yōu)化提供了一套先進的算法,精度下降最小。
我們將在后訓練(Post-training)模式中使用8位量化(無需微調)來優(yōu)化YOLOv8。
優(yōu)化過程包括以下三個步驟:
1)建立量化數據集Dataset;
2)運行nncf.quantize來得到優(yōu)化模型
3)使用串行化函數openvino.runtime.serialize來得到OpenVINO IR模型。
建立量化數據集代碼如下:
1.importnncf#noqa:F811
2.fromtypingimportDict
3.
4.
5.deftransform_fn(data_item
6."""
7.Quantizationtransformfunction.Extractsandpreprocessinputdatafromdataloaderitemforquantization.
9.data_item:DictwithdataitemproducedbyDataLoaderduringiteration
10.Returns:
11.input_tensor:Inputdataforquantization
12."""
13.input_tensor=validator.preprocess(data_item)['img'].numpy()
14.returninput_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"],#ignoreoperations
7.names=["/model.22/dfl/conv/Conv",#inthepost-processingsubgraph
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.fromopenvino.runtimeimportserialize
2.int8_model_path=Path(f'{MODEL_NAME}_openvino_int8_model/{MODEL_NAME}.xml')
3.print(f"Quantizedmodelwillbesavedto{int8_model_path}")
4.serialize(quantized_model,str(int8_model_path))
運行后得到的優(yōu)化的YOLOv8模型保存在以下路徑:
yolov8n_openvino_int8_model/yolov8n.xml
接下來,運行以下代碼在單張測試圖片上驗證優(yōu)化模型的推理結果:
1.ifdevice!="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)
運行結果如下:
?
驗證下優(yōu)化后模型的精度,運行如下代碼:
1.print("FP32modelaccuracy")
2.print_stats(fp_stats,validator.seen,validator.nt_per_class.sum())
3.
4.print("INT8modelaccuracy")
5.print_stats(int8_stats,validator.seen,validator.nt_per_class.sum())
得到結果如下:
?
可以看到模型精度相較于優(yōu)化前,并沒有明顯的下降。
05比較優(yōu)化前后模型的性能
接著,我們利用OpenVINO 基線測試工具https://docs.openvino.ai/latest/openvino_inference_engine_tools_benchmark_tool_README.html 來比較優(yōu)化前(FP32)和優(yōu)化后(INT8)模型的性能。
在這里,我們分別在英特爾至強第三代處理器(Xeon Ice Lake Gold Intel 6348 2.6 GHz 42 MB 235W 28 cores)上運行CPU端的性能比較。
針對優(yōu)化前模型的測試代碼和運行結果如下:
1.#InferenceFP32model(OpenVINOIR)
2.!benchmark_app-m$model_path-dCPU-apiasync-shape"[1,3,640,640]"
FP32模型性能:
?
INT8模型性能:
已經達到了1400+ FPS! 在英特爾獨立顯卡上的性能又如何呢?我們在Arc A770m上測試效果如下:
?
也超過了1000 FPS!
需要注意的是要想獲得如此的高性能,需要將推理運行在吞吐量模式下,并使用多流和多個推理請求(即并行運行多個)。
同樣,仍然需要確保對預處理和后處理管道進行微調,以確保沒有性能瓶頸。
06利用網絡攝像頭運行實時測試
除了基線測試工具外,如果你想利用自己的網絡攝像頭,體驗一下實時推理的效果,可以運行我們提供的實時運行目標檢測函數:
1.run_object_detection(source=0,flip=True,use_popup=False,model=ov_model,device="AUTO")
獲得類似如下圖的效果:
?
07進一步提升性能的小技巧
非同步推理流水線
在進行目標檢測的推理時,推理性能常常會因為數據輸入量的限制而受到影響。此時,采用異步推理的模型,可以進一步提升推理的性能。異步API的主要優(yōu)點是,當設備忙于推理時,應用程序可以并行執(zhí)行其他任務(例如填充輸入或調度其他請求),而不是等待當前推理首先完成。
使用預處理API
預處理API允許將預處理作為模型的一部分,從而減少應用程序代碼和對其他圖像處理庫的依賴。預處理API的主要優(yōu)點是將預處理步驟集成到執(zhí)行圖中,并將在選定的設備(CPU/GPU/VPU/等)上執(zhí)行,而不是作為應用程序的一部分始終在CPU上執(zhí)行。這將提高所選設備的利用率。
對于本次YOLOv8示例來說,預處理API的使用包含以下幾個步驟:
1.初始化PrePostProcessing對象
20.fromopenvino.preprocessimportPrePostProcessor
21.
22.ppp=PrePostProcessor(quantized_model)
2.定義輸入數據格式
1.fromopenvino.runtimeimportType,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")))
具有集成預處理的模型已準備好加載到設備?,F(xiàn)在,我們可以跳過檢測函數中的這些預處理步驟,直接運行如下推理:
1.defdetect_without_preprocess(image:np.ndarray,model
2."""
3.OpenVINOYOLOv8modelwithintegratedpreprocessinginferencefunction.Preprocessimage,runsmodelinferenceandpostprocessresultsusingNMS.
4.Parameters:
5.image(np.ndarray):inputimage.
6.model(Model):OpenVINOcompiledmodel.
7.Returns:
8.detections(np.ndarray):detectedboxesinformat[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.returndetections
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)
小 結
整個的步驟就是這樣!現(xiàn)在就開始跟著我們提供的代碼和步驟,動手試試用Open VINO優(yōu)化和加速YOLOv8吧。
審核編輯:劉清
-
處理器
+關注
關注
68文章
19293瀏覽量
229967 -
FPS
+關注
關注
0文章
35瀏覽量
12012 -
pytorch
+關注
關注
2文章
808瀏覽量
13235
原文標題:如何用OpenVINO?讓YOLOv8獲得1000+ FPS性能?
文章出處:【微信號:SDNLAB,微信公眾號:SDNLAB】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論