OpenVINO 条件付きコンパイルによる最適なバイナリーサイズ

条件付きコンパイルでは、特定のモデルの推論に不要なコンポーネントを除外することで、OpenVINO パッケージのバイナリーサイズを大幅に削減できます。これは、アプリケーションのバイナリーのサイズを削減することが重要であるエッジおよびクライアントのデプロイシナリオで役立ちます。

重要

条件付きコンパイルのトレードオフは、生成された OpenVINO ランタイムは、条件付きコンパイルが適用されたモデルとプラットフォームの推論のみを実行できることです。

詳細は、条件付きコンパイルガイド条件付きコンパイル開発者ガイドをご覧ください。

条件付きコンパイルにより、OpenVINO ランタイム・ライブラリーのバイナリーサイズを削減するには、次の 2 つの手順があります。

  • SELECTIVE_BUILD=COLLECT および DENABLE_PROFILING_ITT=ON ビルドオプションを適用して、条件付きコンパイルの分析モードを有効にし、itt を使用して統計データを収集します。

  • SELECTIVE_BUILD=ON および SELECTIVE_BUILD_STAT=<statistics_data.csv> ビルドオプションを適用して、収集済みの統計データを利用して非アクティブなコード領域を除外し、最終的な OpenVINO パッケージを取得します。

統計データの収集に役立つ Python をインストールします。

複数モデルの条件付きコンパイル

ステージ 1: コードの使用状況に関する統計情報を収集

  • SELECTIVE_BUILD=COLLECT オプションを使用して OpenVINO をビルドします

    git submodule init
    git submodule update
    mkdir build && cd build
    cmake -DENABLE_PROFILING_ITT=ON -DSELECTIVE_BUILD=COLLECT ..
    cmake --build .
    
  • コード使用状況分析用の ITT コレクターを構築します

    cmake --build . --target sea_itt_lib
    
  • 各モデルのコード使用状況を分析するため、ITT コレクターで下でターゲット・アプリケーションを実行します

    python thirdparty/itt_collector/runtool/sea_runtool.py --bindir ${OPENVINO_LIBRARY_DIR} -o ${MY_MODEL_RESULT} ! ./benchmark_app -niter 1 -nireq 1 -m ${MY_MODEL}.xml
    
    Then, statistics information are generated and stored into .cvs format files under ``{MY_MODEL_RESULT}`` directory.
    

    ヒント

    Benchmark_app 以外のアプリケーションを実行して統計データを収集する場合は、プロファイル時間が長くなりすぎたり、統計データが大きくなりすぎないように、推論要求の数と反復数を制限する必要があります。

    このスクリプトを実行すると、生成されたヘッダーファイルを CSV ファイルから取得し、統計が正しいかどうかを確認できます。このステップは条件付きコンパイルの第 2 ステージで暗黙的に実行されます。必要がない場合はスキップしてください。

    python3.8 ../../src/common/conditional_compilation/scripts/ccheader.py --stat ${csv_files} --out conditional_compilation_gen.h
    
    The conditional_compilation_gen.h looks like this:
    
    #pragma once
    
    #define tbb_bind_TBBbindSystemTopology 1
    #define tbb_bind_task_arena_initialize 1
    
    #define ov_opset_opset1_Parameter 1
    #define ov_opset_opset1_Constant 1
    #define ov_opset_opset1_Convolution 1
    #define ov_opset_opset1_Add 1
    #define ov_opset_opset1_Relu 1
    #define ov_opset_opset1_GroupConvolution 1
    #define ov_opset_opset3_ShapeOf 1
    #define ov_opset_opset1_Squeeze 1
    #define ov_opset_opset4_Range 1
    #define ov_opset_opset1_ReduceMean 1
    #define ov_opset_opset1_Softmax 1
    #define ov_opset_opset1_Result 1
    
    #define ov_op_v0_Parameter_visit_attributes 1
    #define ov_op_v0_Parameter_validate_and_infer_types 1
    #define ov_op_v0_Parameter_clone_with_new_inputs 1
    #define ov_op_v0_Constant_visit_attributes 1
    #define ov_op_v0_Constant_clone_with_new_inputs 1
    #define ov_op_v1_Convolution_visit_attributes 1
    #define ov_op_v1_Convolution_validate_and_infer_types 1
    #define ov_op_v1_Convolution_clone_with_new_inputs 1
    #define ov_op_v0_util_BinaryElementwiseArithmetic_visit_attributes 1
    #define ov_op_v1_Add_visit_attributes 1
    #define ov_op_v0_util_BinaryElementwiseArithmetic_validate_and_infer_types 1
    #define ov_op_v1_Add_clone_with_new_inputs 1
    #define ov_op_v0_Relu_visit_attributes 1
    #define ov_op_util_UnaryElementwiseArithmetic_validate_and_infer_types 1
    #define ov_op_v0_Relu_clone_with_new_inputs 1
    #define ov_op_v1_GroupConvolution_visit_attributes 1
    #define ov_op_v1_GroupConvolution_validate_and_infer_types 1
    #define ov_op_v1_GroupConvolution_clone_with_new_inputs 1
    #define ov_op_v3_ShapeOf_visit_attributes 1
    #define ov_op_v3_ShapeOf_validate_and_infer_types 1
    #define ov_op_v3_ShapeOf_clone_with_new_inputs 1
    #define ov_op_v0_Squeeze_visit_attributes 1
    ...
    

