ヘテロジニアス実行#

ヘテロジニアス実行により、複数のデバイス上で 1 つのモデルの推論を実行できます。以下を目的としています:

  • アクセラレーターの能力を利用してモデルの最も重い部分を処理し、CPU などのフォールバック・デバイスでサポートされていない操作を実行します。

  • 1 回の推論中に、利用可能なすべてのハードウェアをより効率良く利用します。

ヘテロジニアス・モードによる実行は、次の 2 つの独立したステップに分割できます:

  1. ハードウェア・アフィニティーを操作に設定します (ov::Core::query_model は Hetero デバイスによって内部的に使用されます)。

  2. モデルをヘテロジニアス・デバイスにコンパイルするには、モデルを分割し、(ov::device::priorities 経由で) 指定されたデバイス上でコンパイルし、ヘテロジニアス・モードで実行することを前提としています。モデルはアフィニティーに従ってサブグラフに分割され、同じアフィニティーを持つ接続された操作セットが専用のサブグラフになります。各サブグラフは専用デバイス上でコンパイルされ、複数の ov::CompiledModel オブジェクトが作成され、自動的に割り当てられた中間テンソルを介して接続されます。

    パイプラインの並列処理を設定すると (ov::hint::model_distribution_policy を介して)、モデルは複数のステージに分割され、各ステージは異なるデバイスに割り当てられます。1 つのステージの出力は、次のステージへの入力として供給されます。

この 2 つのステップは相互接続されておらず、アフィニティーは、手動モードまたは自動モードの 2 つの方法 (以下で説明) または組み合わせて使用する方法のいずれかに設定できます。

ヘテロデバイスの定義と構成#

OpenVINO™ 命名規則に従って、Hetero 実行プラグインには "HETERO" というラベルが割り当てられます。 追加のパラメーターなしで定義すると、デフォルトが使用されるか、次のセットアップ・オプションでさらに構成することができます:

パラメーター名と C++ プロパティー

プロパティー値

説明

“MULTI_DEVICE_PRIORITIES”
ov::device::priorities

HETERO: <device names>
(スペースなしのカンマ区切り)

選択可能なデバイスをリスト。
デバイスシーケンスは上位から下位へ優先されます。

アフィニティーを割り当てる手動モードと自動モード#

手動モード#

"affinity" キーを指定した ov::Node::get_rt_info を使用して、モデル内のすべての操作に対してアフィニティーを明示的に設定することを前提としています。

特定の操作を特定のデバイスに割り当てる場合、そのデバイスが実際にその操作をサポートすることを確認してくださいランダムに操作を選択し、アフィニティーを設定すると、モデルの精度が低下する可能性があります。これを回避するには、操作に組み込まれる定数操作など、関連する操作または操作のサブグラフを同じアフィニティーに設定するようにします。

 for op in model.get_ops(): 
    rt_info = op.get_rt_info() 
    rt_info["affinity"] = "CPU"
for (auto && op : model->get_ops()) { 
    op->get_rt_info()["affinity"] = "CPU"; 
}

自動モード#

専用デバイス (GPUCPU など) からのサポートに従って、どの操作がどのデバイスに割り当てられるか自動的に決定し、モデル照会ステップはモデルのコンパイル中にヘテロデバイスによって暗黙的に呼び出されます。

自動モードでは、“greedy (貪欲)” な動作により、指定した優先順位 (例: ov::device::priorities("GPU,CPU")) に従って、特定のデバイス向けのすべての操作がそのデバイスに割り当てられます。このレイヤーの前後に他の特別な操作がなければ、特定の操作を推論できないなど、デバイスの特性は考慮されていません。デバイスプラグインが HETERO デバイスによって構築されたサブグラフトポロジーをサポートしていない場合、アフィニティーを手動で設定する必要があります。

 import openvino.device as device 

compiled_model = core.compile_model(model, device_name="HETERO:GPU,CPU") 
# 構成プロパティーによるデバイスの優先順位 
compiled_model = core.compile_model( 
    model, device_name="HETERO", config={device.priorities: "GPU,CPU"} 
)
auto compiled_model = core.compile_model(model, "HETERO:GPU,CPU"); 
// または複数の引数を持つ ov::device::priorities  
compiled_model = core.compile_model(model, "HETERO", 
    ov::device::priorities("GPU", "CPU")); 
// または単一の引数を持つ ov::device::priorities 
compiled_model = core.compile_model(model, "HETERO", 
    ov::device::priorities("GPU,CPU"));

手動モードと自動モードを組み合わせて使用#

状況によっては、自動的に設定されたアフィニティーの手動調整を検討する必要があるかもしれません。通常、サブグラフの総数を最小限に抑えてメモリー転送を最適化します。これを行うには、自動的に割り当てられたアフィニティーを次のように “修正” する必要があります:

 # この例では、デフォルトのアフィニティー初期化を実行し、 
# 一部のレイヤーのアフィニティーを手動で修正する方法を示します 
device = "HETERO:GPU,CPU" 

# query_model の結果には、サポートされている操作とデバイスのマッピングが含まれます 
supported_ops = core.query_model(model, device) 

# 特定の操作のデフォルトのアフィニティーを手動で更新 
supported_ops["operation_name"] = "CPU" 

# モデルにアフィニティーを設定 
for node in model.get_ops(): 
    affinity = supported_ops[node.get_friendly_name()] 
    node.get_rt_info()["affinity"] = "CPU" 

