פתרון בעיות

חסר נתיב בינארי של 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 ולהוסיף את --action_env PYTHON_BIN_PATH=<path to python binary> לפקודה Bazel. לדוגמה, תוכלו לעבור להשתמש בקובץ הבינארי 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 מסוימות לא מותקנות. כדי להתקין את החבילות האלה, מריצים את pip install או את pip3 install בהתאם לגרסה הבינארית של Python.

השליפה של מאגרי התלות מרחוק נכשלה

הודעת השגיאה:

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. ב-MedaiPipe יש כמה מאגרי תלות שמתארחים באתרים של Google. יכול להיות שבאזורים מסוימים תצטרכו להגדיר שרת proxy של רשת או להשתמש ב-VPN כדי לקבל גישה למשאבים האלה. יכול להיות שתצטרכו גם לצרף את --host_jvm_args "-DsocksProxyHost=<ip address> -DsocksProxyPort=<port number>" לפקודה Bazel. לפרטים נוספים, ראו בעיה זו ב-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 ו-FFmpeg" שבהתקנה כדי לראות איך לשנות את קובצי WORKSPACE ו-WORKSPACE של MediaPipe linux_opencv/macos_opencv/windows_opencv.BUILD בספריות opencv המקומיות שלך. גם הבעיה הזו ב-GitHub יכולה לעזור.

התקנת PIP של Python נכשלה

הודעת השגיאה:

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

אחרי הרצה של pip install mediapipe, מופיע בדרך כלל שאין Python תואם ל-MediaPipe במערכת. שימו לב: MediaPipe Python PyPI תומך באופן רשמי בגרסת 64 סיביות של Python 3.7 עד 3.10 במערכות ההפעלה הבאות:

  • x86_64 Linux
  • x86_64 macOS מגרסה 10.15 ואילך
  • amd64 Windows

אם יש תמיכה במערכת ההפעלה כרגע ועדיין מופיעה השגיאה הזו, צריך לוודא שהבינארי של Python ו-PIP מיועד ל-Python בגרסאות 3.7 עד 3.10. אם לא, כדאי ליצור את חבילת MediaPipe Python באופן מקומי לפי ההוראות שמפורטות כאן.

כשל בטעינת Python DLL ב-Windows

הודעת השגיאה:

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

בדרך כלל מציין שבמערכת Windows המקומית חסרות חבילות להפצה חוזרת של Visual C++ ו/או Visual C++ DLLs. כדי לפתור את הבעיה, אפשר להתקין את vc_redist.x64.exe או להתקין את חבילת Python "msvc-runtime" באמצעות הרצת

$ python -m pip install msvc-runtime

שימו לב שחבילת Python "msvc-runtime" לא הושקה ולא מתוחזקת על ידי 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"

בדרך כלל מציין ש-CalculatorGraphConfig מפנה ל-OurNewCalculator בשם, אבל יעד הספרייה של OurNewCalculator לא מקושר לקובץ הבינארי של האפליקציה. כשמוסיפים מחשבון חדש לתרשים המחשבון, צריך להוסיף אותו גם כתלות build של האפליקציות באמצעות תרשים המחשבון.

השגיאה הזו אותרה בזמן הריצה, מפני שגרפים של המחשבון מפנים למחשבונים שלהם לפי שם בשדה CalculatorGraphConfig::Node:calculator. כשהספרייה של מחשבון מקושר לקובץ בינארי של אפליקציה, המחשבון נרשם אוטומטית לפי שם באמצעות המאקרו REGISTER_CALCULATOR באמצעות הספרייה registration.h. שימו לב ש-REGISTER_CALCULATOR יכול לרשום מחשבון עם קידומת של מרחב שמות, שזהה למרחב השמות של C++ שלו. במקרה הזה, גם תרשים המחשבון צריך להשתמש באותה קידומת של מרחב שמות.

שגיאת 'אין זיכרון'

מיצוי זיכרון עלול להיות תסמין של יותר מדי חבילות שמסתברות בתוך תרשים MediaPipe פעיל. יכולות להיות לכך כמה סיבות, למשל:

  1. מחשבונים מסוימים בגרף לא יכולים לעמוד בקצב קבלת המנות מזרם קלט בזמן אמת, כמו מצלמת וידאו.
  2. מחשבונים מסוימים ממתינים לחבילות שלא יגיעו לעולם.

במקרה של בעיה (1), יכול להיות שיהיה צורך לשחרר חלק מהחבילות הישנות כדי לעבד את החבילות החדשות יותר. לרמזים מסוימים, ראו: How to process realtime input streams.

