LeRobot documentation

언어 열 및 레시피

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

언어 열 및 레시피

대부분의 LeRobot 데이터셋은 에피소드당 task 문자열 하나를 포함합니다. 이는 짧은 단일 지시 기반 스킬에는 적합하지만, 현재 연구 분야가 나아가고 있는 장기 목표, 멀티모달 로봇 정책(고급 계획, 기억, 중재, VQA, 도구 사용)에는 충분하지 않습니다. 이러한 정책을 데이터셋 포크 없이 지원하기 위해 LeRobot은 LeRobotDataset에 두 개의 선택적 언어 컬럼과, 해당 행을 온디맨드 방식으로 채팅 스타일의 학습 샘플로 변환하는 작은 레시피 레이어를 추가했습니다.

설계는 세 가지 레이어로 명확하게 나뉩니다:

  1. 데이터셋의 데이터 — data/chunk-*/file-*.parquet의 프레임 옆에 저장되는 언어 어노테이션으로, 두 개의 선택적 컬럼(language_persistent 및 language_events)으로 구성됩니다. 이러한 컬럼이 없는 데이터셋은 기존 동작을 유지합니다.
  2. 레시피 — 어떤 어노테이션 행을 바인딩할지와 이를 채팅 턴(role, content, 선택적 이미지, 선택적 도구 호출)으로 어떻게 배치할지를 선언하는 YAML 파일입니다. 레시피는 순수한 설정이며, 새로운 레시피를 추가하려면 Python이 필요하지 않습니다.
  3. 학습 형식 — 샘플링 시점에 RenderTrainingMessagesStep은 레시피를 프레임별 주석과 대조하여 해결하고, 정책 프로세서가 소비하는 HF 스타일의 messages와 LeRobot 전용 사이드카(message_streams, target_message_indices)를 출력합니다.

이 페이지에서는 각 레이어를 순서대로 설명합니다.

Layer 1 — 데이터셋의 언어 열

두 개의 선택적 열은 data/chunk-*/file-*.parquet의 프레임 데이터 옆에 있습니다:

  • language_persistent: 에피소드의 모든 프레임에 걸쳐 브로드캐스트되는 행의 목록으로, subtask, plan, memory와 같이 활성 상태를 유지하는 상태를 나타냅니다.
  • language_events: interjection, vqa, 음성 도구 호출과 같이 이벤트가 방출된 정확한 프레임에서만 포함된 행의 목록

두 열은 동일한 행 구조를 공유합니다(이벤트 행은 행이 위치한 프레임이 이미 timestamp를 제공하므로 timestamp를 생략합니다):

role: string
content: string | null
style: string | null
timestamp: float32        # persistent rows only
camera: string | null     # observation.images.* feature key, view-dependent rows only
tool_calls: list[Json] | null

camera 필드는 content이 특정 카메라 뷰에 기반한 행을 태그합니다. 뷰 의존 스타일(vqa 및 trace)의 행은 camera를 일치하는 observation.images.* 기능 키로 설정해야 합니다. motion을 포함한 모든 다른 스타일의 행은 camera를 null로 두어야 합니다. motion은 관절/카르테시안 용어로 로봇 프레임 원시를 설명합니다. 파이프라인 작성기와 검증기는 validate_camera_field(style, camera)를 통해 이를 강제합니다.

meta/tasks.parquet은 여전히 해당 task의 공식 출처입니다. 특수한 ${task} recipe 바인딩은 항상 해당 task 문자열을 읽으며 언어 어노테이션에 의존하지 않습니다.

아키텍처

언어 스택 자체에는 1층을 뒷받침하는 세 개의 내부 모듈이 있습니다:

  1. lerobot.datasets.language는 스키마, 스타일 레지스트리, column_for_style를 정의합니다.
  2. lerobot.datasets.language_render은 행을 해석하고 메시지를 렌더링합니다.
  3. RenderTrainingMessagesStep는 데이터셋 샘플을 messages, message_streams, target_message_indices로 변환합니다.

LeRobotDataset은 레시피에 종속되지 않습니다. language_persistent와 language_events가 존재하는 경우 이를 그대로 전달하며, 주석이 없는 데이터셋은 기존 동작을 유지합니다.

Layer 2 — 레시피 구조

Recipes는 lerobot.datasets.recipe의 TrainingRecipe와 MessageTurn에 기반한 YAML 파일입니다. bindings를 통해 어떤 annotation row를 가져올지, 그리고 messages를 통해 이를 어떻게 chat turn으로 구성할지를 선언합니다.

messages:
  - { role: user, content: "${task}", stream: high_level }
  - { role: assistant, content: "${subtask}", stream: low_level, target: true }

