LeRobot documentation

비디오 인코딩 매개변수

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

비디오 인코딩 매개변수

비디오 저장이 활성화되면 LeRobot은 타임스텝마다 하나의 이미지 파일을 저장하는 대신 각 카메라 스트림을 MP4 파일로 저장합니다. 비디오 인코딩은 시간 축을 따라 압축을 수행하므로, PNG 파일 묶음에 비해 데이터셋 크기와 I/O를 줄이는 경우가 많습니다. 모든 플레이어와 로더가 이해하는 MP4 형식을 유지하면서요.

MP4로 프레임을 인코딩하는 것은 완전한 FFmpeg 파이프라인입니다. 인코더 선택, 픽셀 포맷, GOP/키프레임, 품질 대 속도 트레이드오프, 선택적 추가 인코더 플래그 등이 포함됩니다. 이러한 설정의 대부분은 PyAV를 통해 전달되는 rgb_encoder의 중첩된 RGBEncoderConfig (lerobot.configs.video.RGBEncoderConfig)를 통해 사용자가 조정할 수 있습니다.

이 매개변수는 --dataset.rgb_encoder.<field>를 사용하여 CLI에서 설정할 수 있습니다(예: lerobot-record 또는 lerobot-rollout 사용). 동일한 블록은 해당 실행의 모든 카메라 비디오 스트림에 적용됩니다.

rgb_encoder가 효과를 내려면 비디오 저장이 켜져 있어야 합니다 — Python API에서는 use_videos=True, CLI에서는 --dataset.video=true(기록 기본값)를 사용하세요. 비디오가 꺼져 있으면 입력은 이미지로 유지되고 rgb_encoder는 무시됩니다.

언제 프레임이 기록되는지 인코딩되는지(스트리밍 vs. 에피소드 후)에 대한 세부 사항, 큐, 그리고 기타 최상위 --dataset.* 스위치는 Streaming Video Encoding을 참고하세요. 인코딩 파라미터 비교 및 실험은 video-benchmark Space를 참고하세요.


예시

lerobot-record \
    --robot.type=so100_follower \
    --robot.port=/dev/tty.usbmodem58760431541 \
    --robot.cameras="{laptop: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}" \
    --robot.id=black \
    --teleop.type=so100_leader \
    --teleop.port=/dev/tty.usbmodem58760431551 \
    --teleop.id=blue \
    --dataset.repo_id=<my_username>/<my_dataset_name> \
    --dataset.num_episodes=2 \
    --dataset.single_task="Grab the cube" \
    --dataset.streaming_encoding=true \
    --dataset.encoder_threads=2 \
    --dataset.rgb_encoder.vcodec=h264 \
    --dataset.rgb_encoder.preset=fast \
    --dataset.rgb_encoder.extra_options='{"tune": "film", "profile:v": "high", "bf": 2}' \
    --display_data=true

파라미터 조정

기본값은 일반적인 로봇공학 데이터셋에 대해 압축률, 시각적 품질, 디코딩/시크 속도를 균형 있게 맞추도록 조정되어 있습니다. 이를 변경하면 녹화(CPU 부하, 프레임 드롭)와 학습(디코딩 처리량, 이미지 품질) 모두에 영향을 미칠 수 있습니다.

이 매개변수들은 특정 이유가 있을 때만 재정의하고, 새로운 설정에 의존하기 전에 파이프라인에 미치는 영향을 측정하세요.

아래의 모든 플래그는 CLI에서 --dataset.rgb_encoder. 접두사가 붙습니다.

