Fehlerbehebung

Fehlender Pfad zur Python-Binärdatei

Fehlermeldung:

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

bedeutet in der Regel, dass Bazel die lokale Python-Binärdatei nicht findet. Um dieses Problem zu beheben, müssen Sie zuerst den Speicherort der Python-Binärdatei ermitteln und dann --action_env PYTHON_BIN_PATH=<path to python binary> zum Bazel-Befehl hinzufügen. Mit dem folgenden Befehl können Sie beispielsweise zur Verwendung des standardmäßigen Python3-Binärprogramms des Systems wechseln:

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

Erforderliche Python-Pakete fehlen

Fehlermeldung:

ImportError: No module named numpy
Is numpy installed?

bedeutet in der Regel, dass bestimmte Python-Pakete nicht installiert sind. Führen Sie je nach Python-Binärversion pip install oder pip3 install aus, um diese Pakete zu installieren.

Remote-Abhängigkeits-Repositories können nicht abgerufen werden

Fehlermeldung:

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)

bedeutet in der Regel, dass Bazel die erforderlichen Abhängigkeits-Repositories, die MediaPipe benötigt, nicht herunterladen kann. MediaPipe hat mehrere Abhängigkeits-Repositories, die von Google-Websites gehostet werden. In einigen Regionen müssen Sie möglicherweise einen Netzwerkproxy einrichten oder ein VPN verwenden, um auf diese Ressourcen zuzugreifen. Möglicherweise müssen Sie dem Bazel-Befehl auch --host_jvm_args "-DsocksProxyHost=<ip address> -DsocksProxyPort=<port number>" anhängen. Weitere Informationen finden Sie in diesem GitHub-Problem.

Wenn Sie der Meinung sind, dass es sich nicht um ein Netzwerkproblem handelt, könnte es sein, dass einige Ressourcen vorübergehend nicht verfügbar sind. Führen Sie bazel clean --expunge aus und versuchen Sie es später noch einmal. Wenn das Problem weiterhin besteht, erstellen Sie bitte ein GitHub-Problem mit der detaillierten Fehlermeldung.

Falsche MediaPipe OpenCV-Konfiguration

Fehlermeldung:

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)'

weist in der Regel darauf hin, dass OpenCV nicht richtig für MediaPipe konfiguriert ist. Im Abschnitt Installation unter „OpenCV und FFmpeg installieren“ erfahren Sie, wie Sie die WORKSPACE- und linux_opencv/macos_opencv/windows_opencv.BUILD-Dateien von MediaPipe für Ihre lokalen OpenCV-Bibliotheken ändern. Dieses GitHub-Problem kann Ihnen ebenfalls weiterhelfen.

Python pip-Installation fehlgeschlagen

Fehlermeldung:

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

nach der Ausführung von pip install mediapipe bedeutet in der Regel, dass für Ihr System keine qualifizierte MediaPipe Python-Version verfügbar ist. Beachten Sie, dass MediaPipe Python PyPI offiziell die 64‑Bit-Version von Python 3.7 bis 3.10 auf den folgenden Betriebssystemen unterstützt:

  • x86_64 Linux
  • x86_64 macOS 10.15 und höher
  • amd64 Windows

Wenn das Betriebssystem derzeit unterstützt wird und dieser Fehler weiterhin angezeigt wird, prüfen Sie, ob sowohl die Python- als auch die pip-Binärdatei für Python 3.7 bis 3.10 sind. Andernfalls können Sie das MediaPipe-Python-Paket lokal erstellen. Folgen Sie dazu dieser Anleitung.

Fehler beim Laden der Python-DLL unter Windows

Fehlermeldung:

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

bedeutet in der Regel, dass auf dem lokalen Windows-System Visual C++-Redistributable-Pakete und/oder Visual C++-Laufzeit-DLLs fehlen. Sie können das Problem beheben, indem Sie entweder die offizielle vc_redist.x64.exe oder das Python-Paket „msvc-runtime“ installieren. Führen Sie dazu Folgendes aus:

$ python -m pip install msvc-runtime

Das Python-Paket „msvc-runtime“ wird nicht von Microsoft veröffentlicht oder gepflegt.

