تحديد المشاكل وحلّها

عدم توفّر مسار ملف 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. تتضمّن MediaPipe عدة مستودعات للتبعيات تديرها مواقع Google الإلكترونية. في بعض المناطق، قد تحتاج إلى إعداد خادم وكيل للشبكة أو استخدام شبكة 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 و linux_opencv/macos_opencv/windows_opencv.BUILD في MediaPipe لتعديل مكتبات opencv المحلية. قد تساعدك أيضًا هذه المشكلة على 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 متوافقة رسميًا مع الإصدار 64 بت من Python 3.7 إلى 3.10 على نظام التشغيل التالي:

  • ‫x86_64 Linux
  • الإصدار 10.15 من نظام التشغيل macOS أو إصدار أحدث بمعمارية x86_64
  • 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++ DLL لوقت التشغيل. يمكن حلّ هذه المشكلة من خلال إما تثبيت الإصدار الرسمي من 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"

يشير عادةً إلى أنّه تمت الإشارة إلى OurNewCalculator بالاسم في CalculatorGraphConfig ولكن لم يتم ربط ملف مكتبة OurNewCalculator بملف التطبيق الثنائي. عند إضافة حاسبة جديدة إلى رسم بياني للحاسبة، يجب أيضًا إضافة هذه الحاسبة كعنصر يشترط إكماله لبناء التطبيقات التي تستخدم الرسم البياني للحاسبة.

يتم رصد هذا الخطأ أثناء التشغيل لأنّ الرسوم البيانية للآلة الحاسبة تشير إلى آلات الحاسبة بالاسم من خلال الحقل CalculatorGraphConfig::Node:calculator. عند ربط مكتبة الآلة الحاسبة بملف ثنائي للتطبيق، يتم تسجيل الآلة الحاسبة تلقائيًا حسب الاسم من خلال الماكرو REGISTER_CALCULATOR باستخدام مكتبة registration.h. يُرجى العِلم أنّه يمكن REGISTER_CALCULATOR تسجيل آلة حاسبة باستخدام بادئة مساحة اسم، تكون مطابقة لمساحة الاسم في C++. في هذه الحالة، يجب أن يستخدم الرسم البياني للحاسبة أيضًا بادئة مساحة الاسم نفسها.

خطأ "نفاد الذاكرة"

يمكن أن يكون استنزاف الذاكرة أحد أعراض تراكم عدد كبير جدًا من الحِزم داخل gráf MediaPipeقيد التشغيل. يمكن أن يحدث ذلك لعدد من الأسباب، مثل:

  1. لا يمكن لبعض الآلات الحاسبة في الرسم البياني مواكبة وصول الحِزم من مصدر إدخال في الوقت الفعلي، مثل كاميرا فيديو.
  2. تنتظر بعض الآلات الحاسبة حِزمًا لن تصل أبدًا.

بالنسبة إلى المشكلة (1)، قد يكون من الضروري إسقاط بعض الحِزم القديمة في الإصدارات القديمة لمعالجة الحِزم الأحدث. للحصول على بعض النصائح، يُرجى الاطّلاع على: How to process realtime input streams.

بالنسبة إلى المشكلة (2)، قد يكون أحد مصادر الإدخال لا يتضمّن حزمًا لبعض الأسباب. قد يكون الجهاز أو الآلة الحاسبة مضبوطَين بشكلٍ غير صحيح أو قد يُنشئان الحِزم بشكل متقطّع فقط. ويمكن أن يؤدي ذلك إلى انتظار الحاسبات في مرحلة ما بعد المعالجة للعديد من الحِزم التي لن تصل أبدًا، ما يؤدي بدوره إلى تراكم الحِزم في بعض مصادر الإدخال. تعالج MediaPipe هذا النوع من المشاكل باستخدام "حدود الطوابع الزمنية". للحصول على بعض النصائح، يُرجى الاطّلاع على: How to process realtime input streams.

يحدّ إعداد MediaPipe CalculatorGraphConfig::max_queue_size من عدد الحِزم المُدرَجة في قائمة الانتظار في أيّ بث إدخال من خلال الحدّ من معدّل إدخال البيانات إلى الرسم البياني. بالنسبة إلى مصادر الإدخال في الوقت الفعلي، يجب أن يكون عدد الحِزم في قائمة الانتظار في مصدر إدخال تقريبًا صفرًا أو واحدًا. إذا لم يكن الأمر كذلك، قد تظهر لك رسالة التحذير التالية:

Resolved a deadlock by increasing max_queue_size of input stream

