作者:馮浩? ?遼寧科技大學 研究生
1. 引言
1.1?OpenVINO? 簡介
圖 1.1.1 OpenVINO?
OpenVINO?(Open Visual Inference & Neural Network Optimization)是由英特爾開發(fā)的一個開源計算機視覺和深度學習工具套件。它旨在幫助開發(fā)者和研究人員優(yōu)化他們的計算機視覺和深度學習模型,以便在英特爾的硬件平臺上獲得更高的性能。
OpenVINO? 提供了一系列的工具和庫,包括 OpenVINO SDK、OpenVINO API、OpenVINO Tools 等,以支持開發(fā)者和研究人員在英特爾的處理器、GPU、FPGA 等硬件平臺上進行模型的推理和優(yōu)化。OpenVINO? 還提供了對各種深度學習框架的支持,如 TensorFlow、PyTorch、Keras 等,使得開發(fā)者可以輕松地將自己的模型部署到英特爾的硬件平臺上。
OpenVINO? 的設(shè)計目標是提供高性能、高效率和低延遲的視覺智能推理,使得計算機視覺和深度學習模型可以在各種設(shè)備和場景中得到廣泛應用,包括智能城市、智能交通、智能醫(yī)療、智能安防等領(lǐng)域。
OpenVINO? 是一個活躍的開源項目,吸引了眾多的開發(fā)者和研究人員參與其中,不斷地優(yōu)化和完善其功能和性能。
1.2Resnet50 簡介
圖 1.2.1 Resnet
ResNet-50 是一種深度學習模型,屬于卷積神經(jīng)網(wǎng)絡(luò)(CNN)的一種。它是微軟研究院的研究人員于 2015 年提出的一種模型,是 ResNet(殘差網(wǎng)絡(luò))的一種變體。ResNet-50 被廣泛應用于計算機視覺任務中,如圖像分類、目標檢測和語義分割等。
ResNet-50 模型具有 50 層,其中包括 49 個卷積層和 4 個池化層。它采用了殘差學習的思想,即在每一層中添加一個或多個殘差塊,使得模型可以更好地學習圖像的特征。這種設(shè)計使得 ResNet-50 模型可以有效地提取圖像的特征,提高了模型的性能和準確度。
ResNet-50 模型在一些公開的圖像識別數(shù)據(jù)集上取得了很好的成績,如 ImageNet 數(shù)據(jù)集。它也經(jīng)常被用作其他深度學習模型的預訓練模型,用于提取圖像的特征。由于其深度和性能,ResNet-50 模型在計算機視覺領(lǐng)域中被廣泛使用,并且已經(jīng)成為了一種標準的模型之一。
1.3 ffmpeg libraries 簡介
FFmpeg Libraries 是一組強大的開源庫,用于處理視頻和音頻數(shù)據(jù)。它們是 FFmpeg 項目的一部分,提供了一系列的功能,包括音視頻編解碼、格式轉(zhuǎn)換、過濾和播放等。這些庫是用 C 語言編寫的,具有高度的可移植性和效率,可以在多種操作系統(tǒng)和硬件平臺上使用。
FFmpeg Libraries 由于其強大的功能和靈活性,被廣泛應用于視頻播放器、視頻編輯軟件、流媒體服務器、視頻分析工具等項目中。它們是多媒體處理領(lǐng)域的重要工具,對于開發(fā)高質(zhì)量的音視頻應用程序至關(guān)重要。
1.4?文章目的與結(jié)構(gòu)安排
本篇文章將詳細闡述如何使用 Resnet50 模型進行部署,并展示如何利用 OpenVINO? 框架結(jié)合異步推理及零拷貝技術(shù),從而提高 Resnet50 模型的推理速度。此外,為了讓讀者更好地理解和掌握相關(guān)知識,文章還將提供一個典型示例供讀者參考,以便更好地掌握 Resnet50 模型的推理部署方法。
2. 異步推理與零拷貝技術(shù)概述
2.1異步推理的概念與優(yōu)勢
異步推理 (Asynchronous Inference) 顧名思義,也就是在調(diào)用執(zhí)行推理的這個代碼塊的時候并不會等待模型推理的結(jié)束并且阻塞當前的線程,而是直接越過當前需要的等待代碼(類似于 I/O 操作)塊繼續(xù)執(zhí)行下面的代碼。
圖 2.1 異步推理偽代碼圖
一般的 AI 視覺模型推理一般存在三個步驟。其一是預處理,將原始數(shù)據(jù)圖像數(shù)據(jù)進行 resize、letterbox、顏色通道轉(zhuǎn)換(BGR->RGB、RGBA->RGB)、padding 等各種預處理操作以符合模型輸入要求;其二是將預處理好的數(shù)據(jù)傳入后調(diào)用底層的框架進行模型推理;其三是將模型輸出的結(jié)果進行一個后處理(例如解析 raw 數(shù)據(jù)、進行 NMS 等操作)。在多次的對比實驗中我們發(fā)現(xiàn)前面的三個步驟只有第二個耗時最多并且阻塞線程,故我們考慮采用異步推理的模式。
2.2零拷貝技術(shù)的概念與優(yōu)勢
圖 2.2.1 零拷貝原理圖
傳統(tǒng)意義上的零拷貝技術(shù)是指在數(shù)據(jù)傳輸過程中,避免不必要的數(shù)據(jù)復制操作,以提高數(shù)據(jù)傳輸?shù)男?。在計算機系統(tǒng)中,數(shù)據(jù)通常存儲在內(nèi)存中,而在進行輸入輸出(I/O)操作時,數(shù)據(jù)需要在應用程序的地址空間和操作系統(tǒng)內(nèi)核的地址空間之間進行傳遞。零拷貝技術(shù)的目標是盡可能減少或消除這些數(shù)據(jù)拷貝的開銷。
常見的零拷貝應用技術(shù):
1. 用戶空間和內(nèi)核空間的數(shù)據(jù)傳遞:
傳統(tǒng)的 I/O 操作通常涉及將數(shù)據(jù)從用戶空間復制到內(nèi)核空間,或者反之。零拷貝技術(shù)通過直接在用戶空間和內(nèi)核空間之間傳遞指針或描述符,而不是復制數(shù)據(jù),來避免數(shù)據(jù)的多余拷貝。
2. 文件映射(Memory-mapped files):
零拷貝技術(shù)可以通過內(nèi)存映射文件的方式,將文件直接映射到應用程序的地址空間中。這樣,應用程序可以直接在內(nèi)存中訪問文件數(shù)據(jù),而無需進行額外的數(shù)據(jù)復制。
3. 直接內(nèi)存訪問(DMA):
零拷貝技術(shù)可以利用直接內(nèi)存訪問來避免 CPU 的介入,直接在設(shè)備和內(nèi)存之間傳輸數(shù)據(jù)。這減少了 CPU 的拷貝操作,提高了數(shù)據(jù)傳輸?shù)男省?/p>
4. 數(shù)據(jù)發(fā)送和接收緩沖區(qū)的優(yōu)化:
通過優(yōu)化數(shù)據(jù)發(fā)送和接收緩沖區(qū)的管理,可以減少或避免數(shù)據(jù)的復制。例如,通過使用環(huán)形緩沖區(qū)或共享內(nèi)存,可以實現(xiàn)零拷貝。
5. 網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)牧憧截悾?/strong>
在網(wǎng)絡(luò)編程中,零拷貝技術(shù)還可以通過在應用層和傳輸層之間減少或消除數(shù)據(jù)的拷貝來提高性能。這通常涉及使用零拷貝套接字操作或使用專門的網(wǎng)絡(luò)協(xié)議棧。
圖 2.2.2 OpenVINO? With Zero-Copy
首先要理解 OpenVINO? 中的零拷貝技術(shù)就需要介紹一下他的背景應用通常流程。在實際應用的場景中數(shù)據(jù)來源一般是編碼壓縮后的視頻,或者視頻流。
1、首先需要將視頻傳入到 GPU 中的 Video Decoder 單元進行解碼,得到的是每一幀的三通道或者四通道圖像(RGB 、BGRA等);
2、之后再將解碼后的圖像從顯存拷貝到內(nèi)存中;
3、在內(nèi)存中執(zhí)行預處理;
4、再將預處理后的數(shù)據(jù)拷貝到 GPU 顯存中;
5、通知 AI 推理模塊 OpenVINO? 進行模型推理;
6、將推理后的輸出數(shù)據(jù)拷貝回內(nèi)存中;
7、最后對內(nèi)存中的輸出數(shù)據(jù)執(zhí)行后處理。
OpenVINO? 中的零拷貝技術(shù),實質(zhì)上是指省略了第 ② 和 ④ 步的操作,并將第 ③ 步的操作集中在 GPU 設(shè)備中進行,從而減少了兩次不必要的數(shù)據(jù)復制過程。此舉可在一定程度上提升推理速度。
2.3零拷貝技術(shù)在 OpenVINO? 中的實現(xiàn)
2.3.1 零拷貝
首先經(jīng)過 ffmpeg 解碼之后會拿到一個 AVFrame 類型的指針數(shù)據(jù)他保存了解碼之后的一幀圖像的原始數(shù)據(jù),我們可以使用這個指針并且利用 OpenVINO? 的接口獲取創(chuàng)建一個 NVTensor,即是 NV 格式的圖像數(shù)據(jù),這個圖像數(shù)據(jù)就可以直接放入 OpenVINO? 進行推理。
auto id = (VASurfaceID)(std::size_t)frame->data[3];
auto va_context = ov_compiled_model.get_context().as<ov::intel_gpu::ocl::VAContext>();
auto Nvtensor = va_context.create_tensor_nv12(iHeight, iWidth, id);
Infer_request.set_input_tensor(0, nvTensor.first); ? ?// Y plane
Infer_request.set_input_tensor(1, nvTensor.second); ? // UV plane
這樣就完成了數(shù)據(jù)由解碼端傳輸?shù)?OpenVINO? 推理端。詳細代碼可以參考:https://github.com/wxxz975/ZeroCopyWithOpenVINO
如欲了解更多 OpenVINO? 開發(fā)資料,請掃描下方二維碼,我們會把最新資料及時推送給您。