Open11
CREStereo の OAK-D 最適化検証
-
MVN
の Myriad コンパイルエラーを回避するため、ONNX から OpenVINO へ変換する過程で MVN が生成されないようにONNXを改造する必要がある。 - まずは、
CREStereo
のMVN
変換が実行される箇所のみを切り出す - 自作ONNX分離ツール sne4onnx を使用
CREStereoの部分グラフ抽出
sne4onnx \
--input_onnx_file_path crestereo_init_iter2_120x160.onnx \
--input_op_names onnx::MatMul_1030 \
--output_op_names onnx::Mul_1041 \
--output_onnx_file_path crestereo_init_iter2_120x160_mvn.onnx
- 元のモデルの
Einsum
の部分でONNXがシェイプ推定できていなくてMatMul
の入力がunk__105
になってしまっている - ONNX から OpenVINO へ変換する前に
unk__105
の部分を静的形状に変更する - とりあえず、部分グラフを抽出する前にモデル全体を OpenVINO で変換したときの
MVN
の入力形状は形状推定に成功しているので、その入力形状を参考に固定値に書き換える。この場合は[1, 70, 256]
。OpenVINO超優秀。 - OpenVINOへ変換したあとの CREStereo の MVN の箇所
静的形状の指定
onnxsim crestereo_init_iter2_120x160_mvn.onnx crestereo_init_iter2_120x160_mvn.onnx \
--input-shape "onnx::MatMul_1030:1,70,256"
- いったん、抽出した部分グラフが
OpenVINO -> Myriad
でどのように変換されるかを見てみる
ONNX -> OpenVINO
$INTEL_OPENVINO_DIR/deployment_tools/model_optimizer/mo.py \
--input_model crestereo_init_iter2_120x160_mvn.onnx \
--data_type FP16 \
--output_dir crestereo_init_iter2_120x160_mvn/openvino/FP16 \
--model_name crestereo_init_iter2_120x160_mvn
- 成功。ただし、本当は
MVN
が生成されてほしくない。Myriad コンパイラがエラーになるので。
mkdir -p crestereo_init_iter2_120x160_mvn/openvino/myriad
${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/lib/intel64/myriad_compile \
-m crestereo_init_iter2_120x160_mvn/openvino/FP16/crestereo_init_iter2_120x160_mvn.xml \
-ip U8 \
-VPU_NUMBER_OF_SHAVES 4 \
-VPU_NUMBER_OF_CMX_SLICES 4 \
-o crestereo_init_iter2_120x160_mvn/openvino/myriad/crestereo_init_iter2_120x160_mvn.blob
- 想定通り Myriad Compile でエラー。
Inference Engine:
IE version ......... 2021.4.0
Build ........... 2021.4.0-3839-cd81789d294-releases/2021/4
[Warning][VPU][Config] Deprecated option was used : VPU_MYRIAD_PLATFORM
[ GENERAL_ERROR ]
/home/jenkins/agent/workspace/private-ci/ie/build-linux-ubuntu20/b/repos/openvino/inference-engine/src/vpu/graph_transformer/src/frontend/frontend.cpp:439 Failed to compile layer "onnx::Mul_1041": [ GENERAL_ERROR ]
/home/jenkins/agent/workspace/private-ci/ie/build-linux-ubuntu20/b/repos/openvino/inference-engine/src/vpu/graph_transformer/src/stages/mvn.cpp:92 Unsupported combination of indices in layer "onnx::Mul_1041". Only across channel and full batch supported.
- ONNXの部分グラフに
Multiply
を外挿する
avoid_mvn.py
import onnx
import onnx_graphsurgeon as gs
import numpy as np
# Load
onnx_graph = onnx.load('crestereo_init_iter2_120x160_mvn.onnx')
graph = gs.import_onnx(onnx_graph)
# Finding outputs for connection
mod_output = None
for graph_node in graph.nodes:
if graph_node.name == 'Sub_650':
for node_output in graph_node.outputs:
if node_output.name == 'onnx::Pow_1034':
mod_output = node_output
break
# Generate dummy Multiply OP
# https://github.com/onnx/onnx/blob/main/docs/Changelog.md#Mul-7
# https://docs.openvino.ai/latest/openvino_docs_ops_arithmetic_Multiply_1.html
mul_node = gs.Node(
op="Mul",
name=f"{mod_output.name}_dummy_mul",
inputs=[
mod_output,
gs.Constant(
name=f"{mod_output.name}_dummy_mul_input",
values=np.asarray([1.0], dtype=np.float32)
),
],
outputs=[
gs.Variable(
name=f"{mod_output.name}_dummy_mul_output",
dtype=np.float32, shape=[1,70,256]
),
]
)
graph.nodes.append(mul_node)
# Finding inputs for connection
mod_input = None
for node_idx, graph_node in enumerate(graph.nodes):
if graph_node.name == 'Div_657':
for input_idx, node_input in enumerate(graph_node.inputs):
if node_input.name == 'onnx::Pow_1034':
graph.nodes[node_idx].inputs[input_idx] = mul_node.outputs[0]
break
# Cleanup
graph.cleanup().toposort()
# Export
changed_graph = gs.export_onnx(graph)
# Shape inference
new_model = onnx.shape_inference.infer_shapes(changed_graph)
# Save
onnx.save(new_model, 'crestereo_init_iter2_120x160_mvn_mul.onnx')
- OpenVINO がちゃんと混乱するかどうかを検証。
$INTEL_OPENVINO_DIR/deployment_tools/model_optimizer/mo.py \
--input_model crestereo_init_iter2_120x160_mvn_mul.onnx \
--data_type FP16 \
--output_dir crestereo_init_iter2_120x160_mvn_mul/openvino/FP16 \
--model_name crestereo_init_iter2_120x160_mvn_mul
-
OpenVINO Model Optimizer を騙すことに成功
-
ただ、まだ
Power
が残っているので Myriad Compile は失敗する想定
mkdir -p crestereo_init_iter2_120x160_mvn_mul/openvino/myriad
${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/lib/intel64/myriad_compile \
-m crestereo_init_iter2_120x160_mvn_mul/openvino/FP16/crestereo_init_iter2_120x160_mvn_mul.xml \
-ip U8 \
-VPU_NUMBER_OF_SHAVES 4 \
-VPU_NUMBER_OF_CMX_SLICES 4 \
-o crestereo_init_iter2_120x160_mvn_mul/openvino/myriad/crestereo_init_iter2_120x160_mvn_mul.blob
- と、思ったら Myriad Blob の生成に成功してしまった。。。
Inference Engine:
IE version ......... 2021.4.0
Build ........... 2021.4.0-3839-cd81789d294-releases/2021/4
[Warning][VPU][Config] Deprecated option was used : VPU_MYRIAD_PLATFORM
Done
onnx -> OpenVINO
$INTEL_OPENVINO_DIR/deployment_tools/model_optimizer/mo.py \
--input_model crestereo_init_iter2_120x160_avoid_mvn.onnx \
--data_type FP16 \
--output_dir crestereo_init_iter2_120x160_avoid_mvn/openvino/FP16 \
--model_name crestereo_init_iter2_120x160_avoid_mvn
OpenVINO -> Myriad
mkdir -p crestereo_init_iter2_120x160_avoid_mvn/openvino/myriad
${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/lib/intel64/myriad_compile \
-m crestereo_init_iter2_120x160_avoid_mvn/openvino/FP16/crestereo_init_iter2_120x160_avoid_mvn.xml \
-ip U8 \
-VPU_NUMBER_OF_SHAVES 4 \
-VPU_NUMBER_OF_CMX_SLICES 4 \
-o crestereo_init_iter2_120x160_avoid_mvn/openvino/myriad/crestereo_init_iter2_120x160_avoid_mvn.blob
- 新しいエラー。
Less
OPは INT64, INT32 の入力を受け付けないので Float16, Float32 にせよ。
Inference Engine:
IE version ......... 2021.4.0
Build ........... 2021.4.0-3839-cd81789d294-releases/2021/4
[Warning][VPU][Config] Deprecated option was used : VPU_MYRIAD_PLATFORM
Less_1562 of type Less: [ GENERAL_ERROR ]
/home/jenkins/agent/workspace/private-ci/ie/build-linux-ubuntu20/b/repos/openvino/inference-engine/src/vpu/graph_transformer/src/stages/eltwise.cpp:160 Stage node Less_1562 (Less) types check error: input #0 has type S32, but one of [FP16] is expected
- 元のONNXグラフ全体に対して問題が発生する全ての
MVN
の生成を阻害するためのMul
を挿入する。なお、全てのMVN
が対象ではない点に注意。
-
Less
とGreater
の型変換エラーに対処するため、前後にCast
を挟んでINT64
とFloat32
を相互に変換する
-
Expand
の型変換エラーに対処するため、前後にCast
を挟んでINT64
とFloat32
を相互に変換する
- 完成形スクリプト
- Self-made tools for ONNX machining