يمكن أيضًا ضبط الإعداد CalculatorGraphConfig::report_deadlock لتسبب تعذُّر تشغيل الرسم البياني وعرض التوقف المفاجئ كخطأ، بحيث يعمل max_queue_size كحدّ أقصى لاستخدام الذاكرة.

تعليق الرسم البياني

ستستدعي العديد من التطبيقات CalculatorGraph::CloseAllPacketSources و CalculatorGraph::WaitUntilDone لإنهاء تنفيذ CalculatorGraph::CloseAllPacketSources أو تعليقه. والهدف من ذلك هو السماح لأيّ حاسبات أو حِزم في انتظار المعالجة ب completing processing، ثمّ إغلاق الرسم البياني. إذا سارت الأمور على ما يرام، سيصل كل البث في الرسم البياني إلى Timestamp::Done، وسيصل كل حاسب إلى CalculatorBase::Close، ثم سينتهي CalculatorGraph::WaitUntilDone بنجاح.

إذا تعذّر على بعض الآلات الحاسبة أو مصادر البيانات الوصول إلى الحالة Timestamp::Done أو CalculatorBase::Close، يمكن عندئذٍ استخدام الأسلوب CalculatorGraph::Cancel لإنهاء تشغيل الرسم البياني بدون انتظار اكتمال جميع الآلات الحاسبة والحِزم في انتظار المعالجة.

توقيت الإخراج غير متساوٍ

تُنشئ بعض الرسوم البيانية في MediaPipe في الوقت الفعلي سلسلة من إطارات الفيديو لعرضها كتأثير فيديو أو كبيانات تشخيصية للفيديو. في بعض الأحيان، سينتج رسم بياني في MediaPipe هذه اللقطات في مجموعات، على سبيل المثال عندما يتم توقّع عدة لقطات ناتجة من المجموعة نفسها من لقطات الإدخال. في حال عرض المخرجات أثناء إنتاجها، يتم استبدال بعض لقطات المخرجات على الفور بلقطات لاحقة في المجموعة نفسها، ما يجعل من الصعب رؤية النتائج وتقييمها بصريًا. في مثل هذه الحالات، يمكن تحسين تصور الإخراج من خلال عرض اللقطات على فترات متساوية في الوقت الفعلي.

يعالج MediaPipe حالة الاستخدام هذه من خلال ربط الطوابع الزمنية بالنقاط في الوقت الفعلي. يشير كل طابع زمني إلى وقت بالميكروسكوند، ويمكن لآلة حاسبة مثل LiveClockSyncCalculator تأخير إخراج الحِزم لمطابقة طوابعها الزمنية. يعدّل هذا النوع من الآلات الحاسبة توقيت النتائج على النحو التالي:

  1. تتوافق المدة بين النتائج مع المدة بين الطوابع الزمنية بأكبر قدر ممكن من الدقة.
  2. يتم إنشاء النتائج بأقل تأخير ممكن.

تأخُّر CalculatorGraph في عرض الإدخالات

بالنسبة إلى العديد من الرسوم البيانية في MediaPipe في الوقت الفعلي، يكون وقت الاستجابة السريع هو الهدف. توفّر MediaPipe المعالجة المتوازيّة بأسلوب "المسار المُعدّ للاستخدام" لبدء معالجة كل حزمة في أقرب وقت ممكن. في العادة، يكون أدنى وقت استجابة ممكن هو الوقت الإجمالي الذي تتطلّبه كل آلة حاسبة على طول "مسار حرج" لآلآت حاسبة متعاقبة. قد يكون وقت استجابة رسم بياني MediaPipe أسوأ من الوقت المثالي بسبب التأخيرات التي تم إجراؤها لعرض اللقطات على فترات متساوية كما هو موضّح في توقيت الإخراج غير متساوٍ.

إذا لم تتمكّن بعض الآلات الحاسبة في الرسم البياني من مواكبة تدفّقات الإدخال في الوقت الفعلي، سيستمر وقت الاستجابة في الزيادة، وسيصبح من الضروري ملفّع بعض حزم الإدخال. إنّ الطريقة المقترَحة هي استخدام أدوات الاحتساب في MediaPipe المصمّمة خصيصًا لهذا الغرض، مثل FlowLimiterCalculator كما هو موضّح في How to process realtime input streams.

مراقبة مدخلات الآلة الحاسبة وتسويات الطوابع الزمنية

