2022年8月1日 星期一

OpenVINO 2022大改版讓Edge AI玩出新花樣


一般採用深度學習(Deep Learning, DL)方式的人工智慧(Artificial intelligence, AI)應用,在開發時須經過資料收集標註、模型選用訓練及最後部署到指定硬體進行推論工作。在訓練模型參數過程需經過數千到數萬次的推論才能使得參數最後收歛到足夠高的推論精度,而這項工作是須要耗費大量算力,所以通常會選用算力較高的硬體裝置(如GPU, TPU, FPGA)來完成。當完成訓練後,推論只需執行一次便可得到結果,明顯可看出算力需求的差異。若推論時仍採用訓練時的裝置,雖可得到極佳的推論效能及無痛移轉部署,但所需的硬體成本也會連帶提升數十到數百倍,更不要說硬體裝置龐大的體積及功耗,所以很難適用到大部份的邊緣智能(Edge AI)應用。通常邊緣智能應用有獨立性(不連網)、低延時、高隱私、低成本、低功耗及大量部署的特性,換句話說,其硬體效能可能就像腳踏車、機車,遠遠不如訓練模型用有如高鐵甚至飛機般高效能的硬體。因此如何將訓練好的模型經過適當的優化、減量及部署到不同的可推論硬體裝置就變成另一項重要課題。



為了讓邊緣智能應用能以更輕量、更彈性地將訓練好的模型部署到各種邊緣裝置上進行推論,2018年5月Intel推出了OpenVINO toolkit (Open Visual Inference and Neural network Optimization,以下簡稱OpenVINO)。這項工具包不僅協助開發者解決不同AI開發框架(如TensorFlow, PyTorch, Mxnet, Caffe …)產生的模型導入,同時將模型轉換成統一的中介表達格式(Intermediate Representation, IR, 模型結構XML檔加模型權重BIN檔),方便推論引擎(Inference Engine)在自家的各種硬體(CPU, GPU, iGPU, FPGA, VPU)進行推論,如此就不必為了部署在不同硬體上要重新開發問題。

Intel OpenVINO從2018年5月(2018 RC5)問世直至2022年3月(2022.1版),已更新了16版次,期間支援了更多的硬體(如Intel Iris Xe GPU等)、框架(如PaddlePaddle, ONNX等)、模型(包含Intel’s Pre-Trained, Public Pre-Trained / Open Model Zoo等)並提供了更多的應用範例(如Samples, Jupyter Notebook Turotials等),而2022.1版則是這三年半來最大幅度的更新。此次更新包含如下幾大亮點,接下來就幫大家簡單盤點一下,如果需要更完整的訊息,可參見官方釋出的說明文件[2]。

  • 提供更多樣便捷的安裝方式
  • 支援更多類型硬體及異構推論
  • 增加更多預訓練模型及公開模型庫
  • 更簡潔有力的API程式開發
  • 模型優化參數簡化及自動化
  • 部署時更智能管理硬體裝置


*提供更多樣便捷的安裝方式


在OpenVINO 2021.4版本之前,本來就有支援多種作業系統(如Linux, Windows, macOS, Raspbian等)及多種安裝方式(Installer, PIP, Docker, Conda, APT, YUM等)。安裝時亦會將相關工具(如Model Optimizer, Benchmark Tool, Accuracy Checker and Annotation Converter, Post-Training Optimization Tool, Model Downloader and other Open Model Zoo Tools等)、相依套件(如OpenCV, OpenCL, DL Streamer, oneVPL等)一起安裝。雖然這樣很方便開發,但在部署時就會變得太龐雜,且佔用很多安裝空間。

所以如Fig. 1所示,在2022.1版時除保留原先多樣性的安裝彈性外,更加入PyPl來源的安裝方式,讓使用Python開發環境的朋友能更容易安裝OpenVINO。同時也將運行所需基礎元件(OpenVINO Runtime)和開發工具採用分開安裝方式,方便部署時能節省時間及空間。如果您是OpenVINO的高手,總是想嚐試在官方正式釋出前的最新版本,那亦可直接從Github上下載,自行編譯。不過開源的版本並不包含FPGA相關內容,須等官方正式釋出。更完整的操作程序可參見官方說明文件[3]。

