Graphs

GraphConfig

GraphConfig는 Meidapipe 그래프의 토폴로지(아마 네트워크 맥락에서의 토폴로지인 듯. 노드들과 이에 연결된 회선들을 포함한 네트워크의 배열이나 구성을 개념적인 그림으로 표현한 것을 토폴로지라고 한다고 한다.)와 기능을 설명하는 명세서입니다. 명세서에서 그래프의 노드는 특정 Calcualtor의 인스턴스를 나타냅니다. 노드 유형, 입출력과 같은 필요한 모든 구성은 명세서에 설명되어야 합니다. 노드에 대한 설명에는 동기화에서 논의된 노드별 옵션, 입력 정책 및 실행 프로그램과 같은 여러 선택적 필드가 포함될 수 있습니다.
GraphConfig에는 그래프 실행기 구성, 스레드 수 및 입력 스트림 최대 대기열 크기와 같은 전역 그래프 수준 설정을 구성하기 위한 몇 가지 다른 필드가 있습니다. 여러 그래프 수준 설정은 다양한 플랫폼에서 그래프의 성능을 조정하는 데 유용합니다. 예를 들어 모바일에서 무거운 모델 추론 Calculator를 별도 실행기에 연결하면 스레드 지역성이 가능하여 실시간 응용 프로그램 성능을 향상시킬 수 있습니다.

ex)

input_stream : "in"
node {
  calculator : "PassThroughCalculator"
  input_stream : "in"
  output_stream : "out1"
}
node {
  calculator : "PassThroughCalculator"
  input_stream : "out1"
  output_stream : "out2"
}
node {
  calculator : "PassThroughCalculator"
  input_stream : "out2"
  output_stream : "out3"
}
node {
  calculator : "PassThroughCalculator"
  input_stream : "out3"
  output_stream : "out4"
}

Subgraph

CalculatorGraphConfig를 하위 모듈로 모듈화하고 perception 솔루션 재사용을 지원하기 위해 MediaPipe 그래프를 Subgraph로 정의할 수 있습니다. 하위 그래프 공개 인터페이스는 Calculator의 공개 인터페이스와 유사한 일련의 입력 및 출력 스트림으로 구성됩니다. 그러면 하위 그래프가 Calcualtor인 것처럼 CalculatorGraphConfig에 포함될 수 있습니다. CalculatorGraphConfig에서 MediaPipe 그래프가 로드되면 각 하위 그래프 노드가 해당 Calculator 그래프로 대체됩니다. 결과적으로 하위 그래프 의미 및 성능은 해당 Calculator 그래프와 동일합니다.

ex)

  1. 하위 그래프를 정의합니다.
type : "TwoPassThroughSubgraph"
input_stream : "out1"
output_stream : "out3"

node {
  calculator : "PassThroughCalculator"
  input_stream : "out1"
  output_stream : "out2"
}
node {
  calculator : "PassThroughCalculator"
  input_stream : "out2"
  output_stream : "out3"
}

하위 그래프 공개 인터페이스는 다음으로 구성되어 있습니다.

  • Graph input streams
  • Graph output streams
  • Graph input side packets
  • Graph output side packets
  1. BUILD 규칙 mediapipe_simple_subgraph를 통해 하위 그래프를 등록합니다. 매개변수 register_as는 새 하위 그래프의 구성요소 이름을 정의합니다.
mediapipe_simple_subgraph(
  name = "twopassthrough_subgraph",
  graph = "twopassthrough_subgraph.pbtxt",
  register_as = "TwoPassThroughSubgraph",
  deps = [
      "//mediapipe/calculators/core:pass_through_calculator",
      "//mediapipe/framework:calculator_graph",
  ],
)
  1. 하위 그래프를 메인 그래프에 사용합니다.

input_stream "in"
node {
  calculator : "PassThroughCalculator"
  input_stream : "in"
  output_stream : "out1"
}
node {
  calculator : "TwoPassThroughSubgraph"
  input_stream : "out1"
  output_stream : "out3"
}
node {
  calculator : "PassThroughCalculator"
  input_stream : "out3"
  output_stream : "out4"
}

주기

기본적으로 MediaPipe는 Calcualtor 그래프가 비주기적이어야 하고 그래프 주기를 오류로 처리해야 합니다. 그래프에 주기가 있어야 하는 경우 그래프 구성에서 주기에 주석을 달아야 합니다. 이 섹션에서는 이를 어떻게 하는 지에 대해 설명합니다.

(참고 : 이는 변경될 수 있는 사항입니다)

