PART 4 텔레오퍼레이션과 모방학습 · 약 40분

16정책 학습과 추론

ACT·Diffusion·SmolVLA 같은 모방학습 정책을 학습하고, 실제 팔에서 추론·평가하는 루프를 만듭니다.

정책(policy)이란#

정책은 "지금 보이는 것(관측)" 을 받아 "다음에 할 행동" 을 내놓는 함수입니다. 모방학습에서는 이 함수를 신경망으로 만들고, 15장에서 모은 시연 데이터로 사람의 행동을 흉내 내도록 학습시킵니다.

text
입력:  카메라 영상(front, side …) + 팔로워 관절 상태 (+ 작업 문장)
   ↓   [정책 신경망]
출력:  다음 관절 목표값 (action) — 한 개 또는 한 묶음(chunk)

학습이 끝나면 리더 암 대신 정책이 action 을 만들어 팔로워에 보냅니다. 13장의 텔레오퍼레이션 루프에서 "사람" 자리만 신경망으로 바뀐 것입니다.

① 시연 수집 lerobot-record ② 정책 학습 lerobot-train ③ 추론 · 평가 --policy.path · eval_* ④ 실패 분석 성공률 · 실패 단계 · 위치 데이터셋 체크포인트 평가 결과 약한 곳 보강 수집 개선의 대부분은 데이터에서 나옵니다
모방학습은 한 번에 끝나지 않습니다. 수집 → 학습 → 평가 → 실패 분석 → 보강 수집을 반복합니다.

어떤 정책을 고를까#

Seeed 위키(DM · RS)의 Training and Evaluation 절은 ACT, SmolVLA, Pi0, Pi0.5, GR00T N1.5 를 다룹니다. 위키는 --policy.type 으로 act, diffusion, pi0, pi0fast, sac, smolvla 등을 바꿔 쓸 수 있다고도 적습니다.

정책종류위키 예시 설정특징 · 요구 사항
ACT처음부터 학습--policy.type=act, --steps=300000가장 무난한 출발점. 행동을 묶음(chunk)으로 예측
Diffusion Policy처음부터 학습--policy.type=diffusion같은 장면에 정답이 여러 개인 작업에 강함 (위키는 타입 이름만 언급)
SmolVLA사전학습 모델 미세조정--policy.path=lerobot/smolvla_base, --batch_size=64, --steps=20000약 450M 파라미터, 언어 지시를 함께 입력
Pi0 / Pi0.5사전학습 VLA 미세조정--policy.type=pi0·pi05, pretrained_path=lerobot/pi0_base·pi05_base, --steps=3000, --batch_size=32Physical Intelligence 의 VLA, bfloat16 · gradient checkpointing 사용
GR00T N1.5사전학습 모델 미세조정--policy.type=grootNVIDIA 의 오픈 파운데이션 모델. CUDA GPU + flash-attn 필수

VLA(Vision-Language-Action) 는 영상과 *문장*을 함께 이해해 행동을 내는 큰 모델입니다. "빨간 블록을 상자에 넣어" 같은 지시를 바꿔 가며 여러 작업을 한 모델로 할 수 있지만, GPU·시간이 훨씬 많이 듭니다. 위키도 GR00T 에 대해 "ACT / Pi0 를 먼저 돌려 본 뒤 시도하라" 고 권합니다.

처음이라면 ACT

ACT 는 설정이 단순하고, 데이터 50 에피소드 정도로 결과를 볼 수 있으며, 위키의 기본 예시이기도 합니다. ACT 로 성공률을 확보한 다음 다른 정책과 비교하세요. 같은 데이터로 정책만 바꿔 보면 "데이터 문제인지 모델 문제인지" 를 가르기 쉬워집니다.

Action chunking — ACT 의 핵심

ACT 는 다음 행동 하나가 아니라 앞으로의 여러 스텝을 한 묶음으로 예측합니다. 한 스텝씩 예측하면 작은 오차가 누적돼 팔이 떨리기 쉬운데, 묶음으로 예측하면 궤적이 부드러워지고 사람 시연의 "머뭇거림" 에도 덜 흔들립니다. 겹치는 묶음들을 평균 내어(temporal ensembling) 더 매끄럽게 만들기도 합니다.

