トラブルシューティング

Python バイナリのパスがない

エラー メッセージ:

ERROR: An error occurred during the fetch of repository 'local_execution_config_python':
  Traceback (most recent call last):
       File "/sandbox_path/external/org_tensorflow/third_party/py/python_configure.bzl", line 208
               get_python_bin(repository_ctx)
    ...
Repository command failed

通常、Bazel がローカル Python バイナリを見つけられないことを示します。この問題を解決するには、まず Python バイナリの場所を見つけて、Bazel コマンドに --action_env PYTHON_BIN_PATH=<path to python binary> を追加します。たとえば、次のコマンドを使用して、システムのデフォルトの python3 バイナリを使用するように切り替えることができます。

bazel build -c opt \
  --define MEDIAPIPE_DISABLE_GPU=1 \
  --action_env PYTHON_BIN_PATH=$(which python3) \
  mediapipe/examples/desktop/hello_world

必要な Python パッケージがない

エラー メッセージ:

ImportError: No module named numpy
Is numpy installed?

通常、特定の Python パッケージがインストールされていないことを示します。Python バイナリ バージョンに応じて pip install または pip3 install を実行して、これらのパッケージをインストールしてください。

リモート依存関係リポジトリを取得できない

エラー メッセージ:

ERROR: An error occurred during the fetch of repository 'org_tensorflow':
   java.io.IOException: Error downloading [https://mirror.bazel.build/github.com/tensorflow/tensorflow/archive/77e9ffb9b2bfb1a4f7056e62d84039626923e328.tar.gz, https://github.com/tensorflow/tensorflow/archive/77e9ffb9b2bfb1a4f7056e62d84039626923e328.tar.gz] to /sandbox_path/external/org_tensorflow/77e9ffb9b2bfb1a4f7056e62d84039626923e328.tar.gz: Tried to reconnect at offset 9,944,151 but server didn't support it

or

WARNING: Download from https://storage.googleapis.com/mirror.tensorflow.org/github.com/bazelbuild/rules_swift/releases/download/0.12.1/rules_swift.0.12.1.tar.gz failed: class java.net.ConnectException Connection timed out (Connection timed out)

通常、これは Bazel が MediaPipe に必要な依存関係リポジトリをダウンロードできないことを示します。MediaPipe には、Google サイトによってホストされている複数の依存関係リポジトリがあります。リージョンによっては、ネットワーク プロキシを設定するか、VPN を使用してこれらのリソースにアクセスする必要があります。Bazel コマンドに --host_jvm_args "-DsocksProxyHost=<ip address> -DsocksProxyPort=<port number>" を追加する必要が生じることもあります。詳しくは、GitHub でこの問題をご覧ください。

ネットワークの問題ではないと思われる場合は、一部のリソースが一時的に使用できない可能性もあります。bazel clean --expunge を実行して、後でもう一度お試しください。それでも問題が解決しない場合は、詳細なエラー メッセージを添えて GitHub の問題を報告してください。

MediaPipe OpenCV の構成が正しくない

エラー メッセージ:

error: undefined reference to 'cv::String::deallocate()'
error: undefined reference to 'cv::String::allocate(unsigned long)'
error: undefined reference to 'cv::VideoCapture::VideoCapture(cv::String const&)'
...
error: undefined reference to 'cv::putText(cv::InputOutputArray const&, cv::String const&, cv::Point, int, double, cv::Scalar, int, int, bool)'

通常、OpenCV が MediaPipe 用に正しく構成されていないことを示します。ローカルの opencv ライブラリ用に MediaPipe の WORKSPACE ファイルと linux_opencv/macos_opencv/windows_opencv.BUILD ファイルを変更する方法については、インストールの「OpenCV と FFmpeg をインストールする」をご覧ください。こちらの GitHub の問題も参考になります。

Python pip インストールの失敗

エラー メッセージ:

ERROR: Could not find a version that satisfies the requirement mediapipe
ERROR: No matching distribution found for mediapipe

pip install mediapipe の実行後に表示される場合は、通常、システムに適格な MediaPipe Python がないことを示します。MediaPipe Python PyPI は、次の OS で Python の 64 ビット バージョンを正式にサポートしています。

  • x86_64 Linux
  • x86_64 macOS 11.0 以降
  • arm64 macOS 11.0 以降
  • amd64 Windows

OS が現在サポートされていて、このエラーが引き続き表示される場合は、Python と pip バイナリの両方が MediaPipe でサポートされている Python バージョン用であることを確認してください。それ以外の場合は、こちらの手順に沿って MediaPipe Python パッケージをローカルにビルドすることを検討してください。

Windows で Python DLL の読み込みに失敗する

エラー メッセージ:

ImportError: DLL load failed: The specified module could not be found

通常、ローカル Windows システムに Visual C++ 再頒布可能パッケージまたは Visual C++ ランタイム DLL が不足していることを示します。この問題は、公式の vc_redist.x64.exe をインストールするか、次のコマンドを実行して「msvc-runtime」Python パッケージをインストールすることで解決できます。

$ python -m pip install msvc-runtime

「msvc-runtime」Python パッケージは、Microsoft によってリリースまたはメンテナンスされていません。

ネイティブ メソッドが見つかりません

エラー メッセージ:

java.lang.UnsatisfiedLinkError: No implementation found for void com.google.wick.Wick.nativeWick

通常、必要なネイティブ ライブラリ(/libwickjni.so など)が読み込まれていないか、アプリの依存関係に含まれていないか、なんらかの理由で見つからないことを示します。Java では、すべてのネイティブ ライブラリを関数 System.loadLibrary を使用して明示的に読み込む必要があります。

登録済みの計算機が見つかりません

エラー メッセージ:

No registered object with name: OurNewCalculator; Unable to find Calculator "OurNewCalculator"

通常、OurNewCalculatorCalculatorGraphConfig で名前で参照されているが、OurNewCalculator のライブラリ ターゲットがアプリケーション バイナリにリンクされていないことを示します。新しい計算機を計算機グラフに追加する場合は、その計算機を、計算機グラフを使用するアプリケーションのビルド依存関係として追加する必要があります。

このエラーは、計算機グラフがフィールド CalculatorGraphConfig::Node:calculator を介して計算機を名前で参照するため、実行時に検出されます。計算機のライブラリがアプリケーション バイナリにリンクされると、registration.h ライブラリを使用して REGISTER_CALCULATOR マクロを介して、計算機が名前で自動的に登録されます。REGISTER_CALCULATOR は、C++ 名前空間と同じ名前空間接頭辞を持つ計算機を登録できます。この場合、計算グラフでも同じ名前空間接頭辞を使用する必要があります。

メモリ不足エラー

メモリが不足するのは、実行中の MediaPipe グラフ内にパケットが蓄積しすぎている兆候です。次のような理由が考えられます。

  1. グラフ内の一部の計算機は、ビデオカメラなどのリアルタイム入力ストリームからのパケットの到着に追いつくことができません。
  2. 一部の計算機は、決して届かないパケットを待機しています。

問題(1)の場合、新しいパケットを処理するために、古いパケットの一部を破棄する必要があります。ヒントについては、How to process realtime input streams をご覧ください。

問題(2)の場合、なんらかの理由で 1 つの入力ストリームにパケットが不足している可能性があります。デバイスや計算機が正しく設定されていないか、パケットが散発的にしか生成されない可能性があります。これにより、下流の計算機が到着しない多くのパケットを待機し、一部の入力ストリームにパケットが蓄積される可能性があります。MediaPipe では、「タイムスタンプ境界」を使用してこの種の問題に対処します。ヒントについては、How to process realtime input streams をご覧ください。

MediaPipe の設定 CalculatorGraphConfig::max_queue_size は、グラフへの入力をスロットリングすることで、入力ストリームにキューに追加されるパケットの数を制限します。リアルタイム入力ストリームの場合、入力ストリームでキューに格納されるパケット数は、ほとんどの場合 0 または 1 です。そうでない場合は、次のような警告メッセージが表示されることがあります。

Resolved a deadlock by increasing max_queue_size of input stream

また、グラフの実行が失敗し、デッドロックがエラーとして表示されるように CalculatorGraphConfig::report_deadlock を設定することもできます。これにより、max_queue_size がメモリ使用量の上限として機能します。

グラフがハングする

多くのアプリでは、CalculatorGraph::CloseAllPacketSourcesCalculatorGraph::WaitUntilDone を呼び出して、MediaPipe グラフの実行を終了または一時停止します。ここでの目的は、保留中の計算機またはパケットが処理を完了できるようにしてから、グラフをシャットダウンすることです。問題がなければ、グラフ内のすべてのストリームが Timestamp::Done に到達し、すべての計算機が CalculatorBase::Close に到達し、CalculatorGraph::WaitUntilDone が正常に完了します。

一部の計算機またはストリームが状態 Timestamp::Done または CalculatorBase::Close に到達できない場合は、メソッド CalculatorGraph::Cancel を呼び出して、保留中のすべての計算機とパケットの完了を待たずにグラフの実行を終了できます。

出力のタイミングが不均一

一部のリアルタイム MediaPipe グラフは、動画エフェクトまたは動画診断として表示するための一連の動画フレームを生成します。複数の出力フレームが同じ入力フレームのクラスタから外挿される場合など、MediaPipe グラフはこれらのフレームをクラスタで生成することがあります。出力が生成された順に表示される場合は、一部の出力フレームが同じクラスタ内の後続のフレームにすぐに置き換えられるため、結果を視覚的に確認して評価することが難しくなります。このような場合は、フレームを均等な間隔でリアルタイムで表示することで、出力の可視化を改善できます。

MediaPipe は、タイムスタンプをポイントにリアルタイムでマッピングすることで、このユースケースに対応しています。各タイムスタンプはマイクロ秒単位の時間を示します。LiveClockSyncCalculator などの計算機を使用すると、タイムスタンプに一致するようにパケットの出力を遅らせることができます。この種の計算ツールは、次のように出力のタイミングを調整します。

  1. 出力間の時間は、タイムスタンプ間の時間にできるだけ近づけます。
  2. 出力は可能な限り遅延なく生成されます。

CalculatorGraph が入力に遅れる

多くのリアルタイム MediaPipe グラフでは、低レイテンシが目標です。MediaPipe は、「パイプライン化」されたスタイルの並列処理をサポートしており、各パケットの処理をできるだけ早く開始します。通常、可能な限り低いレイテンシは、連続する計算機の「クリティカル パス」に沿って各計算機に必要な合計時間です。出力のタイミングが不均一であるで説明されているように、フレームを均等な間隔で表示するために発生する遅延により、MediaPipe グラフのレイテンシが理想よりも悪くなる可能性があります。

グラフ内の計算機の一部がリアルタイム入力ストリームに追いつかないと、レイテンシは増加し続け、一部の入力パケットを破棄する必要があります。推奨される手法は、How to process realtime input streams で説明されているように、この目的に特化して設計された MediaPipe 計算ツール(FlowLimiterCalculator など)を使用することです。

計算機の入力とタイムスタンプの決済をモニタリングする

MediaPipe 計算ツールをデバッグするには、データフローとタイムスタンプの同期を深く理解している必要があります。計算機への受信パケットは、まずストリームごとに入力キューにバッファリングされ、割り当てられた InputStreamHandler によって同期されます。InputStreamHandler ジョブは、確定したタイムスタンプに対する入力パケットセットを決定します。これにより、計算機が「準備完了」状態になり、決定されたパケットセットを入力として Calculator::Process 呼び出しがトリガーされます。

DebugInputStreamHandler を使用すると、アプリケーションの LOG(INFO) 出力で受信パケットとタイムスタンプ決済をリアルタイムで追跡できます。これは、Calculator の input_stream_handler を介して特定の計算機に割り当てることも、CalculatorGraphConfig の input_stream_handler フィールドを介してグラフにグローバルに割り当てることもできます。

グラフの実行中に、受信パケットはログ メッセージを生成します。このログ メッセージには、パケットのタイムスタンプとタイプ、およびすべての入力キューの現在の状態が含まれます。

[INFO] SomeCalculator: Adding packet (ts:2, type:int) to stream INPUT_B:0:input_b
[INFO] SomeCalculator: INPUT_A:0:input_a num_packets: 0 min_ts: 2
[INFO] SomeCalculator: INPUT_B:0:input_b num_packets: 1 min_ts: 2

また、タイムスタンプ決済イベントのモニタリングも可能になります(DefaultInputStreamHandler が適用されている場合)。これにより、入力ストリームで予期しないタイムスタンプ境界の増加が明らかになり、不完全な入力セットで Calculator::Process が呼び出され、(必要となる可能性がある)入力ストリームに空のパケットが生成される可能性があります。

シナリオの例:

node {
  calculator: "SomeCalculator"
  input_stream: "INPUT_A:a"
  input_stream: "INPUT_B:b"
  ...
}

2 つの入力を持つ計算機で、ストリーム A でタイムスタンプ 1 の受信パケットを受信し、続いてストリーム B でタイムスタンプ 2 の入力パケットを受信します。タイムスタンプ上限がストリーム B で 2 に増加し、タイムスタンプ 1 でストリーム A に保留中の入力パケットがあると、タイムスタンプ 1 の不完全な入力セットで Calculator::Process 呼び出しがトリガーされます。この場合、DefaultInputStreamHandler の出力は次のようになります。

[INFO] SomeCalculator: Filled input set at ts: 1 with MISSING packets in input streams: INPUT_B:0:input_b.

VLOG が役に立つ

MediaPipe は多くの場所で VLOG を使用して、デバッグ目的で重要なイベントをロギングします。ロギングが有効になっていない場合、パフォーマンスには影響しません。

VLOG の詳細については、abseil VLOG をご覧ください。

VLOG をグローバルに有効にすると(--v フラグを使用するなど)、スパムになる可能性があることに注意してください。ソースファイルごとに異なるレベルを設定できるソリューション --vmodule フラグ。

--v / --vmodule を使用できない場合(Android アプリの実行など)、MediaPipe では、CalculatorGraph の作成時に適用されるデバッグ目的の VLOG --v / --vmodule フラグのオーバーライドを設定できます。

オーバーライド:

  • MEDIAPIPE_VLOG_V: --v に指定する値を定義して指定します。
  • MEDIAPIPE_VLOG_VMODULE: --vmodule に指定する値を定義して指定します。

オーバーライドは、次のように追加して設定できます。 --copt=-DMEDIAPIPE_VLOG_VMODULE=\"*calculator*=5\"

ビルドコマンドに、目的のモジュールパターンと VLOG レベル(--vmodule の詳細については、abseil VLOG をご覧ください)を指定します。

重要: 上記のコマンドをビルドコマンドに追加すると、依存関係を含むバイナリ全体の再ビルドがトリガーされます。VLOG オーバーライドはデバッグ目的でのみ存在することを考慮すると、一番上に MEDIAPIPE_VLOG_V/VMODULE を追加して vlog_overrides.cc を変更する方が簡単です。

ビルド時にサポートされていないフラグ

Clang 18 以前を使用している場合は、CPU バックエンドで一部のコンパイラ最適化を無効にする必要があります。

avxvnniint8 のサポートを無効にするには、.bazelrc に次の行を追加します。

build --define=xnn_enable_avxvnniint8=false