另外如果您是Python的使用者,從這個版本開始就可支援Python 3.9,可更方便使用Python相關套件包。

 

Fig. 1 OpenVINO新舊版本安裝差異。(OmniXRI整理製作,2022/7/20)


*支援更多類型硬體及異構推論


OpenVINO自2018年推出後,其中透過推論引擎外掛(Inference Engine Plugin)不用重寫程式即可支援自家的各種硬體來進行推論成為最大亮點,其中包括Intel Core / Atom / Xeon CPU(AVX512 / AVX2 / SSE加速運算指令集)、iGPU(Intel HD Graphics, Iris內顯繪圖晶片)、FPGA(原Altera,現為Intel Arria 10 GX)、VPU(原Movidius,現為Intel NSC Myriad 2, NSC2 Myriad X神經加速運算棒)及GNA(高斯神經加速器 內建於Pentium Sliver J5005, Celeron J4005, Core i3-8121U等)。

這幾年又陸續加入更多的Plugin,如HDDL(即多個VPU)、Heterogeneous異構運算(即同時可使用多種硬體協同運算)[等。此次2022.1版更是加入對Intel最新的獨立顯卡GPU的支援,包括Xe, Xe Pro系列,大大提升推論速度。對於Intel 11及12代CPU而言,更加入對AVX512-VNNI, AVX512_BF16指令集的支援,同時亦有支援CPU內建的GPU Iris Xe,使得CPU的運算變得更有效率。如果您想把主機上所有可用運算資源榨乾的話,讓多種裝置同時幫忙運算推論,那這兩篇文章[4][5]就值得您多花點時間研究。其它更多的部署推論裝置說明可參考官方說
明文件[6]。

*增加更多預訓練模型及公開模型庫


OpenVINO為了讓大家更容易上手,從2018推出後就有提供很多範例程式(Samples, Demos, Inference Engine Samples)、Intel預訓練模型(Intel’s Pre-Trained Models)、公開預訓練模型 / 開源模型動物園(Public Pre-Trained Models / Open Model Zoo)。2021.4版後將上述內容從Resource分項中重新整合到Model Zoo分項中,並增加以Jupyter Notebooks型式的Tutorials分項範例程式,讓大家能更了解每個程式段的用法及快速體驗運行推論結果。同時增加了許多循環神經網路(Recurrent neural network, RNN)相關模型,如LSTM、語音辨識、自然語言處理
(Natural Language Processing, NLP)等。

此次2022.1版,將原有的Open Model Zoo Demos移除(需分開安裝),並新增了許多模型,如人臉特徵、英文手寫辨識、英文文字辨識、人員偵測、物件偵測、機器翻譯、背景摳圖、文字預測、影像語義分割、語音辨識等。其中包括Intel預訓練模型16項及公開預訓練模型15項。另外Jupyter Notebook Tutorials亦新增9個範例,包含人體動作辨識、訓後量化(Post-Training Quantization)、手寫辨識、語音變文字、自然語言問答等,如Fig. 2所示。


Fig. 2 OpenVINO 2022.1新增模型及教程。(OmniXRI參考[2]整理製作, 2022/7/20)


*更簡潔有力的API程式開發


在OpenVINO 2021.4(含)以前的版本,在推論前首先將模型轉成中介表示(IR, XML+BIN)檔,接著使用推論引擎(Inference Engine, IE)配合指定的硬體外掛(Plugins)來執行相關程式。而此次2022.1版在推論流程上有重大改革,將原先的繁雜的推論引擎改為單一運行庫(OpenVINO Runtime, OV),並大幅簡化API的呼叫方式,如Fig.3 上方所示。

如Fig. 3左側下方所示,舊版(2021.4)的推論程序為初始化核心InferenceEngine::Core及相關配套程式庫,依需求配置所需的輸出入項目,接著載入模型,建立推論結果要求,待準備好輸入(GetBlob)後就可以開始進行推論,最後再將結果轉回可應用於後端程式的格式,即可完成一次推論。若有大量內容須要推論時,則前面四個步驟可略過,只需反覆後面三個步驟直到全部完成。

如Fig.3右側下方所示,為此次2022.1版的推論流程,可發現和舊版有很大不一樣。首先初始化改成只需配置單一ov::Core即可,不用再配置其它。接著使用ov::CompiledModel來處理載入模型及對應推論硬體,這裡預設可使用AUTO參數來進行推論硬體自動化偵測及配置。接著同樣地建立推論結果要求,設置輸入內容。這裡改用ov::Tensor來取代原來的Blob用法,這樣會更接近主流模型框架的描述方式。取得輸入內容後就可開始進行推論,最後得到輸出結果,經簡單處理後就可轉換到後續程式使用。同樣地,若需大量推論時,只須反覆最後三個步驟即可。

 

Fig. 3 新舊版本執行推論流程比較。(OmniXRI整理製作, 2022/7/20)


為了讓大家更清楚比較新舊版本的API程式寫作差異,這裡以C++為例,表列於Fig. 4。左側為2021.4版[7]、右側為2022.1版[8](API 2.0),可明顯看出新版在程式開發清爽多了。如果您是使用Python的朋友,可以自行參考[7] [8]說明,亦可直接參考這兩個版本的Tutorials分項的範例,官方已給出正確的升版寫作方式。更多遷移到API 2.0所須注意的工作細節及對應IR v11新增內容可參考官方說明文件[9]。

 

Fig. 4 新舊版本執行推論程式比較。(OmniXRI整理製作, 2022/7/20)


*模型優化參數簡化及自動化


在OpenVINO中模型優化器(Model Optimizer, MO)一直是很重要的亮點,它可以幫大家把各種框架(如TensorFlow, PyTorch, ONNX …)產生的模型轉換到中介表示(IR)檔。所謂IR檔包括兩個檔案,XML檔負責描述模型的網路拓撲(節點連接方式),而BIN檔則存放權重值(Weights)及偏差值(Bias)的二進制數值。經過IR檔,就可以很容轉換到各種推論硬體上,也便於進行模型的優化。

在此次2022.1版中,對於執行模型優化器的參數作了一些優化,如下範例所示。舊版(2021.4版為例)須加入輸入模型的外形,而新版就不需要了,因為運行時會自動解讀模型取得相關外形參數。


// OpenVINO 舊版(以2021.4版為例)MO使用命令,必須指定批次輸入的數量N(通常為1)、色彩通道C、資料高度H及資料寬度W
mo --input_model MODEL_NAME --input_shape[N,C,H,W]

// OpenVINO 2022.1版MO使用命令,只需指定模型名稱(如xx.pb, xx.onnx)即可。運行後通常會自動產生FP32/FP16/INT8格式的IR檔,若只需特定數值格式,可另外加上--data_type直接指定。
mo --input_model MODEL_NAME --data_type FP16

 

另外2022.1版MO亦無須使用--disable_nhwc_to_nchw參數,MO會自動加入額外的Layer,以確保和原始框架Layout和數值精度一致。

目前2022.1版MO可支援TensorFlow, ONNX, PyTorch, PaddlePaddle, MXNet, Caffe, Kaldi等模型的轉換及優化,亦提供將近30種的常見模型轉換參考範例(Model Conversion Tutorials),尤其在RNN / NLP相關模型(如TensorFLow BERT / DeepSpeech / Language Modle, ONNX GPT-2 / BERT-NER等)更是有很多支援。更完整的內容可參考官方說明文件[10]。

*部署時更智能管理硬體裝置


此次2022.1版在最後部署上還有幾個小亮點,讓推論效能還能再略微提升,以下就簡單說明之。

1.    Auto Device Plugin

以往舊版使用Inference Engine API時,必須由使用者自己決定要使用的推論硬體、配置對應參數,尤其在多裝置同時運行時就更難設定。此次2022.1版時使用OpenVINO Runtime API,會自動搜索系統中所有算力(如CPU, GPU, iGPU, VPU等)及其規格,並根據模型的精度、結構及用戶指定性能要求等訊息,選取並配置適合算力單元進行部署。可支援的硬體及模型精度如Fig. 5所示。

Fig. 5 OpenVINO 2022.1 自動裝置選擇支持裝置及精度。(OmniXRI參考[11]整理製
作, 2022/7/20))