Native Methode nicht gefunden

Fehlermeldung:

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

bedeutet in der Regel, dass eine erforderliche native Bibliothek wie /libwickjni.so nicht geladen oder nicht in die Abhängigkeiten der App aufgenommen wurde oder aus irgendeinem Grund nicht gefunden werden kann. In Java muss jede native Bibliothek explizit mit der Funktion System.loadLibrary geladen werden.

Kein registrierter Rechner gefunden

Fehlermeldung:

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

bedeutet in der Regel, dass auf OurNewCalculator in einer CalculatorGraphConfig per Name verwiesen wird, das Bibliothek-Ziel für OurNewCalculator aber nicht mit der Anwendungs-Binärdatei verknüpft wurde. Wenn einem Rechengraphen ein neuer Rechenbaustein hinzugefügt wird, muss dieser auch als Buildabhängigkeit der Anwendungen hinzugefügt werden, die den Rechengraphen verwenden.

Dieser Fehler wird bei der Laufzeit erkannt, da in Diagrammen für den Rechner über das Feld CalculatorGraphConfig::Node:calculator auf den Rechner verwiesen wird. Wenn die Bibliothek für einen Rechner in eine Anwendungs-Binärdatei eingebunden ist, wird der Rechner automatisch über das Makro REGISTER_CALCULATOR mithilfe der Bibliothek registration.h registriert. Beachten Sie, dass REGISTER_CALCULATOR einen Rechner mit einem Namespacepräfix registrieren kann, das mit seinem C++-Namespace identisch ist. In diesem Fall muss auch für die Grafik der Rechner das gleiche Namespacepräfix verwendet werden.

Fehler aufgrund fehlenden Arbeitsspeichers

Ein ausgelasteter Arbeitsspeicher kann ein Symptom dafür sein, dass sich zu viele Pakete in einem laufenden MediaPipe-Graphen ansammeln. Das kann verschiedene Ursachen haben, z. B.:

  1. Einige Computer in der Grafik können einfach nicht mit der Ankunft von Paketen aus einem Echtzeit-Eingabestream wie einer Videokamera Schritt halten.
  2. Einige Calculator warten auf Pakete, die nie ankommen.

Bei Problem 1 müssen möglicherweise einige alte Pakete verworfen werden, um die neueren Pakete zu verarbeiten. Einige Tipps finden Sie unter How to process realtime input streams.

Bei Problem 2 kann es sein, dass einem Eingabestream aus irgendeinem Grund Pakete fehlen. Ein Gerät oder ein Taschenrechner kann falsch konfiguriert sein oder nur sporadisch Pakete generieren. Dies kann dazu führen, dass Downstream-Rechner auf viele Pakete warten, die nie ankommen, was wiederum dazu führt, dass sich Pakete in einigen ihrer Eingabestreams ansammeln. In MediaPipe werden solche Probleme mithilfe von „Zeitstempelgrenzen“ behoben. Einige Hinweise finden Sie unter: How to process realtime input streams.

Mit der MediaPipe-Einstellung CalculatorGraphConfig::max_queue_size wird die Anzahl der Pakete begrenzt, die in einen Eingabestream eingereiht werden. Dazu wird die Eingabe in den Graphen gedrosselt. Bei Echtzeit-Eingabestreams sollte die Anzahl der Pakete, die in einem Eingabestream in der Warteschlange stehen, fast immer null oder eins sein. Ist das nicht der Fall, wird möglicherweise die folgende Warnmeldung angezeigt:

Resolved a deadlock by increasing max_queue_size of input stream

Außerdem kann die Einstellung CalculatorGraphConfig::report_deadlock so festgelegt werden, dass der Graph nicht ausgeführt wird und der Deadlock als Fehler angezeigt wird. In diesem Fall dient max_queue_size als Speichernutzungslimit.

Graph hängt