매개변수유형기본값설명
vcodecstr"libsvtav1"비디오 코덱 이름. "auto"는 고정된 우선순위 목록에서 첫 번째 사용 가능한 하드웨어 인코더를 선택하며, 사용할 수 없으면 libsvtav1로 대체됩니다.
pix_fmtstr"yuv420p"출력 픽셀 형식. FFmpeg 빌드에서 선택한 코덱이 지원해야 합니다.
gint2GOP 크기 — g프레임마다 하나의 keyframe을 생성합니다. FFmpeg 옵션 g으로 출력됩니다.
crfint 또는 float30코덱별로 매핑된 추상적 품질 값(자세한 내용은 매핑 참조). 매핑이 단조일 경우, 값이 낮을수록 품질이 높고 출력 크기가 커집니다.
presetint 또는 str12 *인코더 속도 프리셋; 코덱에 따라 의미가 다릅니다.
* 설정되지 않았고 vcodec=libsvtav1인 경우, LeRobot은 기본적으로 12를 사용합니다.
fast_decodeint0libsvtav1: 0–2, svtav1-params를 통해 전달됩니다.
h264 / hevc (소프트웨어): >0인 경우 tune=fastdecode를 설정합니다.
기타 코덱: 일반적으로 사용되지 않습니다.
video_backendstr"pyav"현재 비디오 인코딩에는 "pyav"만 구현되어 있습니다.
extra_optionsdict{}Extra FFmpeg or codec specific options merged after the structured fields above. Cannot override keys already set by those fields.

깊이 스트림

Depth map(Intel RealSense, Reachy 2)은 RGB 스트림과 함께 독립적인 비디오 스트림으로 저장됩니다. 원시 depth(uint16 밀리미터 또는 float32 미터)는 8-bit 코덱을 통과할 수 없으므로, LeRobot은 각 map을 12-bit 코드([0, 4095])로 양자화합니다. 기본적으로 depth 센서의 1/depth 오차 프로파일에 맞추기 위해 로그 스케일로 양자화한 후, 이를 고 비트 깊이 픽셀 포맷(gray12le)에 패킹하여 12-bit 코덱으로 인코딩합니다.

원시 깊이 uint16 mm
float32 m
→
기록 시간 클립 [depth_min,
depth_max] 범위
→ 양자화 12비트 코드 0–4095
로그(기본값) 또는 선형
→ 패킹 gray12le
평면
→ 인코딩 HEVC
Main 12
→ MP4 저장
스트림
→
로드 시간 역양자화 mm / m

--dataset.depth_encoder.<field>를 통해 설정되는 4개의 양자화 옵션을 추가한 DepthEncoderConfig를 사용하여 병렬 depth_encoder 블록으로 깊이 파이프라인을 구성합니다. 이 블록은 RGBEncoderConfig의 모든 필드(vcodec, pix_fmt, crf, …)를 공유합니다.

lerobot-record \
    ... \
    --dataset.depth_encoder.vcodec=hevc \
    --dataset.depth_encoder.depth_min=0.05 \
    --dataset.depth_encoder.depth_max=5.0 \
    --dataset.depth_encoder.use_log=true
매개변수유형기본값설명
vcodecstr"hevc"HEVC Main 12(12비트 지원 코덱, MP4 호환).
extra_optionsdict{"x265-params": "lossless=1"}Depth 기본값은 lossless(정확한 round-trip)이며, crf는 무시됩니다. 더 작은 lossy 스트림을 얻으려면 extra_options={}를 전달하고 crf를 설정하세요.
pix_fmtstr"gray12le"양자화 코드를 전달하는 데 사용되는 단일 채널 12비트 픽셀 형식입니다.
depth_minfloat0.01미터 단위의 깊이를 양자화 0에 매핑합니다. 해당 값은 디코딩 시 클리핑됩니다.
depth_maxfloat10.0미터 단위의 깊이를 양자화 4095에 매핑합니다. 해당 값 이상은 디코딩 시 클리핑됩니다.
shiftfloat3.50 근처에서 수치적 안정성을 위해 대수적 양자화에 사용되는 사전 로그 오프셋(미터). depth_min + shift > 0을 만족해야 합니다.
use_logboolTruetrue인 경우, 로그 공간에서 양자화합니다(일반적인 깊이 센서에 권장됨). 균일/선형 양자화를 사용하려면 false로 설정하세요.

depth_min, depth_max, shift는 입력深度的 단위와 관계없이 항상 미터로 해석됩니다. 입력은 자동 감지됩니다: 정수 배열(예: RealSense에서 바로 가져온 uint16 밀리미터)은 밀리미터로, 부동소수점 배열은 미터로 처리됩니다. depth_min / depth_max를 센서의 실제 작동 범위를 포괄하도록 선택하세요. 해당 범위를 벗어난 값은 포화(saturation) 상태가 되어 경계 부분의 디테일이 손실될 수 있습니다.