以下簡單列出一個C++範例,更完整的內容可參考官方說明文件[11]。


// Auto Device Plugin範例指令,以C++語言為例。
ov::Core core; // 宣告核心物件

// Read a network in IR, PaddlePaddle, or ONNX format:
std::shared_ptr<ov::Model> model = core.read_model("sample.xml");

// compile a model on AUTO using the default list of device candidates.
// Auto Device Plugin範例指令,以C++語言為例。

// 預設不帶參數即為"AUTO",以下兩種寫法為等價用法。
ov::CompiledModel model = core.compile_model(model);
ov::CompiledModel model = core.compile_model(model, "AUTO");

// 亦可手動指定特定推論硬體,如GPU, CPU,以下兩種寫法為等價用法。
// 使用device::priorities可強制決定使用優先順序。
ov::CompiledModel model = core.compile_model(model, "AUTO:GPU,CPU");
ov::CompiledModel model = core.compile_model(model, "AUTO",
ov::device::priorities("GPU,CPU"));

2.    PERFORMANCE_HINT

搭配前項內容,還可加上性能提示ov::hint::performance_mode來配置自動選擇裝置,使其達到最佳性能。目前主要提供吞吐量(THROUGHPUT)和延遲(LATENCY)兩種選項,其C++設定範例如下。如果您是使用Python的朋友或者想了解更多用法,可參考官文說明文件[11]。