레시피는 하위 레시피의 가중치 블렌드로 분기될 수도 있습니다. 샘플링 시에는 샘플 인덱스에서 결정적으로 정확히 하나의 분기가 선택되므로, Python 배선 없이도 서로 다른 프레임이 서로 다른 목적(예: 메모리 업데이트 대 저수준 실행 대 VQA)을 학습합니다.

시간적 의미론

지속 스타일은 방출된 후 대체될 때까지 활성화됩니다:

  • active_at(t, style=subtask)
  • nth_prev(style=memory, offset=1)
  • nth_next(style=subtask, offset=1)

이벤트 스타일은 정확한 타임스탬프에서만 존재합니다:

  • emitted_at(t, style=interjection)
  • emitted_at(t, style=vqa, role=user, camera=observation.images.top)
  • emitted_at(t, role=assistant, tool_name=say)

Exact event matching에는 허용 오차 창이 없으므로, 작성자는 parquet 데이터의 프레임 타임스탬프로 이벤트 행에 타임스탬프를 부여해야 합니다.

뷰 의존적 해상도

뷰 의존 스타일(vqa 및 trace)의 경우, 리졸버는 role=와 tool_name=와 병렬로 camera= 필터를 갖게 됩니다. 여러 카메라를 가진 데이터셋은 일반적으로 동일한 타임스탬프에서 카메라별로 (vqa, user) + (vqa, assistant) 쌍을 하나씩 출력합니다. camera=가 없으면 해당 리졸버는 두 개의 매치를 보고 모호성 오류를 발생시킵니다. 레시피는 각 카메라를 자체 바인딩과 일치하는 이미지 블록을 통해 소비합니다. 예를 들어

ask_vqa_top:
  route: vqa
  bindings:
    vqa_query: "emitted_at(t, style=vqa, role=user, camera=observation.images.top)"
    vqa: "emitted_at(t, style=vqa, role=assistant, camera=observation.images.top)"
  messages:
    - role: user
      stream: high_level
      if_present: vqa_query
      content:
        - { type: image, feature: observation.images.top }
        - { type: text, text: "${vqa_query}" }
    - {
        role: assistant,
        content: "${vqa}",
        stream: high_level,
        target: true,
        if_present: vqa,
      }

데이터셋이 기록하는 카메라별로 이러한 서브 레시피를 하나씩 추가합니다. 명시적인 route: vqa 마커는 일반적인 가중 혼합 선택보다 일치하는 희소 VQA 주석이 우선 적용되도록 하며, 구성 요소 이름은 단순히 설명적인 용도입니다.

3층 — 학습 형식

렌더링된 샘플은 HF 스타일의 채팅 메시지와 LeRobot 사이드카를 사용합니다:

sample["messages"]
sample["message_streams"]
sample["target_message_indices"]

렌더러는 토크나이저 채팅 템플릿을 적용하지 않습니다. 정책 프로세서가 백본에 맞게 메시지를 직렬화하는 방식을 결정하므로, 동일한 데이터셋을 SmolVLA, Pi0.5, 그리고 OpenAI 스타일의 채팅 메시지를 기대하는 향후 모든 VLM에서 사용할 수 있습니다.

블렌드

Blend 레시피는 샘플 인덱스를 기반으로 가중치가 부여된 서브레시피 중 하나를 결정적으로 선택합니다. recipes/subtask_mem.yaml은 컴팩트한 코어 블렌드를 학습합니다. 여기에는 고수준 서브태스크 예측, 저수준 실행, 메모리가 포함됩니다. recipes/subtask_mem_vqa_speech.yaml은 VQA 및 구어체 끼어들기 응답도 추가하는 더 완전한 변형입니다.

recipes/subtask_joint.yaml는 가중 혼합이 아닌 결합 시퀀스 학습을 보여줍니다. 동일한 샘플에 대해, 어시스턴트 서브태스크는 low_level 스트림에서 텍스트 교차 엔트로피로 감독되는 반면 동작 예측은 활성화된 상태로 유지되며, 이는 π0.5 논문에서 제시한 결합 설정과 일치합니다. 현재는 학습 전용입니다. 런타임은 추론 시 이 결합 접두사를 아직 재구성하지 않습니다.

Graceful absence

두 언어 열이 모두 없거나, None이거나, 비어 있으면, RenderTrainingMessagesStep은 사용 가능한 경우 태스크 문자열을 저수준 감독으로 사용하고, 그렇지 않으면 샘플을 변경하지 않습니다. 주석이 달린 샘플의 경우, 적용되는 레시피 분기가 없고 태스크 폴백도 없으면 렌더링이 None을 반환하여 로더가 다른 샘플을 다시 시도할 수 있도록 합니다.

Update on GitHub