במקרה של בעיה (2), יכול להיות שבשידור קלט אחד חסרות חבילות, מסיבה כלשהי. יכול להיות שמכשיר או מחשבון לא הוגדרו כראוי או שהם מייצרים חבילות באופן אקראי בלבד. בעקבות זאת, מחשבונים במורד הזרם (downstream) עלולים להמתין לחבילות רבות שלא יגיעו לעולם, וכתוצאה מכך החבילות להצטבר בחלק ממקורות הקלט. בעזרת MediaPipe אפשר לפתור בעיות מהסוג הזה באמצעות 'גבולות חותמת הזמן'. לחלק מהרמזים, ראו: How to process realtime input streams.

ההגדרה CalculatorGraphConfig::max_queue_size של MediaPipe מגבילה את מספר המנות שנכנסות לתור בכל שידור קלט, באמצעות ויסות נתונים של קלט בתרשים. לתזרמי קלט בזמן אמת, מספר המנות בתור בזרם קלט צריך להיות כמעט תמיד אפס או אחת. אם זה לא המצב, ייתכן שתוצג הודעת האזהרה הבאה:

Resolved a deadlock by increasing max_queue_size of input stream

בנוסף, אפשר להגדיר את ההגדרה CalculatorGraphConfig::report_deadlock כדי לגרום להפעלת התרשים להיכשל ולהציג את המנעול כשגיאה, כך ש-max_queue_size ישמש כמגבלת שימוש בזיכרון.

הגרף נתקע

אפליקציות רבות יקראו ל-CalculatorGraph::CloseAllPacketSources ול-CalculatorGraph::WaitUntilDone כדי לסיים או להשעות את ההפעלה של תרשים MediaPipe. המטרה כאן היא לאפשר לכל החבילות או המחשבוןונים בהמתנה להשלים את העיבוד, ואז לסגור את התרשים. אם הכול תקין, כל זרם בגרף יגיע אל Timestamp::Done, וכל מחשבון יגיע אל CalculatorBase::Close ואז CalculatorGraph::WaitUntilDone ישלימו בהצלחה.

אם חלק מהמחשבים או מהזרמים לא יכולים להגיע למצב Timestamp::Done או CalculatorBase::Close, אפשר לקרוא לשיטה CalculatorGraph::Cancel כדי לסיים את הרצת התרשים בלי להמתין להשלמת כל החבילות והמחשבון הממתינים.

תזמון הפלט לא שווה

חלק מתרשימי MediaPipe בזמן אמת מייצרים סדרה של פריימים של וידאו לצפייה כאפקט של סרטון או כאבחון וידאו. לפעמים, תרשים MediaPipe ייצור את הפריימים האלה באשכולות, לדוגמה כשמתבצעת אקסטרציה של מספר פריימים של פלט מאותו אשכול של מסגרות קלט. במקרה שהפלטים מוצגים כפי שהם מופקים, חלק מהפריימים של הפלט מוחלפים מיד בפריימים מאוחרים יותר באותו אשכול, ולכן קשה לראות ולהעריך את התוצאות באופן חזותי. במקרים כאלה, אפשר לשפר את התצוגה החזותית של הפלט על ידי הצגת הפריימים במרווחים שווים בזמן אמת.

הכלי MediaPipe מטפל בתרחיש לדוגמה הזה על ידי מיפוי חותמות זמן לנקודות בזמן אמת. כל חותמת זמן מציינת את הזמן במיליוניות השנייה, ומחשבון כמו LiveClockSyncCalculator יכול לעכב את פלט החבילות כך שיתאימו לחותמות הזמן שלהן. מחשבון כזה מתאים את התזמון של הפלטים כך:

  1. הזמן בין חותמות הזמן תואם ככל האפשר לזמן בין חותמות הזמן.
  2. הפלטים נוצרים עם השהיה קטנה ככל האפשר.

המחשבון מתעכב מאחורי קלט

עבור גרפים רבים של MediaPipe בזמן אמת, זמן אחזור נמוך הוא מטרה. ב-MediaPipe יש תמיכה בעיבוד מקביל בסגנון 'צינור עיבוד' כדי להתחיל לעבד כל חבילה מוקדם ככל האפשר. בדרך כלל זמן האחזור הנמוך ביותר הוא הזמן הכולל שנדרש לכל מחשבון ב'נתיב קריטי' של מחשבונים עוקבים. זמן האחזור של תרשים MediaPipe יכול להיות גרוע יותר מהאידיאלי, כי עיכובים בהצגת הפריימים במרווחים שווים, כפי שמתואר בתזמון הפלט לא ישר.

אם חלק מהמחשבים בגרף לא מתאימים לתזרמי הקלט בזמן אמת, זמן האחזור ימשיך לגדול ויהיה צורך לשחרר כמה מנות קלט. השיטה המומלצת היא להשתמש במחשבוני MediaPipe שמיועדים במיוחד למטרה הזו, כמו FlowLimiterCalculator כפי שמתואר ב-How to process realtime input streams.