// OpenVINO 2022.1 Performance_mode C++設定範例
ov::Core core; // 宣告核心物件

// 讀取IR模型
std::shared_ptr<ov::Model> model = core.read_model("model_name.xml");

// 依需求二選一,決定效能模式
// 高吞吐(THROUGHPUT)模式
ov::CompiledModel compiled_model = core.compile_model(model, "AUTO",
 ov::hint::performance_mode(ov::hint::PerformanceMode::THROUGHPUT));
// 低延遲(LATENCY)模式
ov::CompiledModel compiled_mode = core.compile_model(model, "AUTO",
ov::hint::performance_mode(ov::hint::PerformanceMode::LATENCY));

另外ov::hint::model_priority亦提供手動控制Auto-Device的執行優先權,如下範例所示。不過高優先級模型會加載到高優先級裝置。而較低優先級的模型不會被加載到被較高優先級的模型占用的裝置上。裝置優先級可參考Fig. 5所示。


// 假設有三個模型和三個推論硬體可配置,依次配置給CPU, GPU, MYRIAD (VPU),且將優先權分別指定高、中、低。但這違反高優先級模型要加載到高優先級裝置原則,所以最後三個模型分別會以GPU, MYRIAD, CPU來執行。
ov::CompiledModel compiled_model0 = core.compile_model(model, "AUTO",
    ov::hint::model_priority(ov::hint::Priority::HIGH));
ov::CompiledModel compiled_model1 = core.compile_model(model, "AUTO",
    ov::hint::model_priority(ov::hint::Priority::MEDIUM));
ov::CompiledModel compiled_model2 = core.compile_model(model, "AUTO",
    ov::hint::model_priority(ov::hint::Priority::LOW));

3.    First Inference Latency

如果您已是舊版OpenVINO的使用者,那一定遇過同樣的模型推論在iGPU和MYRIAD (VPU)運行時,第一次推論會延遲1~2分鐘,尤其使用iGPU時延時更為明顯,而使用CPU則很快就能運行起來。這個問題在2022.1版有明顯的改善。如Fig. 6所示,假設我們要使用Intel GPU進行推論,則在模型編譯和載入到GPU前,先使用CPU來推論,待GPU準備好了就切換過去,使用者完全無感。如此第一次推論延時就變得很短,同時保有第二次之後GPU推論速度的提升,明顯
改善這個問題。

 

Fig. 6 Auto-Device提升首次推論延遲示意圖。[11]


4.    Dynamic Shapes (CPU plugin only)