# 手動で設定されたアフィニティーを持つモデルをロード 
compiled_model = core.compile_model(model, device)
// この例では、デフォルトのアフィニティー初期化を実行し、 
// 一部のレイヤーのアフィニティーを手動で修正する方法を示します 
const std::string device = "HETERO:GPU,CPU"; 

// query_model の結果には、サポートされている操作とデバイスのマッピングが含まれます 
auto supported_ops = core.query_model(model, device); 

// 特定の操作のデフォルトのアフィニティーを手動で更新 
supported_ops["operation_name"] = "CPU"; 

// モデルにアフィニティーを設定 
for (auto&& node : model->get_ops()) { 
    auto& affinity = supported_ops[node->get_friendly_name()]; 
    // op ランタイム情報を使用してアフィニティー・マッピングを保存 
    node->get_rt_info()["affinity"] = affinity; 
} 

// 手動で設定されたアフィニティーを持つモデルをロード 
auto compiled_model = core.compile_model(model, device);

重要なことは、モデル内の操作の "affinity" がすでに初期化されている場合、自動モードは機能しないことです。

フォールバック・デバイスを構成#

各種ヘテロ実行デバイスに異なるデバイス固有の構成オプションを持たせたい場合は、特別なヘルパー・プロパティー ov::device::properties を使用できます。

 import openvino.hint as hints 

core.set_property("HETERO", {device.priorities: "GPU,CPU"}) 
core.set_property("GPU", {properties.enable_profiling: True}) 
core.set_property("CPU", {hints.inference_precision: ov.Type.f32}) 
compiled_model = core.compile_model(model=model, device_name="HETERO")
auto compiled_model = core.compile_model(model, "HETERO", 
    // CPU へのフォールバック機能を備えた GPU 
    ov::device::priorities("GPU", "CPU"), 
    // プロファイリングは GPU に対してのみ有効 
    ov::device::properties("GPU", ov::enable_profiling(true)), 
    // FP32 推論精度は CPU のみ 
    ov::device::properties("CPU", 
ov::hint::inference_precision(ov::element::f32)) 
);

上の例では、GPU デバイスはプロファイル・データを有効にするように構成され、デフォルトの実行精度を使用しますが、CPU には fp32 で推論を実行する構成プロパティーがあります。

難解なトポロジーの処理#

一部のトポロジーは一部のデバイスでのヘテロ実行に適しておらず、実行を妨げる場合もあります。例えば、プライマリー・デバイスでサポートされていない活性化操作を持つモデルは、ヘテロジニアスによって複数のサブグラフのセットに分割され、最適な実行ができなくなります。ヘテロジニアス・モードでモデルの 1 つのサブグラフから別の部分にデータを送信するのに時間がかかる場合、ヘテロジニアス実行に適していない可能性があります。その場合、最も重い部分を手動で定義し、アフィニティーを設定して、1 回の推論中に頻繁にデータを送受信するのを避けることができます。

ヘテロジニアス実行のパフォーマンス分析#

OPENVINO_HETERO_VISUALIZE 環境変数を有効にすると、デバイスごとの操作のアノテーションを含む GraphViz.dot ファイルをダンプできます。

ヘテロジニアス実行モードでは、次の 2 つのファイルを生成できます:

  • hetero_affinity_<model name>.dot - 操作ごとのアフィニティーのアノテーション。

  • hetero_subgraphs_<model name>.dot - グラフごとのアフィニティーのアノテーション。

GraphViz ユーティリティーまたはファイル・コンバーターを使用して画像を表示できます。Ubuntu オペレーティング・システムでは、xdot を使用できます:

  • sudo apt-get install xdot

  • xdot hetero_subgraphs.dot

パフォーマンス・データ (サンプル・アプリケーションでは -pc オプション) を使用して、各サブグラフのパフォーマンス・データを取得できます。

CPU へのフォールバックを使用して HDDL (サポートされなくなったデバイス) で実行されている Googlenet v1 の出力例を示します:

subgraph1: 1. input preprocessing (mean data/HDDL):EXECUTED layerType: realTime: 129 cpu: 129 execType: 
subgraph1: 2. input transfer to DDR:EXECUTED layerType: realTime: 201 cpu: 0 execType: 
subgraph1: 3. HDDL execute time:EXECUTED layerType: realTime: 3808 cpu: 0 execType: 
subgraph1: 4. output transfer from DDR:EXECUTED layerType: realTime: 55 cpu: 0 execType: 
subgraph1: 5.HDDL output postprocessing:EXECUTED layerType: realTime: 7 cpu: 7 execType: 
subgraph1: 6. copy to IE blob:EXECUTED layerType: realTime: 2 cpu: 2 execType: 
subgraph2: out_prob: NOT_RUN layerType: Output realTime: 0 cpu: 0 execType: unknown 
subgraph2: prob: EXECUTED layerType: SoftMax realTime: 10 cpu: 10 execType: ref Total time: 4212 microseconds

サンプルの使い方#

OpenVINO™ サンプルプログラムでは、-d オプションを使用してヘテロジニアス実行を行うことができます。

./hello_classification <path_to_model>/squeezenet1.1.xml <path_to_pictures>/picture.jpg HETERO:GPU,CPU

説明:

  • HETERO はヘテロジニアス実行の略称です

  • GPU,CPU は、GPU を優先し CPU にフォールバックするポリシーを指します。

3 つ以上のデバイスを指定することもできます: -d HETERO:GPU,CPU

関連情報#