한 스텝씩 예측 매 스텝 관측 → 1개 행동, 오차가 쌓여 떨림 묶음(chunk) 예측 한 번 관측 → 앞으로 여러 스텝을 한꺼번에 chunk 1 chunk 2 chunk 3
한 스텝씩 vs 묶음(chunk) 예측. 묶음 예측은 몇 스텝 앞까지의 궤적을 한 번에 내놓습니다.

README 의 커뮤니티 쇼케이스에는 GR00T 계열 모델, Gemma 해커톤 프로젝트 등 reBot 으로 VLA 를 돌린 사례가 소개되어 있으니 아이디어를 얻을 때 둘러보세요.


학습 명령 — ACT#

위키(DM)의 ACT 학습 예시입니다. 로컬 데이터셋(15장에서 push_to_hub=false 로 녹화)이라면 repo_id 를 녹화 때와 똑같이 쓰고 --policy.push_to_hub=false 를 붙입니다.

bash
lerobot-train \
  --dataset.repo_id=seeed_rebot_b601_dm/test \
  --policy.type=act \
  --output_dir=outputs/train/act_rebot_test \
  --job_name=act_rebot_test \
  --policy.device=cuda \
  --wandb.enable=false \
  --policy.push_to_hub=false \
  --steps=300000
인자뜻
--dataset.repo_id학습할 데이터셋 (Hub 면 ${HF_USER}/rebot_test 형태)
--policy.type정책 종류. 데이터셋에 저장된 관절 수·카메라 수에 자동으로 맞춰집니다
--output_dir체크포인트가 쌓이는 폴더
--policy.devicecuda(NVIDIA GPU), Apple Silicon 이면 mps
--steps학습 스텝 수. 위키는 기본값이 더 크다고 설명하며, 체크포인트가 중간중간 저장되므로 넉넉히 잡아도 된다고 안내
--wandb.enabletrue 면 Weights & Biases 로 학습 곡선 확인 (wandb login 필요)
환경별 주의 (위키)
  • RTX 50 시리즈: PyTorch 프리뷰(CUDA 12.8+)가 필요하고, 학습 명령에 --dataset.video_backend=pyav 를 추가합니다.
  • 학습이 끊겼다면 이어서: lerobot-train --config_path=outputs/train/act_rebot_test/checkpoints/last/pretrained_model/train_config.json --resume=true
  • 메모리가 부족하면 --batch_size 부터 줄이세요(위키 SmolVLA 팁).

SmolVLA 는 처음부터가 아니라 사전학습 모델에서 출발합니다.

bash
pip install -e ".[smolvla]"

lerobot-train \
  --policy.path=lerobot/smolvla_base \
  --dataset.repo_id=${HF_USER}/mydataset \
  --batch_size=64 \
  --steps=20000 \
  --output_dir=outputs/train/my_smolvla \
  --job_name=my_smolvla_training \
  --policy.device=cuda \
  --wandb.enable=true

Pi0·Pi0.5·GR00T 의 전체 옵션과 LoRA 같은 PEFT 미세조정, 여러 GPU 학습(accelerate launch --multi_gpu)은 위키의 해당 탭을 그대로 따르세요. 옵션이 많고 버전에 따라 자주 바뀝니다.


GPU 와 시간 감각#

상황위키에 적힌 참고치
ACT, 50 에피소드, RTX 3060(8GB) 노트북약 6시간
ACT, 50 에피소드, RTX 4090 / A100약 2~3시간
SmolVLA, 20k 스텝, A100 1장약 4시간
GR00T N1.5CUDA GPU + flash-attn 필수

GPU 가 없다면 위키는 공식 튜토리얼의 Colab 노트북을 권합니다. CPU 로도 명령은 돌지만 현실적인 시간이 아닙니다. Jetson(JetPack 6.0/6.1)은 위키가 지원하는 환경으로, 주로 추론 쪽에 씁니다.