Viele Anwendungen rufen CalculatorGraph::CloseAllPacketSources und CalculatorGraph::WaitUntilDone auf, um die Ausführung eines MediaPipe-Graphen zu beenden oder zu pausieren. Ziel ist es, die Verarbeitung aller ausstehenden Calculators oder Pakete abzuschließen und dann die Grafik zu beenden. Wenn alles gut geht, erreicht jeder Stream im Diagramm Timestamp::Done und jeder Rechner CalculatorBase::Close. Dann wird CalculatorGraph::WaitUntilDone erfolgreich abgeschlossen.

Wenn einige Evaluatoren oder Streams den Status Timestamp::Done oder CalculatorBase::Close nicht erreichen können, kann die Methode CalculatorGraph::Cancel aufgerufen werden, um die Ausführung des Diagramms zu beenden, ohne auf den Abschluss aller ausstehenden Evaluatoren und Pakete zu warten.

Die Ausgabezeit ist ungleichmäßig

Einige Echtzeit-MediaPipe-Grafiken generieren eine Reihe von Videoframes, die als Videoeffekt oder als Videodiagnose angezeigt werden können. Manchmal werden diese Frames in einem MediaPipe-Graphen in Clustern erstellt, z. B. wenn mehrere Ausgabeframes aus demselben Cluster von Eingabeframes extrapoliert werden. Wenn die Ausgaben in der Reihenfolge ihrer Erstellung präsentiert werden, werden einige Ausgabeframes sofort durch spätere Frames im selben Cluster ersetzt, was die Ergebnisse visuell schwer zu sehen und zu bewerten macht. In solchen Fällen kann die Ausgabevisualisierung verbessert werden, indem die Frames in regelmäßigen Abständen in Echtzeit präsentiert werden.

MediaPipe löst diesen Anwendungsfall, indem Zeitstempel in Echtzeit Punkten zugeordnet werden. Jeder Zeitstempel gibt eine Zeit in Mikrosekunden an. Mit einem Rechner wie LiveClockSyncCalculator kann die Ausgabe von Paketen so verzögert werden, dass sie ihren Zeitstempeln entspricht. Bei dieser Art von Rechner wird das Timing der Ausgaben so angepasst, dass:

  1. Die Zeit zwischen den Ausgaben entspricht der Zeit zwischen den Zeitstempeln so genau wie möglich.
  2. Die Ausgabe erfolgt mit der geringstmöglichen Verzögerung.

CalculatorGraph bleibt hinter den Eingaben zurück

Bei vielen Echtzeit-MediaPipe-Grafiken ist eine geringe Latenz ein Ziel. MediaPipe unterstützt die parallele Verarbeitung im Pipeline-Verfahren, um mit der Verarbeitung jedes Pakets so früh wie möglich zu beginnen. Normalerweise ist die niedrigste mögliche Latenz die Gesamtzeit, die für jeden Rechner entlang eines „kritischen Pfades“ von aufeinanderfolgenden Rechnern erforderlich ist. Die Latenz einer MediaPipe-Grafik kann aufgrund von Verzögerungen, die beim Ausgeben von Frames in gleichmäßigen Intervallen auftreten, höher als die ideale Latenz sein. Weitere Informationen finden Sie unter Das Ausgabezeit-Timing ist ungleichmäßig.

Wenn einige der Rechner im Diagramm nicht mit den Echtzeit-Eingabestreams Schritt halten können, steigt die Latenz weiter an und einige Eingabepakete müssen verworfen werden. Wir empfehlen, die speziell für diesen Zweck entwickelten MediaPipe-Rechner zu verwenden, z. B. FlowLimiterCalculator, wie in How to process realtime input streams beschrieben.

Eingaben in den Rechner und Zeitstempel für Abrechnungen überwachen

Für das Debuggen von MediaPipe-Rechnern ist oft ein umfassendes Verständnis des Datenflusses und der Zeitstempelsynchronisierung erforderlich. Eingehende Pakete an Calculators werden zuerst in Eingabewarteschlangen pro Stream zwischengespeichert, um von der zugewiesenen InputStreamHandler synchronisiert zu werden. Die Aufgabe von InputStreamHandler besteht darin, den Eingabepaketsatz für einen festgelegten Zeitstempel zu ermitteln, wodurch der Rechner in den Status „Bereit“ versetzt wird. Anschließend wird ein Calculator::Process-Aufruf mit dem ermittelten Paketsatz als Eingabe ausgelöst.

