メディアパイプとの統合#

はじめに

MediaPipe は、任意の感覚データに対する推論を実行するパイプラインを構築するオープンソース・フレームワークです。画像およびメディア分析、生成 AI、トランスフォーマーなどの無制限のシナリオに適用できる幅広い計算機/ノードが付属しています。MediaPipe フレームワークの詳細については、こちらをご覧ください。

MediaPipe と OpenVINO モデルサーバーの統合により、グラフをネットワーク経由で公開し、負荷全体をリモートホストまたはマイクロサービスに委任できます。次のシナリオをサポートしています:

OpenVINO 計算機の導入により、OpenVINO ランタイム・バックエンドでの推論実行を最適化することができます。この計算ツールは、モデルサーバー内に展開されたグラフだけでなく、MediaPipe フレームワークを使用するスタンドアロン・アプリケーションにも適用できます。

mp_graph_modes

スタンドアロン MediaPipe アプリケーション内で OpenVINO 計算機を使用する方法については、MediaPipe GitHub フォークを確認してください。

このガイドでは、以下について説明します:

OpenVINO 計算機#

OpenVINO ランタイムのグラフ実行で利点をもたらす計算機のセットを導入します。

それらのドキュメントを参照してください。

PythonExecutorCalculator#

PythonExecutorCalculator はグラフノードでの Python コードの実行を有効にします。Python ノードをご覧ください。

PyTensorOvTensorConverterCalculator#

PyTensorOvTensorConverterCalculator により、PythonExecutorCalculator によって実行されるノードと、OV Tensor を受信および/または生成するノード間の変換が可能になります。

OpenVINO モデルサーバーにデプロイするグラフを作成する方法#

サポートされているグラフ入出力ストリームのパケットタイプ#

OpenVINO モデルサーバーは、グラフの入力および出力で複数のパケットタイプの処理をサポートします。次の表に、pbtxt グラフ定義でサポートされているタグとパケットのタイプを示します:

pbtxt ライン

入力/出力

タグ

パケットタイプ

ストリーム名

input_stream: “a”

入力

なし

ov::Tensor

a

output_stream: “b”

入力

なし

ov::Tensor

b

input_stream: “IMAGE:a”

入力

IMAGE

mediapipe::ImageFrame

a

output_stream: “IMAGE:b”

出力

IMAGE

mediapipe::ImageFrame

b

input_stream: “OVTENSOR:a”

出力

OVTENSOR

ov::Tensor

a

output_stream: “OVTENSOR:b”

出力

OVTENSOR

ov::Tensor

b

input_stream: “REQUEST:req”

入力

REQUEST

KServe inference::ModelInferRequest

req

output_stream: “RESPONSE:res”

出力

RESPONSE

KServe inference::ModelInferResponse

res