하이퍼파라미터로 데이터 문제를 고칠 수 없습니다

학습 곡선(loss)이 잘 내려가도 실물에서 실패할 수 있습니다. 손실은 "시연을 얼마나 잘 흉내 내는가" 이지 "작업을 얼마나 잘 하는가" 가 아니기 때문입니다. 실패 원인의 대부분은 데이터(카메라 이동, 일관성 없는 시연, 부족한 위치 다양성)에 있습니다. 15장의 수집 원칙으로 돌아가세요.


추론과 평가#

위키 방식 — lerobot-record 에 정책 넣기#

Seeed 위키(포크 버전)는 녹화 명령에 --policy.path 를 넣어 정책이 팔을 움직이는 장면을 평가 데이터셋으로 녹화합니다.

bash
lerobot-record \
  --robot.type=seeed_b601_dm_follower \
  --robot.port=/dev/ttyACM0 \
  --robot.can_adapter=damiao \
  --robot.cameras='{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30, fourcc: "MJPG"}, side: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30, fourcc: "MJPG"} }' \
  --robot.id=follower1 \
  --display_data=false \
  --dataset.repo_id=seeed/eval_test123 \
  --dataset.single_task="Put lego brick into the transparent box" \
  --policy.path=outputs/train/act_rebot_test/checkpoints/last/pretrained_model
규칙이유
평가 데이터셋 이름은 eval_ 로 시작학습 데이터와 구분해 저장. 같은 이름 폴더가 있으면 File exists 오류 → 지우고 다시
카메라 이름(front, side)을 녹화 때와 똑같이다르면 mean is infinity ... 오류(정규화 통계를 못 찾음)
single_task 를 녹화 때와 같게언어 지시를 쓰는 VLA 에서 특히 중요
--policy.path로컬 체크포인트 경로 또는 Hub 모델 이름(${HF_USER}/act_rebot_test)

upstream LeRobot 의 새 방식#

LeRobot 공식 문서의 최신 버전은 정책 배포에 **lerobot-rollout** 을 쓰고, --strategy.type 으로 base(기록 없이 빠른 확인), episodic(에피소드 단위 평가 녹화), sentry(연속 녹화·자동 업로드), highlight, dagger(사람 개입 수집)를 고릅니다. 느린 VLA(Pi0, Pi0.5, SmolVLA)는 --inference.type=rtc 로 부드럽게 실행할 수 있다고 안내합니다. 쓰고 있는 LeRobot 버전의 문서를 따르세요. 위키 포크와 upstream 의 명령이 다릅니다.

비동기 추론#

큰 모델은 추론에 시간이 걸려 팔이 멈칫거립니다. 위키의 Async Inference 는 정책 서버(GPU PC)와 로봇 클라이언트(팔 옆 PC)를 나누고, 행동 묶음을 미리 받아 두는 방식입니다(python -m lerobot.async_inference.policy_server / robot_client, --actions_per_chunk=50, --fixed_update_fps=30 등). 위키는 이 통신에 인증이 없고 pickle 역직렬화를 쓰므로 공용 인터넷에 노출하지 말라고 경고합니다.

첫 자율 실행 안전 수칙
  • 정책이 팔을 움직이는 동안 전원 스위치(비상 정지)에 손을 둡니다. 사람이 아니라 신경망이 명령을 내므로 예상 밖 동작이 나올 수 있습니다.
  • 첫 실행은 짧게(episode_time_s 를 줄여서), 작업 공간을 비우고, 깨지거나 무거운 물체 없이.
  • 학습 때와 카메라 위치·조명·물체가 같아야 합니다. 다르면 이상한 곳으로 손을 뻗습니다.
  • 팔로워 전원(RS 48V / DM 24V)과 캘리브레이션 id 가 학습 데이터 수집 때와 같은지 확인합니다.

실패 분석과 보강 루프#

성공률은 감이 아니라 숫자로 봅니다. 평가 프로토콜을 정해 두세요 — 예: 물체 위치 5곳 × 2회 = 10회, 매번 같은 리셋 자세에서 시작.