Depth 기능은 meta/info.json에서 "is_depth_map": true로 표시되며, 해당 quantizer 설정(video.depth_min, video.depth_max, video.shift, video.use_log)이 영구적으로 저장됩니다. 이를 통해 로드 시 depth를 물리적 단위로 역양자화할 수 있습니다.

로드 시 출력 단위

depth_encoder는 기록 시점의 문제입니다. 학습 중과 같은 로드 시점에 depth map이 역양자화되는 단위는 읽기 시점 플래그 --dataset.depth_output_unit로 별도로 설정됩니다:

lerobot-train \
    --dataset.repo_id=<my_username>/<my_dataset_name> \
    --dataset.depth_output_unit=m \
    --policy.type=act
매개변수유형기본값설명
depth_output_unitstr"mm"물리적 단위 깊이 맵은 로드 시 "mm"(밀리미터) 또는 "m"(미터)로 역양자화됩니다.

이것은 순수하게 디코딩 시의 표시 선택 사항이며, 저장된 비디오나 메타데이터를 변경하지 않으므로 동일한 데이터셋을 mm 또는 m으로 다시 인코딩 없이 읽을 수 있습니다. 깊이 카메라가 없는 데이터셋에는 영향을 미치지 않습니다.


데이터셋 메타데이터의 영속성

비디오 스트림의 첫 에피소드가 인코딩된 후, 인코더 구성은 각 비디오 기능 아래에 파일 자체에서 탐지된 값과 함께 데이터셋 메타데이터(meta/info.json)에 저장됩니다. 비디오 기능 observation.images.<camera>의 경우, info.json의 레이아웃은 다음과 같습니다:

{
  "features": {
    "observation.images.laptop": {
      "dtype": "video",
      "shape": [480, 640, 3],
      "info": {
        "video.height": 480,
        "video.width": 640,
        "video.codec": "h264",
        "video.pix_fmt": "yuv420p",
        "video.fps": 30,
        "video.channels": 3,
        "is_depth_map": false,
        "video.g": 2,
        "video.crf": 30,
        "video.preset": "fast",
        "video.fast_decode": 0,
        "video.video_backend": "pyav",
        "video.extra_options": { "tune": "film", "profile:v": "high", "bf": 2 }
      }
    }
  }
}

info 블록에는 두 가지 출처가 기여합니다:

소스출처필드
스트림에서 파생된PyAV를 사용하여 인코딩된 MP4에서 다시 읽습니다.video.height, video.width, video.codec, video.pix_fmt, video.fps, video.channels, is_depth_map, audio.*
인코더 기반RGBEncoderConfig / DepthEncoderConfig에서 가져왔습니다.video.g, video.crf, video.preset, video.fast_decode, video.video_backend, video.extra_options

이 블록은 첫 번째 에피소드에서 한 번만 채워집니다. 데이터셋의 모든 에피소드가 동일한 rgb_encoder로 인코딩되었다고 가정합니다. 녹화 중간에 인코더 설정을 변경하는 것은 지원되지 않으며, info.json에는 첫 번째 에피소드에 사용된 매개변수만 반영됩니다.


데이터셋 병합

merge_datasets로 데이터셋을 집계할 때, 비디오 파일은 재인코딩 없이 그대로 연결되고, info.json의 인코더 필드는 키별로 병합됩니다:

병합 규칙필드동작
일치해야 함video.codec, video.pix_fmt, video.height, video.width, video.fpsStream에서 파생된 필드는 소스 간에 일치해야 하며, 그렇지 않으면 FFmpeg의 concat demuxer가 실패합니다.
느슨하게 병합됨video.g, video.crf, video.preset, video.fast_decode, video.extra_optionsEncoder-tuning 필드. 모든 소스가 일치하면 값이 유지되고, 일치하지 않으면 null(video.extra_options의 경우 {})로 설정되고 경고가 기록됩니다.
Update on GitHub