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 사이트에서 호스팅하는 여러 종속 항목 저장소가 있습니다. 일부 지역에서는 네트워크 프록시를 설정하거나 VPN을 사용하여 이러한 리소스에 액세스해야 할 수 있습니다. 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 설치 실패
오류 메시지:
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는 다음 OS에서 Python 3.7~3.10의 64비트 버전을 공식적으로 지원합니다.
- x86_64 Linux
- x86_64 macOS 10.15 이상
- amd64 Windows
현재 OS가 지원되고 있는데도 이 오류가 계속 표시되면 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
은 그래프에 대한 입력을 제한하여 입력 스트림에 큐에 추가되는 패킷 수를 제한합니다. 실시간 입력 스트림의 경우 입력 스트림에 큐에 추가된 패킷 수는 거의 항상 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는 타임스탬프를 실시간으로 점에 매핑하여 이 사용 사례를 해결합니다.
각 타임스탬프는 마이크로초 단위의 시간을 나타내며 LiveClockSyncCalculator
와 같은 계산기는 패킷의 출력을 지연하여 타임스탬프와 일치시킬 수 있습니다. 이러한 계산기는 다음과 같이 출력의 타이밍을 조정합니다.
- 출력 간 시간은 타임스탬프 간 시간과 최대한 근접합니다.
- 출력은 가능한 한 지연 없이 생성됩니다.
CalculatorGraph가 입력보다 뒤처짐
많은 실시간 MediaPipe 그래프의 경우 짧은 지연 시간이 목표입니다. MediaPipe는 각 패킷의 처리를 최대한 빨리 시작하기 위해 '파이프라인화된' 스타일의 병렬 처리를 지원합니다. 일반적으로 가능한 최소 지연 시간은 연속된 계산기의 '주요 경로'를 따라 각 계산기에 필요한 총 시간입니다. 출력 타이밍이 고르지 않음에 설명된 대로 프레임을 균등한 간격으로 표시하기 위해 도입된 지연으로 인해 MediaPipe 그래프의 지연 시간이 이상보다 더 길어질 수 있습니다.
그래프의 일부 계산기가 실시간 입력 스트림을 따라가지 못하면 지연 시간이 계속 증가하고 일부 입력 패킷을 삭제해야 합니다. How to process realtime input streams
에 설명된 대로 FlowLimiterCalculator
와 같이 이 용도로 특별히 설계된 MediaPipe 계산기를 사용하는 것이 좋습니다.
계산기 입력 및 타임스탬프 결제 모니터링
MediaPipe 계산기를 디버그하려면 데이터 흐름과 타임스탬프 동기화를 심층적으로 이해해야 하는 경우가 많습니다. 계산기로 들어오는 패킷은 먼저 할당된 InputStreamHandler
에 의해 동기화되도록 스트림별 입력 대기열에 버퍼링됩니다. InputStreamHandler
작업은 계산기를 'ready' 상태로 전환하는 정리된 타임스탬프의 입력 패킷 세트를 결정한 다음 결정된 패킷 세트를 입력으로 사용하여 Calculator::Process 호출을 트리거하는 것입니다.
DebugInputStreamHandler
는 애플리케이션의 LOG(INFO) 출력에서 수신 패킷 및 타임스탬프 합의를 실시간으로 추적하는 데 사용할 수 있습니다. 계산기의 input_stream_handler를 통해 특정 계산기에 할당하거나 CalculatorGraphConfig
의 input_stream_handler 필드를 통해 전역적으로 그래프에 할당할 수 있습니다.
그래프 실행 중에 수신되는 패킷은 패킷의 타임스탬프와 유형을 나타내는 로그 메시지를 생성하고 그 뒤에 모든 입력 대기열의 현재 상태가 표시됩니다.
[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개인 계산기가 주어졌으며 스트림 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 이상을 사용하는 경우 CPU 백엔드에서 일부 컴파일러 최적화를 사용 중지해야 할 수 있습니다.
avxvnniint8
지원을 사용 중지하려면 .bazelrc
에 다음을 추가합니다.
build --define=xnn_enable_avxvnniint8=false