For the complete documentation index, see llms.txt. This page is also available as Markdown.

Workflows 컴파일러

Workflows 컴파일러가 Workflow 정의를 실행 가능한 계산 그래프로 변환하는 방식.

컴파일은 프로그래밍 언어로 작성된 문서를 가져와 그 정확성을 검사하고, 실행 환경이 이해할 수 있는 형식으로 변환하는 과정입니다.

워크플로 정의를 실행하고 싶을 때마다 Workflows 생태계에서도 유사한 과정이 일어납니다. Workflows 컴파일러는 JSON 문서를 계산 그래프로 변환하기 위해 여러 단계를 수행하고, 이후 그 그래프는 Workflows 실행 엔진에 의해 실행됩니다. 이 과정은 복잡할 수 있지만, 생태계에 기여하는 개발자에게는 이를 이해하는 것이 도움이 될 수 있습니다. 이 문서에서는 Workflow 블록을 구축하는 데 도움이 되도록 컴파일 과정의 핵심 세부 사항을 설명하고, 핵심 실행 엔진에 대한 기여를 장려합니다.

이 문서는 실행 엔진의 설계를 다룹니다 v1 (이는 현재 안정 버전입니다). 다음에 대한 정보도 확인해 주세요 버전 관리 를 통해 실행 엔진 개발 주기를 이해할 수 있습니다.

컴파일 단계

워크플로 컴파일은 다음을 포함한 여러 단계로 이루어집니다.

  1. 사용 가능한 블록 로드: 실행 환경의 구성에 따라 워크플로에서 사용할 수 있는 모든 블록을 수집합니다

  2. 동적 블록 컴파일: 동적 블록 정의를 표준 Workflow 블록으로 변환합니다

  3. 워크플로 정의 구문 분석: 워크플로를 정의하는 JSON 문서를 읽고 해석하며, 구문 오류를 감지합니다

  4. Workflow 실행 그래프 구축: 실행 중 데이터가 워크플로를 통해 어떻게 흐를지를 정의하는 그래프를 만들고 Workflow 무결성을 검증합니다

  5. 블록에서 Workflow 단계 초기화: 사용 가능한 블록, 단계 정의 및 실행 환경의 구성을 기반으로 개별 워크플로 단계를 설정합니다.

정의에 roboflow_core/inner_workflow@v1 단계가 포함되어 있으면, 컴파일러는 먼저 저장된 워크플로 참조를 해석하고, 중첩된 구성 (깊이, 총 개수, 비순환성)을 검증한 뒤 인라인으로 펼칩니다 자식 단계를 부모 이전 로 파싱하고 실행 그래프를 구축합니다. 전체 파이프라인은 내부 워크플로(중첩 정의) 를 참조하고 parameter_bindings및 환경 제한도 확인하세요.

워크플로 컴파일 단계 각각을 좀 더 자세히 살펴보겠습니다.

Workflows 블록 로딩

에서 설명한 대로 블록 번들링 가이드에 따라, Workflow 블록 그룹을 워크플로 플러그인으로 패키징할 수 있습니다. 플러그인은 본질적으로 표준 Python 라이브러리이며, 메인 모듈에서 Workflow 블록을 동적으로 로드할 수 있게 하는 특정 함수를 노출합니다.

Workflows 컴파일러와 실행 엔진은 특정 Workflow 블록에 종속되지 않도록 설계되어 있으며, 컴파일러는 플러그인에서 블록을 검색하고 로드할 수 있습니다.

Roboflow는 roboflow_core 플러그인을 제공합니다. 여기에는 컴파일러가 항상 로드하는 기본 Workflow 블록 세트가 포함되어 있으며, 컴파일러와 이 블록들은 모두 inference 패키지에 함께 포함되어 있습니다.

사용자 정의 플러그인의 경우, Python 환경에 설치된 뒤에는 WORKFLOWS_PLUGINS라는 환경 변수를 사용해 참조해야 합니다. 이 변수에는 플러그인이 들어 있는 Python 패키지 이름을 쉼표로 구분해 넣어야 합니다.

예를 들어, 두 개의 사용자 정의 플러그인 numpy_pluginpandas_plugin가 있다면, 다음처럼 설정하여 Workflows 환경에서 활성화할 수 있습니다.

둘 다 numpy_pluginpandas_plugin 라이브러리 저장소의 경로가 아니라플러그인을 제공하는 라이브러리의 मुख्य 모듈 이름입니다(import numpy_plugin 가 Python 환경에서 작동해야 플러그인을 로드할 수 있습니다).

컴파일러가 모든 플러그인을 로드하면 다음 컴파일 단계로 진행할 준비가 됩니다.

