동기화

일정 예약 메커니즘

MediaPipe 그래프의 데이터 처리는 CalculatorBase 서브클래스로 정의된 처리 노드 내에서 이루어집니다. 일정 관리 시스템은 각 계산기를 실행할 시기를 결정합니다.

각 그래프에는 하나 이상의 스케줄러 큐가 있습니다. 각 스케줄러 큐에는 정확히 하나의 executor가 있습니다. 노드는 큐 (그리고 실행자)에 정적으로 할당됩니다. 기본적으로 큐는 하나이며 실행자는 시스템 기능에 따라 스레드 수가 있는 스레드 풀입니다.

각 노드에는 준비되지 않음, 준비됨 또는 실행 중과 같은 예약 상태가 있습니다. 준비 함수는 노드를 실행할 준비가 되었는지 확인합니다. 이 함수는 그래프 초기화 시, 노드 실행이 완료될 때마다, 노드의 입력 상태가 변경될 때마다 호출됩니다.

사용되는 준비 함수는 노드 유형에 따라 다릅니다. 스트림 입력이 없는 노드를 소스 노드라고 합니다. 소스 노드는 항상 실행할 준비가 되어 있지만, 프레임워크에 출력할 데이터가 더 이상 없다고 알릴 때까지(종료 시점에) 항상 실행될 수 있습니다.

처리할 입력이 있고 이러한 입력이 노드의 입력 정책 (아래 설명 참조)에 설정된 조건에 따라 유효한 입력 세트를 형성하면 비소스 노드가 준비됩니다. 대부분의 노드는 기본 입력 정책을 사용하지만 일부 노드는 다른 정책을 지정합니다.

노드가 준비되면 해당하는 스케줄러 큐(우선순위 큐)에 태스크가 추가됩니다. 우선순위 함수는 현재 고정되어 있으며 노드의 정적 속성과 그래프 내의 토폴로지 정렬을 고려합니다. 예를 들어 그래프의 출력 측에 가까운 노드의 우선순위가 높고 소스 노드의 우선순위가 가장 낮습니다.

각 큐는 계산기의 코드를 호출하여 실제로 작업을 실행하는 실행자가 제공합니다. 다양한 실행자를 제공 및 구성할 수 있습니다. 이는 우선순위가 낮은 스레드에서 특정 노드를 실행하는 등 실행 리소스 사용을 맞춤설정하는 데 사용할 수 있습니다.

타임스탬프 동기화

MediaPipe 그래프 실행이 분산되어 있습니다. 글로벌 시계가 없으며 여러 노드가 여러 타임스탬프의 데이터를 동시에 처리할 수 있습니다. 이렇게 하면 파이프라인을 통한 처리량이 증가합니다.

그러나 시간 정보는 많은 인식 워크플로에서 매우 중요합니다. 여러 입력 스트림을 수신하는 노드는 일반적으로 어떤 방식으로든 조정해야 합니다. 예를 들어 객체 감지기는 프레임에서 경계 직사각형 목록을 출력할 수 있으며 이 정보는 렌더링 노드에 입력될 수 있으며 렌더링 노드는 원래 프레임과 함께 처리되어야 합니다.

따라서 MediaPipe 프레임워크의 주요 역할 중 하나는 노드의 입력 동기화를 제공하는 것입니다. 프레임워크 메커니즘 측면에서 타임스탬프의 주요 역할은 동기화 키 역할을 하는 것입니다.

또한 MediaPipe는 테스트, 시뮬레이션, 일괄 처리 등 많은 시나리오에서 중요한 결정론적 작업을 지원하도록 설계되었으며, 그래프 작성자는 실시간 제약 조건을 충족해야 할 때 결정론을 완화할 수 있습니다.

동기화와 결정론의 두 가지 목표는 여러 설계 옵션의 근간이 됩니다. 특히, 특정 스트림으로 푸시된 패킷에는 단조 증가하는 타임스탬프가 있어야 합니다. 이는 많은 노드에 유용한 가정일 뿐만 아니라 동기화 로직에도 의존합니다. 각 스트림에는 스트림의 새 패킷에 허용되는 가장 낮은 타임스탬프인 타임스탬프 경계가 있습니다. 타임스탬프가 T인 패킷이 도착하면 바인딩은 단조 요건을 반영하여 자동으로 T+1로 이동합니다. 이를 통해 프레임워크는 T보다 낮은 타임스탬프가 있는 패킷이 더 이상 도착하지 않음을 확신할 수 있습니다.