ステージ 2: 結果として得られる OpenVINO パッケージをビルド

統計情報を基に OpenVINO を再ビルドし、最適なサイズの OpenVINO バイナリーを生成します。

cmake -DSELECTIVE_BUILD=ON -DSELECTIVE_BUILD_STAT=${ABSOLUTE_PATH_TO_STATISTICS_FILES}/*.csv -DENABLE_PROFILING_ITT=OFF ..
cmake --build .

ヒント

複雑な条件で推奨されるシナリオは、OpenVINO の静的ビルドです。この場合、-DBUILD_SHARED_LIBS=OFF を追加して静的ビルドを有効にすることで、最適なバイナリーサイズを取得できます。

異なる命令セット・アーキテクチャー (ISA) の条件付きコンパイル

このステップは、異なる ISAs で異なる統計データを収集することを除いて、異なるモデルのビルドとほぼ同じです。各 ISA でのコード使用状況を分析するため、ITT コレクターでターゲット・アプリケーションを実行します。

python thirdparty/itt_collector/runtool/sea_runtool.py --bindir ${OPENVINO_LIBRARY_DIR} -o ${MY_MODEL_RESULT} ! ./benchmark_app -niter 1 -nireq 1 -m ${MY_MODEL}.xml

ステージ 2 ですべての CSV ファイルを統合して、OpenVINO バイナリーを生成します。

cmake -DSELECTIVE_BUILD=ON -DSELECTIVE_BUILD_STAT=${ABSOLUTE_PATH_TO_STATISTICS_FILES}/*.csv -DENABLE_PROFILING_ITT=OFF ..
cmake --build .

デバイスに依存しない条件付きコンパイル (POC)

状況によっては、複数の異なる SKU (在庫管理単位: 通常、メーカーが製品を識別するために使用する数字とアルファベットの文字列) をサポートする条件付きコンパイルが必要になりますが、ターゲット・ハードウェアごとの統計情報の収集には制限が課されることがあります。これには、条件付きコンパイルが以前のすべての SKU を使用してアクセラレーター上でモデルを実行できる必要があります。

条件付きコンパイルでは、ops やカーネルなど未使用のコード領域を除外するため、統計情報の初期収集が必要です。これを行うには、含まれるすべての操作とカーネルが少なくとも一度は実行されなければなりません。複数の SKU では、いずれかの SKU によって使用されるすべての操作とカーネルがプロファイル・データ内で少なくとも 1 回検出される必要があります。CPU プラットフォーム上でプロファイルを行う場合、エミュレーターなしではプロファイルできません。

最も簡単な方法は、SDE を利用してさまざまな CPU の SKU をエミュレートし、それぞれの SKU に対して複数の統計 CSV ファイルを生成することです。次に例を示します。

for cpu in spr adl tgl icl skl; do
    python ../thirdparty/itt_collector/runtool/sea_runtool.py --bindir ${OPENVINO_LIBRARY_DIR} -o ${MY_MODEL_RESULT} ! sde -$cpu -- ./benchmark_app -niter 1 -nireq 1 -m ${MY_MODEL}.xml
done

JIT カーネルが L1/L2/L3 キャッシュサイズと CPU コア数の影響を受けることを考慮して、L2/L3 キャッシュサイズと CPU コア数をエミュレートする簡単な方法もあります。

  • L2 /L3 キャッシュ・エミュレーション

    キャッシュサイズを取得する関数 unsigned int dnnl::impl::cpu::platform::get_per_core_cache_size(int level) をハックして、分析段階でエミュレートされたキャッシュサイズを返すようにします。最も簡単な方法は、環境変数を利用してエミュレートされたキャッシュサイズを渡すことです。
    例:

    #if defined(SELECTIVE_BUILD_ANALYZER)
        if (level == 2) {
            const char* L2_cache_size = std::getenv("OV_CC_L2_CACHE_SIZE");
            if (L2_cache_size) {
                int size = std::atoi(L2_cache_size);
                if (size > 0) {
                    return size;
                }
            }
        } else if (level == 3) {
            const char* L3_cache_size = std::getenv("OV_CC_L3_CACHE_SIZE");
            if (L3_cache_size) {
                int size = std::atoi(L3_cache_size);
                if (size > 0) {
                    return size;
                }
            }
        } else if (level == 1) {
            const char* L1_cache_size = std::getenv("OV_CC_L1_CACHE_SIZE");
            if (L1_cache_size) {
                int size = std::atoi(L1_cache_size);
                if (size > 0) {
                    return size;
                }
            }
        }
    #endif
    
  • CPU コア数のエミュレーション

    numactl ツールでコア数を制御します。

    python thirdparty/itt_collector/runtool/sea_runtool.py --bindir ${OPENVINO_LIBRARY_DIR} -o ${MY_MODEL_RESULT} ! numactl -C 0-$core_num ./benchmark_app -niter 1 -nireq 1 -m ${MY_MODEL}.xml
    

SKU が決定したら、CPU 情報 (CPUID、L1/L2/L3 キャッシュサイズ、コア数) を収集し、(CPUID、L1/L2/L3 キャッシュサイズ、コア番号) の各ペアをプロファルして CSV ファイルを取得できます。生成された統計 CSV ファイルを OpenVINO パッケージのビルドに提供します。

単一システム上で条件付きコンパイルパッケージを生成する例:

export OV_CC_L1_CACHE_SIZE=<L1 cache size>
export OV_CC_L2_CACHE_SIZE=<L2 cache size>
export OV_CC_L3_CACHE_SIZE=<L3 cache size>
python thirdparty/itt_collector/runtool/sea_runtool.py --bindir ${OPENVINO_LIBRARY_DIR} -o ${MY_MODEL_RESULT} ! sde -spr -- numactl -C 0-$core_num ./benchmark_app -niter 1 -nireq 1 -m ${MY_MODEL}.xml

SKU 情報 (CPUID、L1/L2/L3 キャッシュサイズ、コア数) ごとに上記の手順を実行して、生成される統計 CSV ファイルを収集し、OpenVINO パッケージのビルドに提供します。

cmake -DSELECTIVE_BUILD=ON -DSELECTIVE_BUILD_STAT=${ABSOLUTE_PATH_TO_STATISTICS_FILES}/*.csv -DENABLE_PROFILING_ITT=OFF ..
cmake --build .

Windows* で条件付きコンパイルを有効にする方法

詳細については、OpenVINO 静的ライブラリーの構築を参照してください。

ステージ 1: 選択的ビルド分析ステージ

条件付きコンパイルを有効にして OpenVINO をビルドします。

call C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvar64.bat
set OPENVINO_HOME=D:\work_path\openvino
cd %OPENVINO_HOME%
md build_cc
cd build_cc
cmake -G Ninja -Wno-dev -DCMAKE_BUILD_TYPE=Debug -DENABLE_CPPLINT=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=OFF -DENABLE_FASTER_BUILD=ON -DENABLE_SANITIZER=OFF -DTHREADING=TBB -DBUILD_SHARED_LIBS=OFF -DENABLE_PROFILING_ITT=ON -DSELECTIVE_BUILD=COLLECT -DENABLE_INTEL_GPU=OFF -DENABLE_MULTI=OFF -DENABLE_AUTO=OFF -DENABLE_AUTO_BATCH=OFF -DENABLE_HETERO=OFF -DENABLE_TEMPLATE=OFF -DENABLE_OV_ONNX_FRONTEND=OFF -DENABLE_OV_PADDLE_FRONTEND=OFF -DENABLE_OV_PYTORCH_FRONTEND=OFF -DENABLE_OV_TF_FRONTEND=OFF -DCMAKE_INSTALL_PREFIX=install ..

cmake --build . --config Debug

統計データを収集します。

cd %OPENVINO_HOME%\build_cc
cmake --build . --config Debug --target sea_itt_lib
cd %OPENVINO_HOME%
set PATH=%PATH%;%OPENVINO_HOME%\\temp\tbb\bin
mkdir cc_data
cd %OPENVINO_HOME%\cc_data
python3 ..\thirdparty\itt_collector\runtool\sea_runtool.py --bindir ..\bin\intel64\Debug -o %OPENVINO_HOME%\cc_data\data ! ..\bin\intel64\Debug\benchmark_app.exe -niter 1 -nireq 1 -m <your_model.xml>

このステージはデータのプロファイル向けです。デバッグビルドまたはリリースビルドの選択は、特定の要件によって異なります。

ステージ 2: 結果として得られる OpenVINO パッケージをビルド

最適なバイナリーサイズの最終的な OpenVINO パッケージを生成します。

cd %OPENVINO_HOME%
md build
cd build

cmake -G "Visual Studio 16 2019" -A x64 -DENABLE_CPPLINT=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=OFF -DCMAKE_BUILD_TYPE=Release -DENABLE_FASTER_BUILD=ON -DENABLE_PROFILING_ITT=OFF -DSELECTIVE_BUILD=ON -DENABLE_INTEL_GPU=OFF -DENABLE_MULTI=OFF -DENABLE_AUTO=OFF -DENABLE_AUTO_BATCH=OFF -DENABLE_HETERO=OFF -DENABLE_TEMPLATE=OFF -DENABLE_OV_ONNX_FRONTEND=OFF -DENABLE_OV_PADDLE_FRONTEND=OFF -DENABLE_OV_PYTORCH_FRONTEND=OFF -DENABLE_OV_TF_FRONTEND=OFF -DSELECTIVE_BUILD_STAT=%OPENVINO_HOME%\cc_data\*.csv -DBUILD_SHARED_LIBS=OFF -DENABLE_LTO=ON -DENABLE_ONEDNN_FOR_GPU=OFF -DENABLE_OV_TF_LITE_FRONTEND=OFF -DENABLE_PROFILING_FIRST_INFERENCE=OFF ..

cmake --build . --config Release

ヒント

-DSELECTIVE_BUILD=ON および -DSELECTIVE_BUILD_STAT=%OPENVINO_HOME%\cc_data\*.csv は必須であり、-DBUILD_SHARED_LIBS=OFF が推奨されます。