동적 블록 컴파일

에 대한 주제는 동적 Python 블록 전용 문서 페이지에서 다룹니다. 이 섹션의 내용을 이해하려면, Workflow 정의 안에서 블록 매니페스트와 Python 코드를 모두 JSON 문서에 지정하여 Workflow 블록을 그 자리에서 정의할 수 있는 방법이 있다는 것만 알면 됩니다. 이 기능은 Workflows 실행 엔진을 자체 하드웨어에서 실행할 때만 작동하며 Roboflow 호스팅 플랫폼에서는 비활성화되어 있습니다.

Workflows 컴파일러는 Workflow 정의 안에 직접 정의된 동적 Python 블록을 런타임에 완전한 Workflow 블록으로 변환할 수 있습니다. 컴파일러는 블록 정의를 기반으로 이러한 블록 클래스를 동적으로 생성하므로, 플러그인에서 하듯이 개발자가 이를 수동으로 만들 필요가 없습니다.

이 과정이 완료되면 동적 블록은 사용 가능한 Workflow 블록 풀에 추가됩니다. 그런 다음 이 블록들은 Workflow 정의의 steps 섹션에서 다른 표준 블록과 마찬가지로 사용할 수 있습니다.

Workflow 정의 구문 분석

모든 Workflow 블록이 로드되면 컴파일러는 각 블록의 매니페스트 클래스를 가져옵니다. 이러한 매니페스트는 pydantic 정의에서 단계 항목의 구조를 정의하는 데이터 클래스입니다. 구문 분석 단계에서 Workflows 정의의 오류가 경고되며, 예를 들면 다음과 같습니다.

  • 존재하지 않는 블록의 사용

  • 잘못된 단계 구성

  • 단계에 필요한 매개변수 누락

덕분에 pydanticWorkflows 컴파일러는 자체 파서가 필요하지 않습니다. 또한 블록 작성자는 표준 Python 라이브러리를 사용해 블록 매니페스트를 정의합니다.

Workflow 실행 그래프 구축

Workflow 실행 그래프를 구축하는 것은 Workflow 컴파일에서 가장 중요한 단계입니다. 동작 방식은 다음과 같습니다.

정점 추가

먼저 각 입력, 단계, 출력이 그래프의 정점으로 추가되며, 각 정점에는 나중에 식별할 수 있도록 특별한 레이블이 부여됩니다. 이러한 정점에는 데이터 계보 추적을 위한 시드로 입력 정점을 표시하는 것과 같은 메타데이터도 포함됩니다(자세한 내용은 뒤에서 설명합니다).

간선 추가

정점을 배치한 후 다음 단계는 Workflow에 정의된 선택자를 기반으로 정점들 사이에 간선을 만드는 것입니다. 컴파일러는 블록 매니페스트를 검사해 어떤 속성이 선택자를 받을 수 있는지와 그 선택자의 예상 "종류"가 무엇인지 확인합니다. 이를 통해 컴파일러는 Workflow 정의에서 다음과 같은 오류를 감지할 수 있습니다.

  • 한 단계의 출력 종류가 다음 단계의 예상 입력 종류와 일치하지 않는 경우를 제공하는 것.

  • 존재하지 않는 단계나 입력을 참조하는 것.

각 간선에는 출력 데이터가 어떤 입력 속성으로 전달되는지를 나타내는 메타데이터도 포함되어 있으며, 이는 컴파일의 후반 단계와 실행 중에 도움이 됩니다

일반적으로 단계 입력은 단계 출력에서 데이터를 "요청"하여, 단계 B가 처리되는 동안 단계 A의 출력에서 단계 B의 입력으로 이어지는 간선을 형성합니다. 그러나 제어 흐름 블록은 예외입니다. 이 블록들은 데이터를 수락하는 동시에 매니페스트에서 다른 단계를 선언하여 그래프에 특수한 흐름 제어 간선을 생성합니다.

구조적 검증

그래프가 구성되면 컴파일러는 그래프가 올바르게 실행될 수 있도록 순환과 같은 구조적 문제를 검사합니다.

데이터 계보 검증

마지막으로 데이터 계보 속성은 입력 노드에서 채워져 그래프 전체로 전달됩니다. 그렇다면 데이터 계보란 무엇일까요? 계보는 단계 전반에서 배치의 생성과 중첩을 추적하는 식별자 목록으로, 다음을 결정합니다.

  • 데이터의 소스 경로

  • 차원 수준 데이터의

  • 단계에서 참조될 수 있는 서로 다른 데이터 조각들의 호환성 - 해당 단계가 여러 소스에서 온 대응되는 배치 요소만 받도록 보장합니다(즉, 배치 요소 인덱스 예: (1, 2) 가 두 배치 지향 입력이 단계에 연결될 때 서로 다른 계보를 가진 무작위 배치를 받는 것이 아니라 정확히 같은 데이터 조각을 가리키게 함)