입력 정책

동기화는 노드에서 지정한 입력 정책을 사용하여 각 노드에서 로컬로 처리됩니다.

DefaultInputStreamHandler에 의해 정의된 기본 입력 정책은 다음과 같은 보장과 함께 입력의 확정적 동기화를 제공합니다.

  • 타임스탬프가 동일한 패킷이 여러 입력 스트림에 제공되는 경우 도착 순서와 관계없이 실시간 도착 순서와 관계없이 항상 함께 처리됩니다.

  • 입력 집합은 타임스탬프 오름차순으로 처리됩니다.

  • 패킷이 삭제되지 않으며 완전히 확정적으로 처리됩니다.

  • 위의 보장에 따라 노드는 최대한 빨리 데이터를 처리할 준비가 됩니다.

작동 방식을 설명하려면 처리된 타임스탬프의 정의를 도입해야 합니다. 스트림의 타임스탬프가 타임스탬프 경계보다 낮으면 정산된다고 합니다. 즉, 패킷이 있거나 해당 타임스탬프가 있는 패킷이 도착하지 않을 것이 확실해지면 해당 타임스탬프의 입력 상태를 취소할 수 없는 경우 스트림에 대한 타임스탬프가 정산됩니다.

타임스탬프가 각 스트림에서 결정되면 여러 스트림에서 정해집니다. 또한 타임스탬프가 정산되는 경우 이전의 모든 타임스탬프도 정산된다는 의미입니다. 따라서 설정된 타임스탬프를 오름차순으로 결정적으로 처리할 수 있습니다.

이 정의에서 모든 입력 스트림에 결정되고 하나 이상의 입력 스트림에 패킷을 포함하는 타임스탬프가 있으면 기본 입력 정책이 적용된 계산기가 준비된 것입니다. 입력 정책은 고정된 타임스탬프에 사용 가능한 모든 패킷을 계산기에 대한 단일 입력 집합으로 제공합니다.

이러한 결정론적 동작의 결과로 발생하는 한 가지 결과는 입력 스트림이 여러 개 있는 노드의 경우 타임스탬프가 해결될 때까지 이론적으로 제한되지 않은 대기가 있을 수 있고 그동안 무제한의 패킷이 버퍼링될 수 있다는 것입니다. (두 개의 입력 스트림이 있는 노드를 생각해 보세요. 이 중 하나는 패킷을 계속 전송하고 다른 하나는 아무것도 보내지 않고 경계를 진행하지 않습니다.)

따라서 Google은 커스텀 입력 정책도 제공합니다. 예를 들어 SyncSetInputStreamHandler에 의해 정의된 여러 동기화 세트의 입력을 분할하거나 동기화를 완전히 피하고 ImmediateInputStreamHandler에 의해 정의된 입력이 도착하는 즉시 입력을 처리합니다.

흐름 제어

두 가지 기본 흐름 제어 메커니즘이 있습니다. 백프레셔 메커니즘은 스트림에 버퍼링된 패킷이 CalculatorGraphConfig::max_queue_size에 의해 정의된(구성 가능한) 한도에 도달하면 업스트림 노드의 실행을 제한합니다. 이 메커니즘은 확정적 동작을 유지하고 필요할 때 구성된 한도를 완화하는 교착 상태 방지 시스템을 포함합니다.

두 번째 시스템은 FlowLimiterCalculator에 정의된 실시간 제약조건 (일반적으로 커스텀 입력 정책 사용)에 따라 패킷을 삭제할 수 있는 특수 노드를 삽입하는 것으로 구성됩니다. 예를 들어 공통 패턴은 하위 그래프의 입력에 흐름 제어 노드를 배치하고 최종 출력에서 흐름 제어 노드로 루프백 연결을 포함합니다. 따라서 흐름 제어 노드는 다운스트림 그래프에서 처리 중인 타임스탬프 수를 추적하고 이 개수가 구성 가능한 제한에 도달하면 패킷을 삭제할 수 있습니다. 또한 패킷이 업스트림으로 삭제되므로 타임스탬프를 부분적으로 처리한 후 중간 단계 사이에 패킷을 삭제하여 발생하는 낭비되는 작업을 피할 수 있습니다.

이 계산기 기반 접근 방식을 통해 그래프 작성자는 패킷을 삭제할 수 있는 위치를 제어하고 리소스 제약 조건에 따라 그래프의 동작을 유연하게 조정하고 맞춤설정할 수 있습니다.