MediaPipe フレームワークから既存のグラフを更新して推論に OpenVINO を使用する方法#

このドキュメントでは、Tensorflow/TfLite を使用して既存の Mediapipe グラフを更新し、推論に OpenVINO ランタイムを使用できるようにする手順を説明します。このステップには以下が含まれます:

  • 既存のソリューションからモデルを取得

  • OpenVINOInferenceSession 計算機の構成を準備

  • 既存の pbtxt グラフに変更を加えて、TensorFlow 計算機を OpenVINO 計算機に置き換える

MediaPipe ソリューションで使用されるモデルを取得する方法#

MediaPipe アプリケーションまたはソリューションを google/mediapipe リポジトリーからビルドする場合、通常、bazel ビルドは必要なモデルをデータ依存関係としてダウンロードします。グラフを OpenVINO 推論計算機でデプロイする場合、モデルをモデル・リポジトリーに保存する必要があります。これにより、モデルのバージョン管理機能を利用し、モデルをローカルまたはクラウドストレージに保存できます。OpenVINO 計算機は、特定のモデル名を持つモデル構成を含む config.json ファイルへのパスをパラメーターとして使用します。MediaPipe デモで使用されるモデルを取得するには、そのモデルに依存する元のビルドターゲットをトリガーしてから Bazel キャッシュ内を検索するか、以下の場所から直接ダウンロードすることができます。

  • https://storage.googleapis.com/mediapipe-models/

  • https://storage.googleapis.com/mediapipe-assets/

OpenVINO モデルサーバーの構成を準備する方法#

OVMS 構成ファイルモデル・リポジトリーを準備する必要があります。異なる利点を持つ 2 つの方法があります:

  1. 同じデプロイ内の複数のパイプライン間でモデルを再利用する場合は、最初の方法を推奨します。この場合、servables ディレクトリー構造は次のようになります:

servables/
 ├── config.json
 ├── add_two_inputs_model
 │   └── 1
 │       ├── add.bin
 │       └── add.xml
 ├── dummy
 │   └── 1
 │       ├── dummy.bin
 │       └── dummy.xml
 └── dummyAdd 
     └── graph.pbtxt

config.json:

{ 
  "model_config_list": [ 
    { 
      "config": { 
        "name": "dummy", 
        "base_path": "dummy" 
      } 
    }, 
    { 
      "config": { 
        "name": "add", 
        "base_path": "add_two_inputs_model" 
      } 
    } 
  ] 
  "mediapipe_config_list": [ 
    { 
      "name":"dummyAdd" 
    } 
  ] 
}
  1. 2 つ目は、それぞれに個別のメディアパイプを含む複数のサービスがある場合に適しています。この方法により、デプロイの更新が容易になり、メディアパイプ構成を自己完結することができます。この場合、次のようにディレクトリーを準備します

servables/
 ├── config.json
 └── dummyAddGraph
     ├── add_two_inputs_model
     │   └── 1
     │       ├── add.bin
     │       └── add.xml
     ├── dummy
     │   └── 1
     │       ├── dummy.bin
     │       └── dummy.xml
     ├── graph.pbtxt
     └── subconfig.json

config.json:

{ 
  "model_config_list": [], 
  "mediapipe_config_list": [ 
    { 
      "name":"dummyAddGraph" 
    } 
  ] 
}

subconfig.json:

{ 
  "model_config_list": [ 
    { 
      "config": { 
        "name": "dummy", 
        "base_path": "dummy" 
      } 
    }, 
    { 
      "config": { 
        "name": "add", 
        "base_path": "add_two_inputs_model" 
      } 
    } 
  ] 
}

OpenVINO モデルサーバーの構成の詳細については、ドキュメントを参照してください。

: config.json のベースパスは、config.json のファイルパスに対する相対パスです。

これで、OpenVINO モデルサーバーの構成が完了しました。

OpenVINO モデルサーバーで推論を行うために既存のグラフを調整する方法#

以下に、OpenVINO を推論エンジンとして使用するように TensorFlow または TensorFlowLite 計算機を使用して既存のグラフを調整する手順を示します。これにより、グラフ全体の構造を維持しながら推論の実行を最適化できます。

1. ネストされたサブグラフで使用されるすべての推論計算機を特定#

サブグラフがない場合、この手順は必要ありません。このグラフから始めます。このグラフでは推論計算機を直接使用する方法がありません。これは、MediaPipe フレームワークの subgraph の概念を使用しているためです。既存のグラフを単一の計算機として登録できます。グラフ内でそのようなノードを検索し、推論計算機を直接使用している各サブグラフを検出する必要があります。以下の MediaPipe コードを grep できます:

grep -R -n "register_as = \"HolisticLandmarkCpu"

