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 बाइनरी कहां है और फिर Bazel कमांड में --action_env PYTHON_BIN_PATH=<path to python binary>
जोड़ें. उदाहरण के लिए, सिस्टम में डिफ़ॉल्ट रूप से मौजूद 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 पैकेज इंस्टॉल नहीं हैं. इन पैकेज को इंस्टॉल करने के लिए, कृपया अपने Python बाइनरी वर्शन के हिसाब से pip install
या pip3 install
चलाएं.
रिमोट डिपेंडेंसी रिपॉज़िटरी फ़ेच नहीं हो पाना
गड़बड़ी का मैसेज:
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 की साइटों पर होस्ट किया जाता है. कुछ इलाकों में, उन संसाधनों को ऐक्सेस करने के लिए, आपको नेटवर्क प्रॉक्सी सेट अप करना पड़ सकता है या वीपीएन का इस्तेमाल करना पड़ सकता है. आपको Bazel कमांड में
--host_jvm_args "-DsocksProxyHost=<ip address> -DsocksProxyPort=<port number>"
जोड़ना पड़ सकता है. ज़्यादा जानकारी के लिए,
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 लाइब्रेरी के लिए, MediaPipe के WORKSPACE और linux_opencv/macos_opencv/windows_opencv.BUILD फ़ाइलों में बदलाव करने का तरीका जानने के लिए, कृपया इंस्टॉलेशन में "OpenCV और FFmpeg इंस्टॉल करें" सेक्शन देखें. GitHub पर मौजूद यह समस्या भी आपको मदद कर सकती है.
Python pip install की गड़बड़ी
गड़बड़ी का मैसेज:
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, इन ओएस पर Python 3.7 से 3.10 के 64-बिट वर्शन के साथ आधिकारिक तौर पर काम करता है:
- x86_64 Linux
- x86_64 macOS 10.15 और उसके बाद के वर्शन
- amd64 Windows
अगर आपके ओएस पर फ़िलहाल यह सुविधा काम करती है और आपको अब भी यह गड़बड़ी दिखती है, तो कृपया पक्का करें कि Python और pip, दोनों बाइनरी, Python 3.7 से 3.10 के लिए हों. अगर ऐसा नहीं है, तो यहां दिए गए निर्देशों का पालन करके, MediaPipe Python पैकेज को स्थानीय तौर पर बनाएं.
Windows पर Python DLL लोड न होना
गड़बड़ी का मैसेज:
ImportError: DLL load failed: The specified module could not be found
आम तौर पर, इससे पता चलता है कि आपके लोकल Windows सिस्टम में, Visual C++ के फिर से डिस्ट्रिब्यूट किए जा सकने वाले पैकेज और/या Visual C++ के रनटाइम DLL मौजूद नहीं हैं. इस समस्या को हल करने के लिए, vc_redist.x64.exe को आधिकारिक तौर पर इंस्टॉल करें या "msvc-runtime" Python पैकेज को इंस्टॉल करने के लिए,
$ python -m pip install msvc-runtime
कृपया ध्यान दें कि "msvc-runtime" Python पैकेज को 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
के ज़रिए अपने कैलकुलेटर का नाम बताते हैं.
जब किसी कैलकुलेटर की लाइब्रेरी को ऐप्लिकेशन बाइनरी से लिंक किया जाता है, तो registration.h
लाइब्रेरी का इस्तेमाल करके, REGISTER_CALCULATOR
मैक्रो के ज़रिए कैलकुलेटर अपने-आप नाम से रजिस्टर हो जाता है. ध्यान दें कि REGISTER_CALCULATOR
, कैलकुलेटर को नेमस्पेस प्रीफ़िक्स के साथ रजिस्टर कर सकता है. यह प्रीफ़िक्स, C++ नेमस्पेस जैसा ही होता है. इस मामले में, कैलकुलेटर ग्राफ़ में भी उसी नेमस्पेस प्रीफ़िक्स का इस्तेमाल करना होगा.
मेमोरी खत्म होने की गड़बड़ी
ज़्यादा मेमोरी का इस्तेमाल होने का मतलब है कि MediaPipe ग्राफ़ में बहुत ज़्यादा पैकेट इकट्ठा हो रहे हैं. ऐसा कई वजहों से हो सकता है. जैसे:
- ग्राफ़ में मौजूद कुछ कैलकुलेटर, वीडियो कैमरे जैसी रीयल टाइम इनपुट स्ट्रीम से पैकेट आने की दर के साथ तालमेल नहीं बैठा पाते.
- कुछ कैलकुलेटर ऐसे पैकेट का इंतज़ार कर रहे हैं जो कभी नहीं आएंगे.
समस्या (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 काम करता है.
ग्राफ़ हैंग होना
कई ऐप्लिकेशन, MediaPipe ग्राफ़ को पूरा करने या निलंबित करने के लिए, CalculatorGraph::CloseAllPacketSources
और
CalculatorGraph::WaitUntilDone
को कॉल करेंगे. यहां हमारा मकसद, किसी भी कैलकुलेटर या पैकेट को प्रोसेसिंग पूरी करने की अनुमति देना है. इसके बाद, ग्राफ़ को बंद करना है. अगर सब कुछ ठीक रहा, तो ग्राफ़ में मौजूद हर स्ट्रीम Timestamp::Done
पर पहुंच जाएगी और हर कैलकुलेटर CalculatorBase::Close
पर पहुंच जाएगा. इसके बाद, CalculatorGraph::WaitUntilDone
पर पहुंचने की प्रोसेस पूरी हो जाएगी.
अगर कुछ कैलकुलेटर या स्ट्रीम, Timestamp::Done
या
CalculatorBase::Close
स्टेटस तक नहीं पहुंच पाते हैं, तो CalculatorGraph::Cancel
तरीके का इस्तेमाल करके ग्राफ़ को बंद किया जा सकता है. इसके लिए, सभी कैलकुलेटर और पैकेट के पूरा होने का इंतज़ार करने की ज़रूरत नहीं है.
आउटपुट का समय अलग-अलग है
MediaPipe के कुछ रीयल-टाइम ग्राफ़, वीडियो इफ़ेक्ट या वीडियो की गड़बड़ी की जानकारी के तौर पर देखने के लिए, वीडियो फ़्रेम की एक सीरीज़ बनाते हैं. कभी-कभी, MediaPipe ग्राफ़ इन फ़्रेम को क्लस्टर में जनरेट करेगा. उदाहरण के लिए, जब इनपुट फ़्रेम के एक ही क्लस्टर से कई आउटपुट फ़्रेम एक्सट्रपलेशन किए जाते हैं. अगर आउटपुट को ठीक उसी तरह दिखाया जाता है जिस तरह वे जनरेट होते हैं, तो कुछ आउटपुट फ़्रेम तुरंत ही उसी क्लस्टर के बाद के फ़्रेम से बदल जाते हैं. इससे नतीजों को विज़ुअल तौर पर देखना और उनका आकलन करना मुश्किल हो जाता है. ऐसे मामलों में, रीयल टाइम में फ़्रेम को बराबर अंतराल पर दिखाकर, आउटपुट विज़ुअलाइज़ेशन को बेहतर बनाया जा सकता है.
MediaPipe, टाइमस्टैंप को रीयल टाइम में पॉइंट पर मैप करके, इस इस्तेमाल के उदाहरण को हल करता है.
हर टाइमस्टैंप, माइक्रोसेकंड में समय दिखाता है. साथ ही, LiveClockSyncCalculator
जैसे कैलकुलेटर, टाइमस्टैंप से मैच करने के लिए पैकेट के आउटपुट में देरी कर सकते हैं. इस तरह का कैलकुलेटर, आउटपुट के समय में बदलाव करता है, ताकि:
- आउटपुट के बीच का समय, टाइमस्टैंप के बीच के समय से जितना हो सके उतना मिलता-जुलता होता है.
- आउटपुट कम से कम देरी के साथ जनरेट किए जाते हैं.
CalculatorGraph, इनपुट के पीछे रह जाता है
MediaPipe के कई रीयल-टाइम ग्राफ़ के लिए, कम इंतज़ार का समय एक मकसद होता है. MediaPipe, "पाइपलाइन" स्टाइल की पैरलल प्रोसेसिंग की सुविधा देता है, ताकि हर पैकेट की प्रोसेसिंग जल्द से जल्द शुरू की जा सके. आम तौर पर, कम से कम इंतज़ार का समय, एक कैलकुलेटर से दूसरे कैलकुलेटर के "क्रिटिकल पाथ" में, हर कैलकुलेटर के लिए ज़रूरी कुल समय होता है. आउटपुट का समय अलग-अलग है में बताए गए मुताबिक, फ़्रेम को एक जैसे इंटरवल पर दिखाने के लिए, MediaPipe ग्राफ़ में देरी हो सकती है. इस वजह से, ग्राफ़ का इंतज़ार समय, सही समय से ज़्यादा हो सकता है.
अगर ग्राफ़ में मौजूद कुछ कैलकुलेटर, रीयल टाइम इनपुट स्ट्रीम के साथ नहीं चल पाते हैं, तो इंतज़ार का समय बढ़ता रहेगा. साथ ही, कुछ इनपुट पैकेट छोड़ने पड़ेंगे. हमारा सुझाव है कि आप MediaPipe के उन कैलकुलेटर का इस्तेमाल करें जिन्हें खास तौर पर इस काम के लिए डिज़ाइन किया गया है. जैसे, How to process realtime input streams
में बताए गए FlowLimiterCalculator
.
कैलकुलेटर के इनपुट और टाइमस्टैंप सेटलमेंट को मॉनिटर करना
MediaPipe कैलकुलेटर को डीबग करने के लिए, अक्सर डेटा फ़्लो और टाइमस्टैंप सिंक करने की पूरी जानकारी होनी चाहिए. कैलकुलेटर में आने वाले पैकेट, पहले हर स्ट्रीम के लिए इनपुट कतार में बफ़र किए जाते हैं, ताकि उन्हें असाइन किए गए InputStreamHandler
के साथ सिंक किया जा सके. InputStreamHandler
का काम, सेटल किए गए टाइमस्टैंप के लिए इनपुट पैकेट सेट करना है. इससे कैलकुलेटर “तैयार” स्थिति में आ जाता है. इसके बाद, Calculator::Process कॉल को ट्रिगर किया जाता है. इसमें, इनपुट के तौर पर सेट किए गए पैकेट का इस्तेमाल किया जाता है.
DebugInputStreamHandler
का इस्तेमाल, ऐप्लिकेशन के LOG(INFO) आउटपुट में रीयल-टाइम में आने वाले पैकेट और टाइमस्टैंप सेटलमेंट को ट्रैक करने के लिए किया जा सकता है. इसे कैलकुलेटर के input_stream_handler या CalculatorGraphConfig
के input_stream_handler फ़ील्ड की मदद से, दुनिया भर में ग्राफ़ या कैलकुलेटर के लिए असाइन किया जा सकता है.
ग्राफ़ को लागू करने के दौरान, इनकमिंग पैकेट 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"
...
}
दो इनपुट वाले कैलकुलेटर को स्ट्रीम A पर टाइमस्टैंप 1 वाला इनकमिंग पैकेट मिलता है. इसके बाद, स्ट्रीम B पर टाइमस्टैंप 2 वाला इनपुट पैकेट मिलता है. टाइमस्टैंप 1 पर स्ट्रीम A में इनपुट पैकेट बाकी होने पर, स्ट्रीम B पर टाइमस्टैंप बाउंड बढ़कर 2 हो जाता है. इससे टाइमस्टैंप 1 के लिए अधूरे इनपुट सेट के साथ, Calculator::Process कॉल ट्रिगर होता है. इस मामले में, DefaultInputStreamHandler
का आउटपुट:
[INFO] SomeCalculator: Filled input set at ts: 1 with MISSING packets in input streams: INPUT_B:0:input_b.
VLOG आपके काम का है
MediaPipe, डीबग करने के लिए ज़रूरी इवेंट को लॉग करने के मकसद से, कई जगहों पर VLOG
का इस्तेमाल करता है. हालांकि, लॉगिंग की सुविधा चालू न होने पर, परफ़ॉर्मेंस पर कोई असर नहीं पड़ता.
abseil VLOG
पर VLOG
के बारे में ज़्यादा जानें
ध्यान रखें कि VLOG
को ग्लोबल तौर पर चालू करने पर, यह स्पैम हो सकता है. उदाहरण के लिए, --v
फ़्लैग का इस्तेमाल करके. समाधान --vmodule
फ़्लैग, जो अलग-अलग सोर्स फ़ाइलों के लिए अलग-अलग लेवल सेट करने की अनुमति देता है.
जिन मामलों में --v
/ --vmodule
का इस्तेमाल नहीं किया जा सकता (जैसे, Android ऐप्लिकेशन चलाना), MediaPipe की मदद से, डिबग करने के लिए VLOG
--v
/ --vmodule
फ़्लैग बदले जा सकते हैं. ये फ़्लैग, CalculatorGraph
बनाने पर लागू होते हैं.
बदली गई कीमत:
MEDIAPIPE_VLOG_V
:--v
के लिए, अपनी वैल्यू तय करें और उसे उपलब्ध कराएंMEDIAPIPE_VLOG_VMODULE
:--vmodule
के लिए अपनी वैल्यू तय करें और उसे उपलब्ध कराएं
बदलाव करने के लिए, ये चीज़ें जोड़ें:
--copt=-DMEDIAPIPE_VLOG_VMODULE=\"*calculator*=5\"
अपने पसंदीदा मॉड्यूल पैटर्न और VLOG
लेवल के साथ, अपनी बिल्ड कमांड में abseil VLOG
पर --vmodule
के बारे में ज़्यादा जानकारी देखें.
अहम जानकारी: ध्यान रखें कि ऊपर दी गई बातों को अपनी बिल्ड कमांड में जोड़ने से, डिपेंडेंसी के साथ-साथ पूरी बाइनरी को फिर से बनाने की प्रोसेस शुरू हो जाएगी. इसलिए, VLOG
बदलाव सिर्फ़ डीबग करने के लिए मौजूद है. इसलिए, सबसे ऊपर MEDIAPIPE_VLOG_V/VMODULE
जोड़कर vlog_overrides.cc
में बदलाव करना ज़्यादा तेज़ है.
बिल्ड के दौरान इस्तेमाल नहीं किए जा सकने वाले फ़्लैग
अगर Clang 18 या इससे पहले के वर्शन का इस्तेमाल किया जा रहा है, तो आपको हमारे सीपीयू बैकएंड में, कंपाइलर के कुछ ऑप्टिमाइज़ेशन बंद करने पड़ सकते हैं.
avxvnniint8
के लिए सहायता की सुविधा बंद करने के लिए, अपने .bazelrc
में यह जोड़ें:
build --define=xnn_enable_avxvnniint8=false