회차위치결과실패 단계메모
1A성공—
2B실패접근블록 왼쪽 2 cm 를 집음
3C실패집기그리퍼가 일찍 닫힘
실패 패턴흔한 원인처방
특정 위치에서만 실패그 위치 시연 부족그 위치 에피소드 10개 추가
물체 근처에서 머뭇거림·진동시연마다 접근 방식이 다름접근 방향을 통일해 재수집
엉뚱한 곳으로 뻗음카메라 이동·조명 변화카메라 고정, 수집 환경 재현
집었다가 놓침그리퍼 닫힘 타이밍·힘닫은 뒤 잠깐 멈추는 시연, 잡기 쉬운 물체로 시작
처음부터 안 움직임카메라 이름·task 불일치, 잘못된 체크포인트명령 인자 재확인

정책이 실패하는 장면에서 사람이 개입해 바로잡은 시연을 추가하는 방식을 DAgger 라고 합니다. upstream 의 dagger 전략이 이를 지원합니다. 핵심은 같습니다 — 정책이 약한 곳의 데이터를 보강해서 다시 학습합니다.


시뮬레이터로 "닫힌 루프" 체험하기#

정책의 본질은 매 순간 다시 보고 다시 결정하는 것(닫힌 루프)입니다. 녹화된 동작을 그대로 재생하는 것(열린 루프)과 비교해 봅시다.

실습 — 재생 vs 관측 기반 정책
  1. 시뮬레이터에서 큐브를 켜고, 15장의 Playground 집기 코드를 실행하면서 녹화 탭으로 녹화합니다.
  2. 큐브를 다른 곳으로 옮긴 뒤 녹화 탭의 재생을 누르세요. 팔은 예전 큐브 자리로 가서 허공을 집습니다 — 이것이 열린 루프(lerobot-replay 와 같은 원리)입니다.
  3. 이제 Python 탭에서 아래 "손으로 만든 정책" 을 실행합니다. 매 단계 관측(arm.cube())을 다시 읽고 행동을 정합니다.
python
def policy(obs):
    """관측 → 행동. 학습된 신경망 대신 규칙으로 만든 아주 단순한 정책"""
    cube, tcp = obs["cube"], obs["tcp"]
    dx, dy = cube[0] - tcp[0], cube[1] - tcp[1]
    dist_xy = (dx*dx + dy*dy) ** 0.5
    if dist_xy > 0.01:                       # 아직 큐브 위가 아니면 → 수평으로 다가가기
        step = min(0.05, dist_xy)
        return ("move", tcp[0] + dx/dist_xy*step, tcp[1] + dy/dist_xy*step, cube[2] + 0.08)
    if tcp[2] > cube[2] + 0.015:             # 큐브 위면 → 내려가기
        return ("move", cube[0], cube[1], cube[2] + 0.01)
    return ("grasp",)

arm.home(); arm.open()
for t in range(20):                          # 최대 20 스텝의 닫힌 루프
    obs = {"cube": arm.cube(), "tcp": arm.fk()}
    act = policy(obs)
    print(t, act[0], [round(v, 3) for v in act[1:]])
    if act[0] == "grasp":
        arm.close(); arm.wait(0.3)
        x, y, z = arm.fk()
        arm.move_to(x, y, z + 0.06, t=1.0, down=True)
        break
    if not arm.move_to(act[1], act[2], act[3], t=0.5, down=True):
        print("IK 실패 — 도달 불가 위치"); break
  1. 큐브 위치를 바꿔 다시 실행해 보세요. 이번에는 새 위치를 따라갑니다. 학습된 정책도 이와 같이 매 프레임 카메라를 보고 다음 행동(묶음)을 정합니다. 차이는 규칙 대신 시연에서 배운 신경망이라는 점입니다.

Sim-to-Real VLA 코스 (Seeed × NVIDIA)#