단계에 의해 새 중첩 배치가 생성될 때마다 고유 식별자가 출력의 계보에 추가됩니다. 이를 통해 컴파일러는 단계 간 입력이 호환되는지 추적하고 검증할 수 있습니다.

데이터 계보의 기본 가정은 모든 배치 지향 입력이 동일한 계보 식별자를 부여받는다는 것입니다. 따라서 이는 암묵적으로 모든 입력 배치가 배치 내 대응 위치에 있는 대응 데이터 포인트와 함께 입력되도록 강제합니다. 예를 들어, Workflow가 다음을 비교하는 경우 image_1image_2 (그리고 Workflow 정의에 이 두 입력을 선언한다고 가정하면), 컴파일러는 image_1[3] 의 요소가 image_2[3].

와 대응한다고 가정합니다.

전용 섹션에서 설명했듯이 블록 개발에서 각 블록은 입력과 출력의 예상 차원성을 정의할 수 있습니다. 이는 데이터가 어떻게 구조화되어야 하는지를 의미합니다. 예를 들어, 한 블록이 이미지 배치보다 한 단계 위에 있는 입력을 필요로 한다면 예측컴파일러는 Workflow 단계를 검증할 때 이 요구사항이 충족되는지 확인합니다. 단계 간 연결이 예상 차원성과 일치하지 않으면 오류가 발생합니다. 또한 각 입력은 데이터 계보를 기준으로 호환되는지도 검증됩니다. 단계가 검증을 통과하면 출력 차원성이 결정되고, 이후 단계와의 호환성을 검사하는 데 사용됩니다.

중요한 점은 블록이 차원성 요구사항을 절대적인 것이 아니라 상대적인 용어로 정의한다는 것입니다. 즉, 블록은 입력과 출력 사이의 차원성 차이(또는 오프셋)를 명시합니다. 이 접근 방식은 블록이 어떤 차원 수준에서도 유연하게 동작할 수 있게 합니다.

버전 1에서 Workflows 컴파일러는 두 개의 서로 다른 차원 수준의 조합차원에서 동작하는 블록만 지원합니다. 이는 설계를 단순하게 유지하기 위한 조치였습니다. 더 많은 차원 수준의 조합 차원을 처리하는 블록이 앞으로 필요하다면, 이 지원을 확장하는 것을 고려할 것입니다.

흐름 제어 표시

Workflows 컴파일러는 실행 엔진이 워크플로의 흐름 제어 구조를 관리하도록 돕습니다. 특정 단계의 입력 구축과 워크플로 그래프 실행에 흐름 제어가 어떻게 영향을 미치는지 시스템이 이해할 수 있게 해 주는 속성을 표시합니다(자세한 내용은 실행 엔진 문서).

를 참조하세요). 워크플로 구조가 올바른지 확인하기 위해 컴파일러는 데이터 계보 검증.

과 유사한 방식으로 흐름 제어 단계의 데이터 계보를 검사합니다. 컴파일러는 다음과 같은 경우 흐름 제어 단계가 다른 단계에 영향을 줄 수 있다고 가정합니다.

  • 흐름 제어 단계가 배치 지향이 아닌 입력에서 동작하는 경우 - 이 경우 흐름 제어 단계는 입력이 데이터 배치이더라도 연결된 단계(및 관련 단계)가 완전히 실행되도록 허용하거나 막을 수 있으며, 모든 배치 요소가 영향을 받습니다.

  • 흐름 제어 단계가 호환되는 계보를 가진 배치 지향 입력에서 동작하는 경우 - 이 경우 흐름 제어 단계는 배치의 각 요소별로 어떤 요소는 진행시키고 어떤 요소는 중지할지 개별적으로 결정할 수 있습니다.

배치 지향 호환성

앞서 설명했듯이, Workflows는 배치 지향 데이터스칼라를 정의합니다. Workflows에서 데이터의 성격에 대한 설명에서 볼 수 있듯이, 배치 지향 데이터를 대상으로 실행되는 연산은 거의 동등한 두 가지 실행 방식이 있습니다.

  • 한 번에 모두: 전체 데이터 배치를 가져와 처리하는 방식

  • 하나씩: 배치 요소를 순회하며 결과를 순차적으로 얻는 방식

Workflow 블록이 배치를 다루는 기본 방식은 요소별로 소비하는 것이므로 실질적인 차이는 없습니다 다음 사이에는 배치 지향 데이터스칼라 이런 경우에 해당합니다. 실행 엔진은 단순히 배치에서 스칼라 값을 꺼내 각 단계에 전달합니다.