غالبًا ما يتطلب تصحيح أخطاء أدوات حساب MediaPipe فهمًا عميقًا لمسار تدفق البيانات ومزامنة الطوابع الزمنية. يتم أولاً تخزين الحِزم الواردة إلى الآلات الحاسبة في قوائم انتظار الإدخال لكل بث لتتم مزامنتها من خلال InputStreamHandler المحدَّد. وظيفة InputStreamHandler هي تحديد مجموعة حزم الإدخال للطابع الزمني المحدد، ما يضع الآلة الحاسبة في حالة "جاهزة"، ثم تنشيط طلب Calculator::Process مع مجموعة الحِزم التي تم تحديدها كمدخل.

يمكن استخدام DebugInputStreamHandler لتتبُّع الحِزم الواردة و عمليات تسوية الطوابع الزمنية في الوقت الفعلي في إخراج LOG(INFO) للتطبيق. ويمكن تحديده لحاسبات رياضية معيّنة من خلال عنصر input_stream_handler في "الحاسبة" أو للرسم البياني على مستوى التطبيق من خلال حقل input_stream_handler في CalculatorGraphConfig.

أثناء تنفيذ الرسم البياني، تنشئ الحِزم الواردة رسائل LOG تكشف عن الطابع الزمني ونوع الحزمة، متبوعة بالحالة الحالية لجميع قوائم انتظار الإدخال:

[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"
  ...
}

في حال توفّر آلة حاسبة تتضمّن مدخلَين، يتم تلقّي حزمة واردة تحمل الطابع الزمني 1 في البثّ "أ" متبوعة بحزمة إدخال تحمل الطابع الزمني 2 في البثّ "ب". يؤدي زيادة حدود الطابع الزمني إلى 2 في البث "ب" مع حزمة إدخال في انتظار المعالجة في البث "أ" عند الطابع الزمني 1 إلى بدء طلب Calculator::Process مع مجموعة إدخال غير مكتملة تم ضبطها للطابع الزمني 1. في هذه الحالة، يعرض DefaultInputStreamHandler ما يلي:

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

فيديوهات السفر

تستخدم MediaPipe VLOG في العديد من الأماكن لتسجيل الأحداث المهمة لأغراض debugging ، مع عدم التأثير في الأداء في حال عدم تفعيل التسجيل.

اطّلِع على مزيد من المعلومات عن VLOG على abseil VLOG.

يُرجى العِلم أنّ VLOG يمكن أن يكون غير مرغوب فيه إذا تم تفعيله على مستوى الموقع الإلكتروني، على سبيل المثال (باستخدام --v flag). علامة الحل --vmodule التي تسمح بضبط مستويات مختلفة لملفات المصدر المختلفة

في الحالات التي لا يمكن فيها استخدام --v / --vmodule (مثل تشغيل تطبيق Android)، تسمح MediaPipe بضبط VLOG --v / --vmodule لإلغاء علامات debugging لأغراض يتم تطبيقها عند إنشاء CalculatorGraph.

عمليات الإلغاء:

  • MEDIAPIPE_VLOG_V: تحديد القيمة التي تقدّمها وتقديمها لـ --v
  • MEDIAPIPE_VLOG_VMODULE: تحديد القيمة التي تقدّمها وتقديمها --vmodule

يمكنك ضبط عمليات الاستبدال عن طريق إضافة: --copt=-DMEDIAPIPE_VLOG_VMODULE=\"*calculator*=5\"

مع أنماط الوحدات ومستويات VLOG المطلوبة (اطّلِع على مزيد من التفاصيل عن --vmodule في abseil VLOG) إلى أمر الإنشاء.

ملاحظة مهمة: يُرجى العِلم أنّ إضافة ما سبق إلى أمر الإنشاء سيؤدي إلى إعادة بناء الملف الثنائي بالكامل بما في ذلك التبعيات. وبما أنّ VLOG overrides تُستخدَم لأغراض تصحيح الأخطاء فقط، من الأسرع تعديل vlog_overrides.cc ببساطة من خلال إضافة MEDIAPIPE_VLOG_V/VMODULE في أعلى الصفحة.

علامات غير متوافقة أثناء عملية الإنشاء

إذا كنت تستخدم الإصدار 18 من Clang أو إصدارًا أقدم، قد تحتاج إلى إيقاف بعض تحسينات compiler في الخلفية الخاصة بوحدة المعالجة المركزية.

لإيقاف ميزة "المساعدة بشأن avxvnniint8"، أضِف ما يلي إلى .bazelrc:

build --define=xnn_enable_avxvnniint8=false