README 의 B601-RS 로드맵 Isaac Sim Simulation 항목과 쇼케이스에는 Seeed 스토어의 "Learning Physical AI - A Sim-to-Real VLA Pipeline with Seeed reBot Arm and NVIDIA Isaac" 코스가 링크되어 있습니다(페이지). 시뮬레이션에서 데이터를 만들고 VLA 를 학습해 실물 reBot 으로 옮기는 흐름을 다루는 것으로 소개됩니다. 커리큘럼·가격·형식은 페이지에서 직접 확인하세요.

관련 오픈소스로 rebot-arm-dli-isaacsim 이 있습니다. README 에 따르면 NVIDIA 의 SO-101 Sim-to-Real 워크플로를 reBot B601-RS 에 맞춘 프로젝트로,

  • 실물 reBot Arm 102 리더로 Isaac Sim 4.5 속 B601-RS 를 60 Hz 로 조종하고(물리 120 Hz),
  • 손목 front · 고정 side 카메라로 LeRobot Dataset v3 를 녹화하며,
  • 물체 위치·질량·조명·손목 카메라에 도메인 무작위화를 겁니다.

시뮬레이션 데이터 → 정책 학습 → 실물 추론의 다리는 20장에서 Isaac Sim · MuJoCo 와 함께 자세히 봅니다.


정리#

  • 정책 = 관측(영상 + 관절 상태 + 문장) → 행동. 텔레오퍼레이션의 사람 자리를 신경망이 대신합니다.
  • 위키가 다루는 정책: ACT(첫 선택), SmolVLA(lerobot/smolvla_base, 20k 스텝), Pi0/Pi0.5(3000 스텝, batch 32), GR00T N1.5(CUDA + flash-attn). Diffusion 도 --policy.type 으로 선택 가능.
  • 학습: lerobot-train --policy.type=act ..., 로컬 데이터면 --policy.push_to_hub=false, RTX 50 은 --dataset.video_backend=pyav. ACT 50 에피소드 ≈ RTX 3060 노트북 6시간, 4090/A100 2~3시간.
  • 평가(위키 포크): lerobot-record --policy.path=..., 데이터셋은 eval_ 접두어, 카메라 이름·task 는 학습 때와 동일. upstream 최신은 lerobot-rollout.
  • 성공률을 숫자로 재고, 실패 패턴별로 데이터를 보강해 다시 학습하는 루프를 돕니다.

확인 문제#

  1. ACT 가 다음 행동을 하나씩이 아니라 "묶음(chunk)" 으로 예측해서 얻는 장점은 무엇인가요?
  2. 로컬에 녹화한 seeed_rebot_b601_dm/test 로 ACT 를 학습할 때 반드시 맞춰야 할 인자 두 가지는?
  3. 평가 실행 시 mean is infinity ... 오류가 났습니다. 가장 먼저 의심할 것은?
  4. 학습 loss 는 잘 내려갔는데 실물 성공률이 낮습니다. 하이퍼파라미터를 바꾸기 전에 확인해야 할 것은?
  5. 시뮬레이터 실습에서 녹화 재생(열린 루프)은 큐브를 옮기면 실패하고, 규칙 정책(닫힌 루프)은 성공했습니다. 차이의 이유는?
정답
  1. 여러 스텝의 궤적을 한 번에 내므로 작은 오차의 누적과 떨림이 줄고, 시연의 머뭇거림에도 덜 흔들려 동작이 부드러워집니다.
  2. --dataset.repo_id 를 녹화 때와 똑같이(seeed_rebot_b601_dm/test) 쓰고, Hub 업로드를 끄는 --policy.push_to_hub=false 를 붙입니다.
  3. --robot.cameras 의 카메라 이름(예: front, side)이 데이터 수집 때와 다른지 확인합니다.
  4. 데이터 품질입니다 — 카메라·조명이 수집 때와 같은지, 시연이 일관됐는지, 실패 위치의 시연이 충분한지 확인하고 필요하면 보강 수집합니다.
  5. 재생은 예전 행동을 그대로 반복할 뿐 현재 상황을 보지 않습니다. 정책은 매 스텝 관측(큐브 위치)을 다시 읽고 행동을 정하므로 바뀐 위치를 따라갑니다.