블록이 배치 입력을 받을 때는 과정이 더 복잡해질 수 있습니다. 자세한 내용은 블록 개발 가이드에서 배우게 되지만, 블록은 반드시 제공되어야 하는 각 입력과 배치 단위로 제공될 수 있고 동시에 배치 지향 데이터와 스칼라 모두를 받을 수 있는 모든 입력을 표시해야 합니다(이 경우는 훨씬 드뭅니다). 이런 경우에는 계보 를 사용해 각 단계 입력에 실제로 공급되는 데이터가 배치 또는 스칼라인지 추론합니다. 위반이 감지되면(예를 들어 스칼라 배치가 필요한 입력에 스칼라가 제공되거나 그 반대의 경우) 오류가 발생합니다.

향후 개선 가능성

현재로서는 위에서 설명한 동작이 Workflows 생태계의 잠재력을 제한하는지 확실하지 않습니다. 설명한 메커니즘의 결과로 발생한 오류 때문에 Workflow를 실행할 수 없다면 GitHub 이슈.

를 통해 알려 주세요.

문서에서는 종종 Workflow Step을 프로토타입 역할을 하는 Workflow Block의 인스턴스로 언급합니다. 간단히 말해, Workflow Block은 특정 동작을 구현하는 클래스이며, 실행 엔진을 실행하는 환경, Workflow 정의, 또는 런타임 입력에 의해 설정되는 구성으로 사용자 정의할 수 있습니다.

프로그래밍에서는 보통 생성자를 사용해 클래스를 인스턴스화하며, 대개 초기화 매개변수가 필요합니다. 같은 맥락에서 Workflow Block은 Workflow의 어떤 단계가 해당 블록을 참조할 때마다 Workflows 컴파일러에 의해 초기화됩니다. 어떤 블록은 특정 초기화 매개변수가 필요할 수 있고, 어떤 블록은 필요하지 않을 수 있습니다.

블록에 초기화 매개변수가 필요한 경우:

  • 블록은 필요한 매개변수를 선언해야 하며, 이에 대한 자세한 설명은 블록 개발 가이드

  • Workflow가 실행되는 환경에서 이 매개변수의 값을 제공해야 합니다.

  • Workflow가 실행되는 환경에서 이 매개변수의 값을 제공해야 합니다.

이 두 번째 부분은 다소 까다로워 보일 수 있으므로, 예를 들어 살펴보겠습니다. 다음 사용자 가이드의에서 Workflows와 연동하는 방법을 보여 주는 섹션 아래에서 inference Python 패키지를 사용하면 다음과 같은 코드를 볼 수 있습니다.

이 예에서 workflow_init_parameters에는 컴파일러가 블록 요청에 따라 Workflow 단계를 초기화할 때 사용하는 값이 들어 있습니다.

초기화 매개변수(흔히 "init 매개변수"라고도 함)는 두 가지 방법으로 컴파일러에 전달할 수 있습니다.

  • 명시적으로: 특정 값(숫자, 문자열, 객체 등)을 제공합니다.

  • 암시적으로: 기본값이 Workflows 플러그인 내부에 정의되어 있으며, 특정 값일 수도 있고 환경 변수 등에서 값을 동적으로 생성하는 인자 없는 함수일 수도 있습니다.

딕셔너리 workflow_init_parameters 는 명시적으로 전달된 초기화 매개변수를 보여 줍니다. 키의 구조가 중요합니다. {plugin_name}.{init_parameter_name}입니다. 또한 {init_parameter_name}만 지정할 수도 있지만, 이렇게 하면 매개변수 해결 방식이 달라집니다.

매개변수는 어떻게 해결되나요?

컴파일러가 블록의 필요한 초기화 매개변수를 찾을 때 다음 과정을 따릅니다.

  1. 정확한 일치: 먼저 명시적으로 제공된 매개변수에서 {plugin_name}.{init_parameter_name}.

  2. 기본 매개변수: 일치하는 항목이 없으면 플러그인의 기본 매개변수를 확인합니다.

  3. 일반 일치: 마지막으로 명시적으로 제공된 매개변수에서 {init_parameter_name} 만으로 일반적인 일치를 찾습니다.

이 메커니즘은 일부 블록 매개변수는 기본값을 가질 수 있고 다른 매개변수는 명시적으로 제공되어야 하므로 유연성을 제공합니다. 또한 이를 통해 특정 매개변수를 서로 다른 플러그인 간에 공유할 수 있습니다.

마지막 업데이트

도움이 되었나요?