การแก้ปัญหา

ไม่มีเส้นทางไบนารีของ 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 เพื่อติดตั้งแพ็กเกจเหล่านั้น

ดึงข้อมูลที่เก็บ Dependency ระยะไกลไม่สำเร็จ

ข้อความแสดงข้อผิดพลาด:

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 ดาวน์โหลดที่เก็บ Dependency ที่จําเป็นซึ่ง MediaPipe ต้องการไม่สําเร็จ MediaPipe มีที่เก็บข้อมูล Dependency หลายแห่งที่โฮสต์โดยเว็บไซต์ของ 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 รองรับอย่างเป็นทางการใน Python 3.7 ถึง 3.10 เวอร์ชัน 64 บิตบนระบบปฏิบัติการต่อไปนี้

  • x86_64 Linux
  • x86_64 macOS 10.15 ขึ้นไป
  • Windows แบบ amd64

หากระบบปฏิบัติการรองรับในขณะนี้แต่คุณยังเห็นข้อผิดพลาดนี้อยู่ โปรดตรวจสอบว่าทั้ง Python และไพน์ไบนารีเป็นสำหรับ Python 3.7 ถึง 3.10 หรือลองสร้างแพ็กเกจ MediaPipe Python ในพื้นที่โดยทำตามวิธีการที่นี่

โหลด Python DLL ใน Windows ไม่สำเร็จ

ข้อความแสดงข้อผิดพลาด:

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

มักจะบ่งบอกว่าระบบ Windows ในเครื่องไม่มีแพ็กเกจ Visual C++ ที่พร้อมแจกจ่ายซ้ำและ/หรือ DLL รันไทม์ของ Visual C++ ปัญหานี้แก้ไขได้โดยการติดตั้ง vc_redist.x64.exe อย่างเป็นทางการ หรือติดตั้งแพ็กเกจ Python "msvc-runtime" โดยเรียกใช้

$ python -m pip install msvc-runtime

โปรดทราบว่า Microsoft ไม่ได้เผยแพร่หรือดูแลรักษาแพ็กเกจ Python "msvc-runtime"

ไม่พบเมธอดเนทีฟ

ข้อความแสดงข้อผิดพลาด:

java.lang.UnsatisfiedLinkError: No implementation found for void com.google.wick.Wick.nativeWick

มักบ่งบอกว่ายังไม่ได้โหลดไลบรารีแบบเนทีฟที่จำเป็น เช่น /libwickjni.so หรือไม่ได้รวมไว้ใน Dependency ของแอป หรือหาไม่พบเนื่องจากเหตุผลบางอย่าง โปรดทราบว่า 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++ ของโปรแกรม ในกรณีนี้ กราฟเครื่องคิดเลขต้องใช้คำนำหน้าเนมสเปซเดียวกันด้วย

ข้อผิดพลาดหน่วยความจำไม่เพียงพอ

หน่วยความจําหมดอาจเป็นอาการของแพ็กเก็ตที่สะสมอยู่ในกราฟ MediaPipe ที่ทำงานอยู่มากเกินไป ปัญหานี้อาจเกิดขึ้นได้จากหลายสาเหตุ เช่น

  1. เครื่องคำนวณบางเครื่องในกราฟไม่สามารถทำงานทันกับแพ็กเก็ตที่เข้ามาจากสตรีมอินพุตแบบเรียลไทม์ เช่น กล้องวิดีโอ
  2. เครื่องคิดเลขบางเครื่องกำลังรอแพ็กเก็ตที่จะไม่มาถึง

สําหรับปัญหา (1) คุณอาจต้องทิ้งแพ็กเก็ตเก่าบางรายการในเวอร์ชันเก่าเพื่อประมวลผลแพ็กเก็ตล่าสุด ดูคำแนะนำบางส่วนได้ที่ How to process realtime input streams

สำหรับปัญหา (2) อาจเป็นเพราะสตรีมอินพุต 1 รายการไม่มีแพ็กเก็ตเนื่องด้วยสาเหตุบางอย่าง อุปกรณ์หรือเครื่องคิดเลขอาจได้รับการกําหนดค่าไม่ถูกต้องหรืออาจสร้างแพ็กเก็ตเป็นครั้งคราวเท่านั้น ซึ่งอาจทําให้เครื่องคำนวณปลายทางต้องรอแพ็กเก็ตจํานวนมากที่จะไม่มาถึง ซึ่งทําให้แพ็กเก็ตสะสมอยู่ในสตรีมอินพุตบางรายการ MediaPipe แก้ปัญหาประเภทนี้โดยใช้ "ขอบเขตการประทับเวลา" ดูคำแนะนำบางส่วนได้ที่ How to process realtime input streams