Mit der DebugInputStreamHandler können eingehende Pakete und Zeitstempelabrechnungen in Echtzeit in der LOG(INFO)-Ausgabe der Anwendung erfasst werden. Sie kann bestimmten Rechnern über den input_stream_handler des Rechners oder global über das Feld „input_stream_handler“ von CalculatorGraphConfig zugewiesen werden.

Während der Ausführung des Graphen generieren eingehende Pakete LOG-Nachrichten, die den Zeitstempel und den Typ des Pakets enthalten, gefolgt vom aktuellen Status aller Eingabewarteschlangen:

[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

Außerdem können Sie damit Ereignisse zur Zeitstempelabwicklung überwachen, falls die DefaultInputStreamHandler angewendet wird. So können Sie eine unerwartete Erhöhung der Zeitstempelbindung in Eingabestreams erkennen, die zu einem Calculator::Process-Aufruf mit einer unvollständigen Eingabemenge führt, was wiederum zu leeren Paketen in (potenziell erforderlichen) Eingabestreams führt.

Beispiel:

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

Angenommen, ein Taschenrechner mit zwei Eingaben empfängt ein eingehendes Paket mit Zeitstempel 1 in Stream A, gefolgt von einem Eingabepaket mit Zeitstempel 2 in Stream B. Die Zeitstempelgrenze wird in Stream B auf 2 erhöht. Da in Stream A zu Zeitstempel 1 ein ausstehendes Eingabepaket vorhanden ist, wird der Calculator::Process-Aufruf mit einer unvollständigen Eingabe für Zeitstempel 1 ausgelöst. In diesem Fall gibt DefaultInputStreamHandler Folgendes aus:

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

VLOGs sind deine Freunde

In MediaPipe wird VLOG an vielen Stellen verwendet, um wichtige Ereignisse zu Debugging-Zwecken zu protokollieren. Die Leistung wird dadurch nicht beeinträchtigt, wenn die Protokollierung nicht aktiviert ist.

Weitere Informationen zu VLOG auf abseil VLOG

Beachten Sie, dass VLOG zu Spam führen kann, wenn Sie es beispielsweise mit dem Flag --v global aktivieren. Das Flag --vmodule der Lösung, mit dem für verschiedene Quelldateien unterschiedliche Ebenen festgelegt werden können.

Wenn --v / --vmodule nicht verwendet werden kann (z.B. beim Ausführen einer Android-App), können in MediaPipe VLOG---v / --vmodule-Flag-Überschreibungen für die Fehlerbehebung festgelegt werden, die beim Erstellen von CalculatorGraph angewendet werden.

Überschreibt:

  • MEDIAPIPE_VLOG_V: Wert für --v definieren und angeben
  • MEDIAPIPE_VLOG_VMODULE: Wert für --vmodule definieren und angeben

Sie können Überschreibungen festlegen, indem Sie Folgendes hinzufügen: --copt=-DMEDIAPIPE_VLOG_VMODULE=\"*calculator*=5\"

mit den gewünschten Modulmustern und VLOG-Ebenen (weitere Informationen zu --vmodule finden Sie unter abseil VLOG) in Ihren Build-Befehl ein.

WICHTIG: Wenn Sie den Build-Befehl um die oben genannten Optionen ergänzen, wird die gesamte Binärdatei einschließlich der Abhängigkeiten neu erstellt. Da VLOG-Überschreibungen nur zu Debugging-Zwecken existieren, ist es schneller, einfach vlog_overrides.cc zu ändern und ganz oben MEDIAPIPE_VLOG_V/VMODULE hinzuzufügen.

Nicht unterstützte Flags während des Builds

Wenn Sie Clang 18 oder älter verwenden, müssen Sie möglicherweise einige Compileroptimierungen in unserem CPU-Backend deaktivieren.

Wenn Sie die Unterstützung für avxvnniint8 deaktivieren möchten, fügen Sie Ihrem .bazelrc Folgendes hinzu:

build --define=xnn_enable_avxvnniint8=false