タグが欠落している場合、OpenVINO モデルサーバーはパケットタイプが `ov::Tensor' であると想定します。ストリーム名は任意に指定できますが、慣例として小文字を使用します。

MediaPipe IMAGE 変換に必要なデータレイアウトは HWC で、サポートされる精度は次のとおりです:

データタイプ

許可されるチャネル数

FP16

1,3,4

FP32

1.2

UINT8

1,3,4

INT8

1,3,4

UINT16

1,3,4

INT16

1,3,4

: MediaPipe ImageFrame 形式への入力のシリアル化では、KServe リクエスト内のデータを KServe API GRPC に基づく raw_input_contents フィールド、KServe API REST に基づくバイナリー拡張にカプセル化される必要があります。これは、triton-client などのクライアント・ライブラリーのデフォルト動作です。

クライアントが gRPC/REST 要求で入力を numpy 配列として送信すると、その入力はモデルサーバー側でグラフで指定された形式に逆シリアル化されます。例えば、グラフの入力タイプが IMAGE である場合、gRPC/REST クライアントは形状 (300, 300, 3) と精度 INT8 の入力データを送信できます。例えば、(1,300,300,1) などの形状でデータを送信することは、レイアウトと次元数が正しくないため許可されません。

入力グラフが OVTENSOR として設定される場合、入力の任意の形状と精度が許可されます。これは ov::Tensor オブジェクトに変換され、グラフに渡されます。例えば、入力は形状 (1,3,300,300) と精度 FP32 を持つことができます。テンソルがモデルで受け入れられない場合、計算機とグラフはエラーを返します。

gRPC 単項呼び出しと gRPC ストリーミングのコード例を確認してください。

OpenVINO モデルサーバーによるシリアル化および逆シリアル化でデータ変換を回避するオプションもあります。入力ストリームのタイプが REQUEST である場合、計算機にパススルーされます。受信側の計算機は、それを逆シリアル化し、すべてのコンテンツを解釈します。同様に、出力形式 RESPONSE は、クライアントへの完全な KServe 応答メッセージを作成する計算機に委任されます。これにより、任意のデータを raw_input_content に保存し、後でカスタム計算機でデコードできるため、データ形式に柔軟性が与えられます。

注: OpenVINOInferenceCalculator でサポートされているパケットタイプとタグのリスト (グラフの例を含む) については、OpenVINO モデルサーバーの計算機のドキュメントを確認してください。

サイドパケット#

サイドパケットは、グラフ初期化の開始時に計算機に渡すことができる特別なパラメーターです。オブジェクト検出のしきい値や処理するオブジェクト数を設定するなど、計算機の動作を調整できます。KServe API を使用すると、副入力パケットをグラフにプッシュすることもできます。これらは、KServe 要求パラメーターとして渡されます。タイプは、stringint64 または boolean にすることができます。gRPC ストリーム接続では、ストリーム内の最初の要求のみにサイド・パッケージ・パラメーターを含めることができることに注意してください。クライアント側では、以下のコード例は定義方法を示しています:

client.async_stream_infer( 
    model_name="model_name",
     inputs=[infer_input], parameters={'SIDE_PACKET_NAME': 10})

デフォルト計算機のリスト#

OpenVINO 推論計算機のほかに、モデルサーバーのパブリック Docker イメージには、デモで使用されるすべての計算機も含まれています。含まれるすべての計算機、サブグラフ、入出力ストリームハンドラーのリストは、追加パラメーター --log_level TRACE で開始されるモデルサーバーでレポートされます。

CPU と GPU の実行#

現時点では、パブリック Docker イメージに含まれる計算機は CPU 実行のみをサポートしています。これらはノード間でオブジェクトとホストメモリーからのメモリーバッファーを交換します。MediaPipe グラフでは GPU バッファーはサポートされていませんが、GPU ターゲットデバイスで推論操作を実行することはできます。入力データと応答は、GPU とホストメモリーの間で自動的に交換されます。シナリオでは、インテルのディスクリート GPU と統合 GPU に必要な依存関係が含まれているため、タグに -gpu サフィックスが付いたビルドイメージを使用してください。

GPU での完全なパイプライン実行は、将来のリリースでサポートされる予定です。

グラフのデプロイ#

グラフとモデルをパッケージ化する方法#

さまざまな環境でのグラフ・アーティファクトの配布と展開プロセスを簡素化するために、特定のフォルダー構造を作成することを推奨します:

mediapipe_graph_name/ 
├── graph.pbtxt 
├── model1 
│   └── 1
│       ├── model.bin 
│       └── model.xml 
├── model2 
│   └── 1 
│       ├── model.bin 
│       └── model.xml 
└── subconfig.json

graph.pbtxt には、メディアパイプ・グラフの定義が含まれる必要があります。subconfig.json は、メイン・モデル・サーバーの config.json 構成ファイルの拡張機能です。サブ構成には、グラフノードで使用されるモデルの定義が含まれている必要があります。これらはモデルサーバーの初期化中にロードされ、グラフの実行開始時に使用できるようになります。付属の OpenVINO 推論セッション計算ツールには、subconfig.json で構成されたモデル名への参照が含まれている必要があります。subconfig.json の例は次のとおりです:

{ 
    "model_config_list": [ 
        {"config": { 
            "name": "model1_name", 
            "base_path": "model1" 
           } 
        } 
    ] 
}

Mediapipe サーバブルを使用して OpenVINO モデルサーバーを起動#

MediaPipe サーバブル設定は、モデル設定ファイルと同様に同じ json ファイルに配置されます。モデルは model_config_list セクションで定義されますが、グラフは mediapipe_config_list セクションで設定されます。

MediaPipe グラフ・アーティファクトが上記のようにパッケージ化されている場合、OpenVINO モデルサーバーの構成は非常にシンプルです。デプロイするグラフのリストを含む config.json を準備するだけで済みます:

{ 
    "model_config_list": [], 
    "mediapipe_config_list": [ 
    { 
        "name":"mediapipe_graph_name" 
    }, 
    { 
        "name":"mediapipe2", 
        "base_path":"non_default_path" 
    } 
    ] 
}

MediaPipe グラフ内のノードは、model_config_list セクションとサブ構成で設定されたモデルの両方を参照できます。

MediaPipe 構成オプションの説明#

オプション

タイプ

説明

必須

"name"

文字列

gRPC/REST 要求で指定された名前フィールドに関連するグラフ識別子

はい

"base_path"

文字列

グラフ定義およびサブ構成ファイルへのパスは相対パスです。絶対パスまたはメイン構成パスに対する相対パスを指定できます。デフォルト値は “(main config path)(name)” です。

いいえ

"graph_path"

文字列

グラフ・プロト・ファイルへのパス。Base_path には絶対パスまたは相対パスを指定できます。デフォルトは、“(base_path)\graph.pbtxt” です。ファイルが存在する必要があります。

いいえ

"subconfig"

文字列

サブ構成ファイルへのパス。Base_path には絶対パスまたは相対パスを指定できます。デフォルトは、“(base_path)\subconfig.json” です。ファイルが見つからなくてもエラーにはなりません。

いいえ

サブ構成ファイルには、モデル設定ファイル と同じ形式で、model_config_list セクションのみを含めることができます。

デプロイのテスト#

デバッグログ#

グラフの実行を検証する最も簡単な方法は、モデルサーバーの log_levelDEBUG に設定することです。 docker run --rm -it -v $(pwd):/config openvino/model_server:latest --config_path /config/config.json --log_level DEBUG

グラフの初期化と実行から mediapipe フレームワーク内のすべての操作を詳細にレポートします。モデルサーバーのログにより、グラフの正しい形式と、必要なすべてのモデルが読み込まれていることを確認できます。グラフ定義のロードでは、すべての計算機がモデルサーバーにコンパイルされたかは確認されないことに注意してください。これは、要求を KServe エンドポイントに送信した後にテストできます。要求の処理中に、ログには計算機の初期化とノードの処理の情報が含まれます。

MediaPipe は、グラフの初期化中は入力ハンドラー設定を検証せず、グラフ作成ステージ (要求処理時) で検証することに注意してください。したがって、展開前にサンプル要求を KServe エンドポイントに送信して構成をテストすることを推奨します。

追跡#

現在、モデルサーバー側でのグラフトレースはサポートされていません。メディアパイプ・トレースを利用してグラフのボトルネックを特定する場合、メディアパイプ・アプリケーション・レベルからグラフをテストします。mediapipe の追跡に記載されている手順に従って、総合アプリと同様のサンプル・アプリケーションを構築します。

ベンチマーク#

グラフを実装してデプロイしたときに、パフォーマンスをテストにはいくつかのオプションがあります。単項要求のスループットを検証するには、ベンチマーク・クライアントを使用できます。

gRPC 接続のストリーミングには、rtsp_client を使用できます。RTSP ビデオストリーム、MPG4 ファイル、またはローカルカメラからのコンテンツに基づいて、gRPC ストリームと mediapipe グラフへの負荷を生成できます。

リモート・クライアントから MediaPipe グラフを使用#

MediaPipe グラフは、単項呼び出しとストリーミングの両方に同じ gRPC/REST KServe 推論 API を使用できます。どちらの場合でも、KServe API サポートを備えた同じクライアント・ライブラリーを使用できます。単項とストリーミングのクライアント・コードは異なります。こちらのコードを確認してください。

gRPC ストリーミング機能に関する情報も確認してください

グラフの状態については、GetModelStatusREST モデル状態GetModelMetadata および REST モデルメタデータ の呼び出しを使用して照会できます。

MediaPipe グラフと個々のモデルの違いは、バージョン管理にあります。MediaPipe グラフへのすべての呼び出しでは、version パラメーターは無視されます。MediaPipe グラフはバージョン管理されません。ただし、グラフ内のモデルの特定のバージョンを参照することはできます。

独自の mediapipe 計算機を OpenVINO モデルサーバーに追加#

MediaPipe グラフには、モデル・サーバー・イメージにビルトインされている計算機のみを含めることができます。独自のメディアパイプ計算機を OpenVINO モデルサーバー機能に追加する場合、それを依存関係として追加し、OpenVINO モデルサーバーのバイナリーを再構築する必要があります。

外部リポジトリーにある場合は、http_archive() 定義または git_repository() 定義を bazel WORKSPACE ファイルに追加する必要があります。次に、計算機ターゲットを bazel 依存関係として src/BUILD ファイルに追加する必要があります。これは次の場合に行う必要があります:

cc_library(
    name = "ovms_lib", 
...

deps プロパティーの conditions:default セクション内:

 deps = [ 
    "//:ovms_dependencies", 
    "//src/kfserving_api:kfserving_api_cpp", 
       ] + select({ 
    "//conditions:default": [ 
    "//src:ovmscalculatoroptions_cc_proto", # ovmscalculatoroptions_proto - just mediapipe stuff with mediapipe_proto_library adding nonvisible target 
    "@mediapipe_calculators//:mediapipe_calculators", 
    "@your_repository//:yourpathtocalculator/your_calculator

REGISTER_CALCULATOR(your_calculator) を確認してください。追加した計算機ファイルにはマクロが存在します。

MediaPipe グラフの例#

総合分析

画像分類

物体検出

マルチモデル

現時点の制限事項#

  • 文字列タイプの入力は、OVMS_PY_TENSOR としてタグ付けされた入力にのみサポートされます。

  • KServe の ModelMetadata 呼び出し応答には、入力名と出力名のみが含まれます。応答では、図形は空でデータタイプは "INVALID" になります。

  • バイナリー入力は、IMAGE および OVTENSOR タイプの MediaPipe グラフではサポートされていません。

  • サブ構成ファイルおよび mediapipe グラフファイルの更新によって、モデルサーバー構成のリロードはトリガーされません。サブ構成やグラフを含む完全な構成のリロードは、メイン構成 JSON ファイルを更新するか、REST API config/reload エンドポイントを使用して開始できます。

既知の問題#

  • MediaPipe の SyncSetInputStreamHandler オプションはグラフの検証中は検証されませんが、グラフの作成時には次のように検証されます:

input_stream: "INPUT:input" 
input_stream: "LOOPBACK:loopback" 
input_stream_handler { 
    input_stream_handler: "SyncSetInputStreamHandler", 
    options { 
        [mediapipe.SyncSetInputStreamHandlerOptions.ext] { 
            sync_set { 
                tag_index: "LOOPBACK:1" # wrong index example 
            } 
        } 
    } 
}

タグ LOOPBACK とインデックス 1 (正しいインデックスは 0) を持つ入力ストリームがないため、MediaPipe はアプリケーション全体を閉じます。したがって、運用環境にデプロイする前に、デプロイメントの設定が正しいかテストしてください。