記錄自己openvino的使用
ubuntu 安裝 openvino
openvino在ubuntu上的安裝過程
參考鏈接:https://docs.openvinotoolkit.org/cn/latest/openvino_docs_install_guides_installing_openvino_linux.html
安裝過程
- 安裝openvino安裝包
./install_GUI.sh
- 安裝外部依賴軟件
cd /opt/intel/openvino/install_dependencies
sudo -E ./install_openvino_dependencies.sh
- 設置環境變量
雖然官方有個一鍵腳本設置,但這樣設置會跟你系統opencv起沖突,所以我只設了openvino相關lib庫路徑:
修改/etc/ld.so.conf
/opt/intel/openvino/deployment_tools/ngraph/lib
/opt/intel/openvino/deployment_tools/inference_engine/lib/intel64
/opt/intel/openvino/deployment_tools/inference_engine/external/tbb/lib
/opt/intel/openvino/inference_engine/external/mkltiny_lnx/lib
最后sudo ldconfig
-
配置模型轉換工具環境
因為我只用onnx轉換,然后onnx轉換工具的環境依賴其實就是onnx,只需要在conda環境下安裝一個onnx即可 -
計算棒相關依賴
sudo usermod -a -G users "$(whoami)"
sudo cp /opt/intel/openvino/inference_engine/external/97-myriad-usbboot.rules
/etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
sudo ldconfig
然后重啟
通過docker來使用openvino
直接在dockerhub 搜索 openvino,獲取openvino_dev的鏡像
從 Tags 中選擇 自己想要的 openvino版本
docker pull openvino/ubuntu18_dev:2021.2
docker run --user root --restart=always --privileged -d --name openvino -p 3333:22 --ipc=host -i -t -v /home:/home openvino/ubuntu18_dev:2021.2 /usr/sbin/sshd -D
注意
https://github.com/openvinotoolkit/model_server/blob/master/docs/docker_container.md#building-the-image
如果想要在計算棒上使用 openvino,請使用openvino2020.3及以下版本,另外 docker 運行鏡像時 需要 加上 -v /dev:/dev
openvino 的模型說明
openvino模型分為 xml 和 bin 文件,xml文件是模型文件,bin文件為權重文件。
openvino模型文件xml初步解析
xml模型分3個部分:
- layers : 記錄了網絡所有層
- edges : 記錄了層之間數據的輸入和輸出
- meta_data : 記錄了模型轉換的一些信息
layers
layer有id name type version屬性,id是編號,name是網絡層名字,type是網絡層類型.
type="Result"的層是輸出層,輸出層示例:
<layer id="333" name="indexs" type="Convert" version="opset1">
<data destination_type="I64"/>
<input>
<port id="0">
<dim>200</dim>
<dim>3</dim>
</port>
</input>
<output>
<port id="1" precision="I32">
<dim>200</dim>
<dim>3</dim>
</port>
</output>
</layer>
<layer id="334" name="selected_indices/sink_port_0" type="Result" version="opset1">
<input>
<port id="0">
<dim>200</dim>
<dim>3</dim>
</port>
</input>
</layer>
注意:調用openvino接口獲取模型輸出的名字時得到的是indexs而並非selected_indices/sink_port_0
edges
我理解的edge是模型之間數據的傳遞的記錄信息,舉例說明:
<edge from-layer="333" from-port="1" to-layer="334" to-port="0"/>
333層的輸出 port1,是334層的輸入 port0
openvino模型轉換的一個坑(我覺得是個坑)
openvino的模型轉換其實就是記錄一個圖的所有流向,然后所有流向的終點就為輸出(這就是一個很大的坑).舉例說明:
confidences = F.softmax(confidences, dim=2)
probs0,probs1 = torch.split(confidences,1,2)
return probs1
原始模型的輸出是probs1,然而openvino轉換的模型會有兩個輸出probs0和probs1
對於轉換后的IR與轉換前的IR的結果不匹配問題有3種方法解決
- 修改xml文件
- 修改模型導出代碼
- 修改c++ 部署代碼 設置自己想要的輸出
曾經遇到的問題
-
NonMaxSuppression結果異常
在 2020.04的openvino上 導出帶nms的onnx然后轉換成openvino的模型,推理時最多只得到了一個結果,原因未知,不確定是否是因為openvino版本不同(因為之前使用2020.01版本時 nms結果輸出正常) 還是openvino的nms只支持不歸一化處理的boxes 或者其他未知原因,目前靠c++實現了nms。 -
split 初始化 報錯問題
在 2020.04上,如果對一個tensor 進行切片操作多次,並且正好切出的子tensor 合並起來就是原始tensor的話, openvino 會做圖優化,將這些slice操作合並成split操作,然而我就遇到了初始化報錯split的問題。
解決方法:使用gather或者index_select 代替 切片的操作。
openvino 動態batch
參考鏈接: https://docs.openvinotoolkit.org/latest/openvino_docs_IE_DG_DynamicBatching.html
動態批處理功能使您可以在預設的批處理大小限制內動態更改推理調用的批處理大小。 如果事先不知道批次大小,並且由於資源限制,不希望使用或無法使用較大的批次大小,則此功能可能很有用。 例如,具有人的年齡,性別或情緒識別的面部檢測是典型的使用場景。
用法
您可以通過在加載網絡時傳遞給插件的配置圖中將KEY_DYN_BATCH_ENABLED標志設置為YES來激活動態批處理。 此配置創建一個ExecutableNetwork對象,該對象將允許使用SetBatch() 方法在其所有推斷請求中動態設置批處理大小。 在傳遞的CNNNetwork對象中設置的批量大小將用作最大批量大小限制。
這是一個代碼示例:
int dynBatchLimit = FLAGS_bl; //take dynamic batch limit from command line option
// Read network model
InferenceEngine::Core core;
InferenceEngine::CNNNetwork network = core.ReadNetwork("sample.xml");
// enable dynamic batching and prepare for setting max batch limit
const std::map<std::string, std::string> dyn_config =
{ { InferenceEngine::PluginConfigParams::KEY_DYN_BATCH_ENABLED, InferenceEngine::PluginConfigParams::YES } };
network.setBatchSize(dynBatchLimit);
// create executable network and infer request
auto executable_network = core.LoadNetwork(network, "CPU", dyn_config);
auto infer_request = executable_network.CreateInferRequest();
// ...
// process a set of images
// dynamically set batch size for subsequent Infer() calls of this request
size_t batchSize = imagesData.size();
infer_request.SetBatch(batchSize);
infer_request.Infer();
// ...
// process another set of images
batchSize = imagesData2.size();
infer_request.SetBatch(batchSize);
infer_request.Infer();
局限性
當前,存在使用動態批處理的某些限制:
- 僅對CPU和GPU插件使用動態批處理。
- 在僅包含某些層的拓撲上使用動態批處理:
Convolution Deconvolution Activation LRN Pooling FullyConnected SoftMax Split Concatenation Power Eltwise Crop BatchNormalization Copy
不要使用可能會隨意改變張量形狀的圖層(例如Flatten,Permute,Reshape),特定於對象檢測拓撲的圖層(ROIPooling,ProirBox,detectionOutput)以及自定義圖層。 在將網絡加載到插件的過程中執行拓撲分析,如果拓撲不適用,則會生成異常。
自己測試
作動態batch 官方說不支持的層,但自己測試卻沒有報錯
Reshape
Flatten
單獨只導出一個op作 動態batch 測試,發現以下op不支持
permute (Transpose)