Percorso del file binario Python mancante
Il messaggio di errore:
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
di solito indica che Bazel non riesce a trovare il file binario Python locale. Per risolvere questo problema, individua innanzitutto la posizione del file binario di Python, quindi aggiungi --action_env PYTHON_BIN_PATH=<path to python binary>
al comando Bazel. Ad esempio, puoi passare all'utilizzo del file binario python3 predefinito di sistema con il seguente comando:
bazel build -c opt \
--define MEDIAPIPE_DISABLE_GPU=1 \
--action_env PYTHON_BIN_PATH=$(which python3) \
mediapipe/examples/desktop/hello_world
Pacchetti Python necessari mancanti
Il messaggio di errore:
ImportError: No module named numpy
Is numpy installed?
in genere indica che alcuni pacchetti Python non sono installati. Esegui pip install
o pip3 install
a seconda della versione binaria di Python per installare i pacchetti.
Impossibile recuperare i repository delle dipendenze remote
Il messaggio di errore:
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)
in genere indica che Bazel non riesce a scaricare i repository delle dipendenze necessarie per MediaPipe. MediaPipe ha diversi repository di dipendenze ospitati da siti Google. In alcune regioni, potrebbe essere necessario configurare un proxy di rete o utilizzare una VPN per accedere a queste risorse. Potrebbe anche essere necessario aggiungere
--host_jvm_args "-DsocksProxyHost=<ip address> -DsocksProxyPort=<port number>"
al comando Bazel. Per maggiori dettagli, consulta
questo problema GitHub.
Se ritieni che non si tratti di un problema di rete, un'altra possibilità è che alcune risorse potrebbero essere temporaneamente non disponibili. Esegui bazel clean --expunge
e riprova più tardi. Se il problema persiste, segnala un problema su GitHub con il messaggio di errore dettagliato.
Configurazione errata di OpenCV di MediaPipe
Il messaggio di errore:
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)'
in genere indica che OpenCV non è configurato correttamente per MediaPipe. Consulta le sezioni "Installa OpenCV e FFmpeg" in Installazione per scoprire come modificare i file WORKSPACE e linux_opencv/macos_opencv/windows_opencv.BUILD di MediaPipe per le librerie opencv locali. Anche questa segnalazione di GitHub può esserti utile.
Errore di installazione di pip per Python
Il messaggio di errore:
ERROR: Could not find a version that satisfies the requirement mediapipe
ERROR: No matching distribution found for mediapipe
dopo l'esecuzione di pip install mediapipe
in genere indica che non è presente MediaPipe Python qualificato per il tuo sistema. Tieni presente che MediaPipe Python
PyPI supporta ufficialmente la versione a 64 bit di Python da 3.7 a 3.10 sui seguenti sistemi operativi:
- Linux x86_64
- x86_64 macOS 10.15 o versioni successive
- Windows amd64
Se il sistema operativo è attualmente supportato e continui a visualizzare questo errore, assicurati che sia il codice Python sia il codice pip siano per Python 3.7-3.10. In caso contrario, prendi in considerazione la possibilità di compilare il pacchetto Python MediaPipe in locale seguendo le istruzioni riportate qui.
Errore di caricamento della DLL di Python su Windows
Il messaggio di errore:
ImportError: DLL load failed: The specified module could not be found
di solito indica che nel sistema Windows locale mancano i pacchetti di Visual C++ riedistribuibili e/o le DLL di runtime di Visual C++. Il problema può essere risolto installando il file ufficiale vc_redist.x64.exe o il pacchetto Python "msvc-runtime" eseguendo
$ python -m pip install msvc-runtime
Tieni presente che il pacchetto Python "msvc-runtime" non viene rilasciato o gestito da Microsoft.
Metodo nativo non trovato
Il messaggio di errore:
java.lang.UnsatisfiedLinkError: No implementation found for void com.google.wick.Wick.nativeWick
in genere indica che una libreria nativa necessaria, ad esempio /libwickjni.so
, non è stata caricata o non è stata inclusa nelle dipendenze dell'app o non può essere trovata per qualche motivo. Tieni presente che Java richiede che ogni libreria nativa venga caricata esplicitamente utilizzando la funzione System.loadLibrary
.
Nessun calcolatore registrato trovato
Il messaggio di errore:
No registered object with name: OurNewCalculator; Unable to find Calculator "OurNewCalculator"
in genere indica che a OurNewCalculator
viene fatto riferimento per nome in un
CalculatorGraphConfig
, ma che la destinazione della libreria per OurNewCalculator non è stata collegata al file binario dell'applicazione. Quando si aggiunge una nuova calcolatrice al grafico, questa deve essere aggiunta anche come dipendenza della build delle applicazioni che utilizzano il grafico della calcolatrice.
Questo errore viene rilevato in fase di runtime perché i grafici del calcolatore fanno riferimento ai calcolatori per nome tramite il campo CalculatorGraphConfig::Node:calculator
.
Quando la libreria di una calcolatrice è collegata a un file binario dell'applicazione, la calcolatrice viene registrata automaticamente per nome tramite la macro REGISTER_CALCULATOR
utilizzando la libreria registration.h
. Tieni presente che
REGISTER_CALCULATOR
può registrare una calcolatrice con un prefisso dello spazio dei nomi,
identico allo spazio dei nomi C++. In questo caso, anche il grafico del calcolatore deve utilizzare lo stesso prefisso dello spazio dei nomi.
Errore di memoria insufficiente
L'esaurimento della memoria può essere un sintomo di un numero eccessivo di pacchetti che si accumulano all'interno di un gráfo MediaPipe in esecuzione. Questo può accadere per diversi motivi, ad esempio:
- Alcuni calcolatori nel grafico non riescono semplicemente a tenere il passo con l'arrivo di pacchetti da uno stream di input in tempo reale, ad esempio una videocamera.
- Alcune calcolatrici sono in attesa di pacchetti che non arriveranno mai.
Per il problema (1), potrebbe essere necessario eliminare alcuni pacchetti meno recenti per elaborare quelli più recenti. Per alcuni suggerimenti, consulta:
How to process realtime input streams
.
Per il problema (2), è possibile che uno stream di input manchi di pacchetti per qualche motivo. Un dispositivo o una calcolatrice potrebbe essere configurato in modo errato o produrre pacchetti solo sporadicamente. Ciò può causare l'attesa di molti calcolatori a valle per molti pacchetti che non arriveranno mai, il che a sua volta causa l'accumulo di pacchetti su alcuni dei loro stream di input. MediaPipe risolve questo tipo di problema utilizzando
"limiti di timestamp". Per alcuni suggerimenti, consulta:
How to process realtime input streams
.
L'impostazione MediaPipe CalculatorGraphConfig::max_queue_size
limita il numero di pacchetti in coda su qualsiasi stream di input regolando gli input al grafico. Per gli stream di input in tempo reale, il numero di pacchetti in coda in uno stream di input dovrebbe essere quasi sempre pari a zero o uno. In caso contrario, potresti visualizzare il seguente messaggio di avviso:
Resolved a deadlock by increasing max_queue_size of input stream
Inoltre, l'impostazione CalculatorGraphConfig::report_deadlock
può essere impostata in modo da causare il fallimento dell'esecuzione del grafico e mostrare il deadlock come errore, in modo che max_queue_size agisca come limite di utilizzo della memoria.
Blocchi del grafico
Molte applicazioni chiameranno CalculatorGraph::CloseAllPacketSources
e
CalculatorGraph::WaitUntilDone
per terminare o sospendere l'esecuzione di un grafo MediaPipe. L'obiettivo è consentire a eventuali calcolatori o pacchetti in attesa di completare l'elaborazione e poi di arrestare il grafico. Se tutto va bene, ogni stream nel grafico raggiungerà Timestamp::Done
e ogni calcolatrice raggiungerà CalculatorBase::Close
, quindi CalculatorGraph::WaitUntilDone
verrà completato correttamente.
Se alcuni calcolatori o stream non riescono a raggiungere lo stato Timestamp::Done
o
CalculatorBase::Close
, è possibile chiamare il metodo CalculatorGraph::Cancel
per interrompere l'esecuzione del grafico senza attendere il completamento di tutti i calcolatori e i pacchetti in attesa.
La temporizzazione dell'output non è uniforme
Alcuni grafici MediaPipe in tempo reale producono una serie di frame video da visualizzare come effetto video o come diagnostica video. A volte, un grafo MediaPipe produce questi frame in cluster, ad esempio quando diversi frame di output vengono estrapolati dallo stesso cluster di frame di input. Se gli output vengono presentati man mano che vengono prodotti, alcuni frame di output vengono sostituiti immediatamente da quelli successivi nello stesso cluster, il che rende difficile vedere e valutare i risultati visivamente. In questi casi, la visualizzazione dell'output può essere migliorata presentando i frame a intervalli regolari in tempo reale.
MediaPipe risolve questo caso d'uso mappando i timestamp ai punti in tempo reale.
Ogni timestamp indica un'ora in microsecondi e un calcolatore come
LiveClockSyncCalculator
può ritardare l'output dei pacchetti in modo che corrispondano ai relativi
timestamp. Questo tipo di calcolatrice regola la temporizzazione delle uscite in modo che:
- Il tempo tra le uscite corrisponde al tempo tra i timestamp il più possibile.
- Le uscite vengono prodotte con il ritardo più breve possibile.
CalculatorGraph non segue gli input
Per molti grafici MediaPipe in tempo reale, la latenza ridotta è un obiettivo. MediaPipe supporta l'elaborazione parallela in stile "pipeline" per iniziare l'elaborazione di ogni pacchetto il prima possibile. In genere, la latenza più bassa possibile è il tempo totale richiesto da ogni calcolatore lungo un "percorso critico" di calcolatori successivi. La latenza di un grafico MediaPipe potrebbe essere peggiore di quella ideale a causa dei ritardi introdotti per visualizzare i frame a intervalli regolari come descritto in La temporizzazione dell'output non è uniforme.
Se alcuni dei calcolatori nel grafico non riescono a tenere il passo con gli stream di input in tempo reale, la latenza continuerà ad aumentare e sarà necessario eliminare alcuni pacchetti di input. La tecnica consigliata è utilizzare i calcolatori MediaPipe progettati appositamente per questo scopo, come FlowLimiterCalculator
, come descritto in How to process realtime input streams
.
Monitora gli input del calcolatore e i calcoli dei timestamp
Il debug dei calcolatori MediaPipe spesso richiede una conoscenza approfondita del flusso di dati e della sincronizzazione dei timestamp. I pacchetti in arrivo ai calcolatori vengono prima memorizzati nella coda di input per ogni stream in modo da essere sincronizzati dal InputStreamHandler
assegnato. Il compito del job InputStreamHandler
è determinare il set di pacchetti di input per un timestamp stabilito, che mette la calcolatrice in stato "pronta", seguito dall'attivazione di una chiamata Calculator::Process con il set di pacchetti determinato come input.
DebugInputStreamHandler
può essere utilizzato per monitorare i pacchetti in entrata e
i calcoli dei timestamp in tempo reale nell'output LOG(INFO) dell'applicazione. Può essere assegnata a calcolatori specifici tramite input_stream_handler del calcolatore o al grafico a livello globale tramite il campo input_stream_handler di CalculatorGraphConfig
.
Durante l'esecuzione del grafico, i pacchetti in arrivo generano messaggi LOG che rivelano il timestamp e il tipo di pacchetto, seguito dallo stato corrente di tutte le code di input:
[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
Inoltre, consente il monitoraggio degli eventi di regolamento del timestamp (se viene applicato DefaultInputStreamHandler
). In questo modo è possibile rilevare un aumento inaspettato del limite di timestamp negli stream di input che genera una chiamata Calculator::Process con un insieme di input incompleto che genera pacchetti vuoti negli stream di input (potenzialmente richiesti).
Scenario di esempio:
node {
calculator: "SomeCalculator"
input_stream: "INPUT_A:a"
input_stream: "INPUT_B:b"
...
}
Dato un calcolatore con due input, riceve un pacchetto in entrata con timestamp 1 sullo stream A seguito da un pacchetto di input con timestamp 2 sullo stream B. L'aumento del limite del timestamp a 2 nello stream B con un pacchetto di input in attesa nello stream A al timestamp 1 attiva la chiamata Calculator::Process con un insieme di input incompleto per il timestamp 1. In questo caso, DefaultInputStreamHandler
restituisce:
[INFO] SomeCalculator: Filled input set at ts: 1 with MISSING packets in input streams: INPUT_B:0:input_b.
I vlog sono tuoi amici
MediaPipe utilizza VLOG
in molti punti per registrare eventi importanti a scopo di debugging, senza influire sulle prestazioni se la registrazione non è attivata.
Scopri di più su VLOG
su abseil VLOG
Tieni presente che VLOG
può essere considerato spam se lo attivi a livello globale, ad esempio utilizzando il flag --v
. Il flag --vmodule
della soluzione che consente di impostare livelli diversi per
diversi file di origine.
Nei casi in cui non è possibile utilizzare --v
/ --vmodule
(ad es. quando viene eseguita un'app per Android), MediaPipe consente di impostare sostituzioni di flag VLOG
--v
/ --vmodule
per scopi di debug, che vengono applicate quando viene creato CalculatorGraph
.
Sostituzioni:
MEDIAPIPE_VLOG_V
: definisci e fornisci il valore che offri per--v
MEDIAPIPE_VLOG_VMODULE
: definisci e offri il valore che offri per--vmodule
Puoi impostare le sostituzioni aggiungendo:
--copt=-DMEDIAPIPE_VLOG_VMODULE=\"*calculator*=5\"
con i pattern dei moduli e i livelli VLOG
che preferisci (vedi maggiori dettagli su VLOG
in abseil VLOG
) al comando di compilazione.--vmodule
IMPORTANTE: tieni presente che l'aggiunta del codice precedente al comando di compilazione attiverà la ricostruzione
dell'intero file binario, incluse le dipendenze. Pertanto, poiché le sostituzioni VLOG
esistono solo per scopi di debug, è più veloce modificare semplicemente vlog_overrides.cc
aggiungendo MEDIAPIPE_VLOG_V/VMODULE
in alto.
Flag non supportati durante la compilazione
Se utilizzi Clang 18 o versioni precedenti, potresti dover disattivare alcune ottimizzazioni del compilatore nel nostro backend della CPU.
Per disattivare il supporto di avxvnniint8
, aggiungi quanto segue a .bazelrc
:
build --define=xnn_enable_avxvnniint8=false