在深度學習模型中靜態模型在推論時可透過調用塑形函式reshape()就能很容易調整輸入資料的張量形狀(或維度),但這樣的計算是非常耗時的。如果遇到像自然語言處理(如BERT)、風格轉移這類輸入張量維度是會動態變化的模型,調用reshape()就會變成計算的瓶頸。在2022.1版開始支援動態塑形(不指定特定維度的數值),除可解決計算耗時問題,同時解決以往難以處理地時序型循環神經網路模型推論問題。以下簡單列出幾種動態塑形的用法,更完整的內容可參考官方說明文件[12]。


// 動態塑形範例,以C++為例。
ov::Core core; // 宣告核心物件
auto model = core.read_model("model_name.xml"); // 讀入模型

// 假設指定其中一個維度為靜態且大小為1,而另一個維度為動態(未知大小),即使用ov::Dimension(),或者使用-1取代亦可。
model->reshape({{1, ov::Dimension()}});  // {1,?}
model->reshape({{1, -1}});  // {1,?},用法同上

// 亦可指定動態重塑的範圍(上下限),如下例子為二個維度皆為動態,前者圍為1到10,後者為8到512。
model->reshape({{ov::Dimension(1, 10), ov::Dimension(8, 512)}}); // {1..10,8..512}

5.    Preprocessing API

通常深度學習的模型都會指定輸入資料的維度、數值格式、尺寸大小,若輸入資料不符合指定格式時就要進行預處理(Preprocessing),而在舊版OpenVINO多半是搭配配套安裝的OpenCV來協助完成。不過這些工作只能依賴CPU,沒辦法透過其它高效能裝置(如iGPU, GPU)來加速預處理。

假設輸入資料為一張三通道RGB彩色影像,那導入模型前就需下列預處理工作,如Fig. 7所示。

  • 將每一通道U8格式資料轉換到FP32格式
  • 將資料維度格式從[n, h, w, c]轉換到[n, c, h, w]
  • 將圖像原尺寸轉換到模型指定輸入尺寸(有可能從矩形被壓縮到正方形)
  • 由於透過OpenCV讀檔,所以需將BGR格式重新轉換成RGB格式
  • 對每個像素進行數值正規化,即將像素減去平均值再除以比例因子。

 

Fig. 7 傳統影像導入模型推論前預處理示意圖。[13]


雖然透過OpenCV可以完成以上所有預處理工作但效能不高,所以2022.1版提供了能使用GPU/VPU等更高效能的硬體來執行預處理及推論後處理的函式ov::preprocess::PrePostPocessor。以下就簡單舉一個例子來說明,更完整的內容可參考官方說明文件[13]。


// 輸入資料預處理範例,以C++為例。
ov::Core core; // 宣告核心物件
std::shared_ptr<ov::Model> model = core.read_model(model_path); // 讀入模型
ov::preprocess::PrePostProcessor ppp(model); // 初始化預/後處理函式
ov::preprocess::InputInfo& input = ppp.input(input_name); // 取得輸入資料資訊

input.tensor() // 指定輸入資料原始格式
  .set_element_type(ov::element::u8) // 輸入為U8格式
  .set_shape({1, 480, 640, 3}) // 數量1, 高480, 寬640, 通道3
  .set_layout("NHWC") // 資料排列方式為批次數量、高、寬及通道數
  .set_color_format(ov::preprocess::ColorFormat::BGR); // 色彩格式為BGR

input.model().set_layout("NCHW"); // 將資料排列方式調整成NCHW
input.preprocess() // 開始對輸入資料進行預處理
  .convert_element_type(ov::element::f32) // 指定資料數值精度轉換到FP32
  .convert_color(ov::preprocess::ColorFormat::RGB) // 指定色彩格式轉換到
RGB
  .resize(ov::preprocess::ResizeAlgorithm::RESIZE_LINEAR) // 將影像以線性縮放
至指定尺寸
  .mean({100.5, 101, 101.5}) // 指定平均值參數
  .scale({50., 51., 52.}); // 指定比例因子參數

std::cout << "Dump preprocessor: " << ppp << std::endl;
model = ppp.build(); // 建置模型