샘플 코드로 mediapipe/framework/calculator_graph_test.ccCalculatorGraphTest.Cycle 단위 테스트를 사용하세요. 아래는 테스트의 순환 그래프입니다. adder의 sum 출력은 정수 source calculator에서 생성된 정수 합입니다.

calculator_graph_test.cc 예시 순환 그래프

Back Edge Annotation

각 주기 edge는 back edge로 주석 처리되어야 합니다. 이렇게 하면 back edges를 모두 제거한 후 MediaPipe의 토폴로지 정렬이 작동합니다.
일반적으로 back edges를 선택하는 방법엔 여러 가지가 있습니다. back edges로 표시된 edges는 up streams로 간주되는 노드와 down streams로 간주되는 노드에 영향을 미치며, 이는 MediaPipe가 노드에 할당하는 우선 순위에 영향을 줍니다.
예를 들어, CalculatorGraphTest.Cycle 테스트는 old_sum edge를 back edge로 표시하므로 Delay 노드는 Adder 노드의 다운스트림 노드로 간주되고 더 높은 우선 순위가 부여됩니다. 또는 delay node에 대한 sum 입력을 back edges로 표시할 수 있습니다. 이 경우 delay node는 Adder 노드의 업스트림 노드로 간주되고 더 낮은 우선 순위가 부여됩니다.

Initial Packet

정수 소스의 첫 번째 정수가 도착할 때 Adder Calculator를 실행할 수 있으려면 Adder에 대한 old_sum 입력 스트림에서 값이 0이고 타임스탬프가 동일한 초기 패킷이 필요합니다. 이 초기 패킷은 Open() 메소드의 delay Calculator에 의해 출력되어야 합니다.

Delay in a Loop

각 루프는 이전 sum 출력을 다음 정수 입력과 정렬하기 위해 지연을 발생시켜야 합니다. 이것 또한 delay node에 의해 수행됩니다. 따라서 delay node는 정수 source Calculator의 타임스탬프에 대해 다음을 알아야 합니다.

  • 첫 번째 출력 타임스탬프
  • 연속 출력 간 타임스탬프 delta

패킷 순서만 신경쓰고 패킷 타임스탬프는 무시하는 대체 스케줄링 정책을 추가해 불편함을 없앨 계획입니다. (추후 기능이 추가된다는 의미인 듯)

Early Termination of a Calculator When One Input Stream is Done

기본적으로 MeidaPipe는 모든 입력 스트림이 완료되면 source가 아닌 Calculator의 Close() 메소드를 호출합니다. 그러나 예제 그래프에서 정수 source가 완료되는 즉시 Adder 노드를 중지하려 합니다. 이는 대체 입력 스트림 핸들러인 EarlyCloseInputStreamHandler로 Adder 노드를 구성하여 수행됩니다.

Relavant Source Code

DELAY CALCULATOR

초기 패킷을 출력하는 Open() 코드와 입력 패킷에 (단위) 지연을 추가하는 Process() 코드에 유의하십시오. 위에서 언급했듯 이 delay node는 출력 스트림이 패킷 타임스탬프가 0, 1, 2, 3, ...인 입력 스트림과 함께 사용된다 가정합니다.

class UnitDelayCalculator : public Calculator {
  public : 
    static absl::Status FillExpectations(
      const CalcualtorOptions& extendable_options, PacketTypeSet* inputs,
      PacketTypeSet* outputs, PacketTypeSet* input_side_packets) {
    inputs->Index(0)->Set<int>("An Integer.");
    outputs->Index(0)->Set<int>("The inputdelayed by one time unit.");
    return absl::OkStatus();
  }

  absl::Status Open() final {
    Output()->ADD(new int(0), Timestamp(0));
    return absl::OkStatus();
  }

  absl::Status Process() final{
    const Packet& packet = Input()->Value();
    Output()->AddPacket(packet.At(pakcet.Timestamp().NextAllowedInStream()));
    return absl::OkStatus();
  }
};

GRAPH CONFIG

back_edge주석과 대체 input_stream_handler에 유의하십시오.

node {
  calculator : "GlobalCountSourceCalculator"
  input_side_packet : "global_counter"
  output_stream : "integers"
}
node {
  calculator : "IntAdderCalculator"
  input_stream : "integers"
  input_stream : "old_sum"
  input_stream_info: {
    tag_index : ":1"
    back_edge : true
  }
  output_stream : "sum"
  input_stream_handler {
    input_steram_handler : "EarlyCloseInputStreamHandler"
  }
}
node {
  calculator : "UnitDelayCalculator"
  input_stream : "sum"
  output_stream : "old_sum"
}

참고 : https://google.github.io/mediapipe/framework_concepts/graphs.html

+ Recent posts