การตั้งค่า MediaPipe CalculatorGraphConfig::max_queue_size จะจำกัดจำนวนแพ็กเก็ตที่จัดคิวไว้ในสตรีมอินพุตโดยจำกัดอินพุตไปยังกราฟ สําหรับสตรีมอินพุตแบบเรียลไทม์ จํานวนแพ็กเก็ตที่รออยู่ในสตรีมอินพุตควรเป็น 0 หรือ 1 เกือบทุกครั้ง หากไม่เป็นเช่นนั้น คุณอาจเห็นข้อความเตือนต่อไปนี้

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 รองรับ Use Case นี้โดยการแมปการประทับเวลาไปยังจุดต่างๆ แบบเรียลไทม์ การประทับเวลาแต่ละรายการจะระบุเวลาเป็นไมโครวินาที และเครื่องคิดเลขอย่าง 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

ในระหว่างการเรียกใช้กราฟ พารามิเตอร์ที่เข้ามาในระบบจะสร้างข้อความบันทึกซึ่งแสดงการประทับเวลาและประเภทของแพ็กเก็ต ตามด้วยสถานะปัจจุบันของคิวอินพุตทั้งหมด

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

สมมติว่าเครื่องคิดเลขมีอินพุต 2 รายการ โดยได้รับแพ็กเก็ตขาเข้าที่มีการประทับเวลา 1 ในสตรีม A ตามด้วยแพ็กเก็ตอินพุตที่มีการประทับเวลา 2 ในสตรีม B การประทับเวลาสูงสุดเพิ่มขึ้นเป็น 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.

VLOG คือเพื่อนแท้

MediaPipe ใช้ VLOG ในหลายตำแหน่งเพื่อบันทึกเหตุการณ์สำคัญเพื่อวัตถุประสงค์ในการแก้ไขข้อบกพร่อง โดยไม่ส่งผลต่อประสิทธิภาพหากไม่ได้เปิดใช้การบันทึก

ดูข้อมูลเพิ่มเติมเกี่ยวกับ VLOG ใน abseil VLOG

โปรดทราบว่า VLOG อาจทำให้เกิดสแปมได้หากคุณเปิดใช้แบบทั่วโลก เช่น (โดยใช้ --v flag) แฟล็ก --vmodule ของโซลูชันที่อนุญาตให้ตั้งค่าระดับที่แตกต่างกันสำหรับไฟล์ต้นฉบับแต่ละไฟล์

ในกรณีที่ใช้ --v / --vmodule ไม่ได้ (เช่น เรียกใช้แอป Android) MediaPipe อนุญาตให้ตั้งค่าการลบล้าง Flag VLOG --v / --vmodule เพื่อวัตถุประสงค์ในการแก้ไขข้อบกพร่อง ซึ่งจะมีผลเมื่อสร้าง CalculatorGraph

การลบล้าง

  • MEDIAPIPE_VLOG_V: กําหนดและให้คุณค่าที่คุณมอบให้ --v
  • MEDIAPIPE_VLOG_VMODULE: กําหนดและให้คุณค่าที่คุณมอบให้กับผู้คน --vmodule

คุณตั้งค่าการลบล้างได้โดยเพิ่มข้อมูลต่อไปนี้ --copt=-DMEDIAPIPE_VLOG_VMODULE=\"*calculator*=5\"

ด้วยรูปแบบโมดูลและระดับ VLOG ที่ต้องการ (ดูรายละเอียดเพิ่มเติมสำหรับ --vmodule ที่ abseil VLOG) ลงในคําสั่งบิลด์

สำคัญ: โปรดทราบว่าการเพิ่มคำสั่งข้างต้นลงในคำสั่งบิลด์จะทริกเกอร์การสร้างไฟล์ไบนารีทั้งหมดขึ้นใหม่ รวมถึงการสร้างไฟล์ที่เกี่ยวข้อง ดังนั้น เมื่อพิจารณาว่าVLOGการลบล้างมีอยู่เพื่อวัตถุประสงค์ในการแก้ไขข้อบกพร่องเท่านั้น การแก้ไขvlog_overrides.ccโดยการเพิ่ม MEDIAPIPE_VLOG_V/VMODULE ที่ด้านบนสุดจะเร็วกว่า

Flag ที่ไม่รองรับระหว่างการสร้าง

หากใช้ Clang 18 หรือเก่ากว่า คุณอาจต้องปิดใช้การเพิ่มประสิทธิภาพคอมไพเลอร์บางอย่างในแบ็กเอนด์ CPU

หากต้องการปิดใช้การสนับสนุน avxvnniint8 ให้เพิ่มข้อมูลต่อไปนี้ลงใน .bazelrc

build --define=xnn_enable_avxvnniint8=false