bazel mediapipe_simple_subgraph 関数を使用すると、別の pbtxt ファイルがグラフとして登録されていることがわかります。このファイルには推論計算機が存在しないため、サブグラフを使用して直接または間接的に使用されているすべての推論計算機が見つかるまで手順を繰り返す必要があります。

これらの手順により、調整が必要な推論ノードを含む pbtxt ファイルのリストが得られます。

2. グラフとサブグラフの推論計算機の置き換え#

必要に応じて、グラフおよびサブグラフ内の推論計算機の置き換えから始めます。既存の構成は次のようになります:

node { 
  calculator: "HandLandmarkModelLoader" 
  input_side_packet: "MODEL_COMPLEXITY:model_complexity" 
  output_side_packet: "MODEL:model" 
} 
node { 
  calculator: "InferenceCalculator" 
  input_side_packet: "MODEL:model" 
  input_stream: "TENSORS:input_tensor" 
  output_stream: "TENSORS:output_tensors" 
  options: { 
    [mediapipe.InferenceCalculatorOptions.ext] { 
      model_path: "mediapipe/modules/holistic_landmark/hand_recrop.tflite" 
      delegate { 
        xnnpack {} 
      } 
    } 
  } 
}

これにより、どのモデルが使用されているか (hand_recrop)、どのタイプのパケットが推論計算機 (vector\<mediapipe::Tensor\>) に送信されるかわかります。入力されたモデル名の情報も必要です。これは確認できます。モデルの読み込みまたはメタデータ要求呼び出しからの OVMS ログを使用します。その情報を使用して、グラフの部分を次のように置き換えます:

node { 
  calculator: "OpenVINOModelServerSessionCalculator" 
  output_side_packet: "SESSION:session" 
  node_options: { 
    [type.googleapis.com / mediapipe.OpenVINOModelServerSessionCalculatorOptions]: { 
      servable_name: "hand_recrop" 
      servable_version: "1" 
    } 
  } 
} 
node { 
  calculator: "OpenVINOInferenceCalculator" 
  input_side_packet: "SESSION:session" 
  input_stream: "TENSORS:initial_crop_tensor" 
  output_stream: "TENSORS:landmark_tensors" 
  node_options: { 
    [type.googleapis.com / mediapipe.OpenVINOInferenceCalculatorOptions]: { 
      tag_to_input_tensor_names { 
        key: "TENSORS" 
        value: "input_1" 
      } 
      tag_to_output_tensor_names { 
        key: "TENSORS" 
        value: "output_crop" 
      } 
    } 
  } 
}

OpenVINOModelServerSessionCalculator では、servable_name に前に見つけたモデルの名前を設定します。OpenVINOInferenceCalculator では、入力と出力タグ名が TENSORS で始まるようにします。次に、これらのタグを mediapipe.OpenVINOInferenceCalculatorOptions tag_to_input_tensor_names フィールドと tag_to_output_tensor_names フィールドで実際のモデル名にマッピングする必要があります。

2.1. 入力/出力テンソルの順序付けに関する情報を追加#

モデルに複数の入力または出力がある場合、この手順が必要になる場合があります。入力/出力パケットタイプが何らかのタイプのベクトルである場合、グラフで期待されるテンソルの正しい順序を理解する必要があります。モデルが複数の出力を生成すると仮定すると、次のセクションを OpenVINOInferenceCalculatorOptions に追加する必要があることがあります:

output_order_list: ["Identity","Identity_1","Identity_2","Identity_3"]

複数の入力の場合は、同様の手順を実行し、以下を追加します:

input_order_list: ["Identity","Identity_1","Identity_2","Identity_3"]

3. グラフの入出力ストリームを調整#

この手順は、OpenVINO モデルサーバーにグラフをデプロイする予定があり、既存のグラフにサポートされる入力/出力パケットタイプがない場合に必要です。こちらでサポートされる入力および出力パケットタイプを確認してください。その場合、ここで行ったようにコンバーター計算機を追加する必要があるかもしれません。

4. セッション計算ツールで config.json ファイルのパスを設定#

既存のアプリケーションでグラフを使用する場合は、この手順が必要です。次のように、OpenVINOModelServerSessionCalculatorOptionsserver_config フィールドに値を入力して、構成ファイルに完全なファイルパスを渡す必要があります:

node { 
  calculator: "OpenVINOModelServerSessionCalculator" 
  output_side_packet: "SESSION:session" 
  node_options: { 
    [type.googleapis.com / mediapipe.OpenVINOModelServerSessionCalculatorOptions]: { 
      servable_name: "hand_recrop" 
      servable_version: "1" 
      server_config: "/servables/config.json" 
    } 
  } 
}