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.:
- Einige Computer in der Grafik können einfach nicht mit der Ankunft von Paketen aus einem Echtzeit-Eingabestream wie einer Videokamera Schritt halten.
- 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:
- Die Zeit zwischen den Ausgaben entspricht der Zeit zwischen den Zeitstempeln so genau wie möglich.
- 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 angebenMEDIAPIPE_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