小結


此次OpenVINO 2022.1的大改版帶來許多重大優化,值得大家好好了解一下。對於沒用過的伙伴,可直接享用,感受一下這項工具在開發AI應用程式所帶來的便捷性。若是初學者或輕度使用者,只會下載模型進行推論的朋友,則可依各範例提示修改引數即可運行。若您已是OpenVINO開發的高手或者是API程式應用的老手,則需重新熟悉一下新的API 2.0寫作方式,因為新舊版本完全不相容,也沒有升版自動轉換的工具,所以舊有已開發的程式必須逐一對照、手動修改。若您暫時不想升到API 2.0版,則還是可以繼續使用舊有API 1.0的寫法,但是須要手動修改C/C++專案檔(makefile, project file, …)中頭文件(header file)及函式庫(library)的引用路徑。雖然升版會有一些小麻煩,但對後續應用程式的開發、程式運作效能及在不同硬體上部署會得到更多好處,且更能適用更多常用模型,值得衡量利弊後,採取全面或漸進式更新的規畫。

本文同步發行於MakerPRO


參考文獻


[1] Intel, OpenVINO Online Documentation
https://docs.openvino.ai/2022.1/index.html

[2] Intel, Release Notes for Intel Distribution of OpenVINO toolkit v.2022
https://www.intel.com/content/www/us/en/developer/articles/release-notes/openvino-relnotes.html

[3] Intel, Github – openvinotoolkit – Build OpenVINO Inference Engine
https://github.com/openvinotoolkit/openvino/wiki/BuildingCode

[4] Intel, Performing inference with OpenVINO runtime – Running on multiple devices simultaneously
https://docs.openvino.ai/2022.1/openvino_docs_OV_UG_Running_on_multiple_devices.html

[5] Intel, Performing inference with OpenVINO runtime - Heterogeneous execution
https://docs.openvino.ai/2022.1/openvino_docs_OV_UG_Hetero_execution.html

[6] Intel, Deploying Inference – Working with devices (plugins)
https://docs.openvino.ai/2022.1/openvino_docs_OV_UG_Working_with_devices.html

[7] Intel, DEPLOYING INFERENCE - Inference Engine Developer Guide - Integrate Inference Engine
https://docs.openvino.ai/2021.4/openvino_docs_IE_DG_Integrate_with_customer_application_new_API.html

[8] DEPLOYING INFERENCE - Performing inference with OpenVINO Runtime - Integrate OpenVINO with Your Application
https://docs.openvino.ai/2022.1/openvino_docs_OV_UG_Integrate_OV_with_your_application.html

[9] Intel, Transition to OpenVINO 2.0 API
https://docs.openvino.ai/2022.1/openvino_2_0_transition_guide.html

[10] Intel, Convert Model with Model Optimizer
https://docs.openvino.ai/2022.1/openvino_docs_MO_DG_Deep_Learning_Model_Optimizer_DevGuide.html

[11] Intel, DEPOLYING INFERENCE - Performing inference with OpenVINO Runtime
https://docs.openvino.ai/2022.1/openvino_docs_OV_UG_supported_plugins_AUTO.html

[12] Intel, DEPOLYING INFERENCE - Performing inference with OpenVINO Runtime – Dynamic Shapes
https://docs.openvino.ai/2022.1/openvino_docs_OV_UG_DynamicShapes.html#doxid-openvino-docs-o-v-u-g-dynamic-shapes

[13] Intel, DEPOLYING INFERENCE - Performing inference with OpenVINO Runtime – Optimize Prepocessing
https://docs.openvino.ai/2022.1/openvino_docs_OV_UG_Preprocessing_Overview.html


 



沒有留言:

張貼留言

【頂置】簡報、源碼、系列文快速連結區

常有人反應用手機瀏覽本部落格時常要捲很多頁才能找到系列發文、開源專案、課程及活動簡報,為了方便大家快速查詢,特整理連結如下,敬請參考! Edge AI Taiwan 邊緣智能交流區 全像顯示與互動交流區 台科大(NTUST) 人工智慧與邊緣運算實務 開南大學...