이 글의 실습 코드는 Hugging Face 공식 LeRobot 노트북을 기반으로 합니다. 원본 출처: Train ACT with LeRobot (Colab) LeRobot GitHub: https://github.com/huggingface/lerobot
들어가며
로봇이 무언가를 배운다는 것은 어떤 의미일까요.
어린아이가 젓가락 사용법을 배우는 장면을 생각해봅니다. 처음에는 어른이 직접 손을 잡아주고, 시범을 보여줍니다. 아이는 그 모습을 보고, 흉내 내고, 실패하고, 다시 따라 하면서 점점 능숙해집니다. 아무도 "엄지손가락을 몇 도 각도로 구부려라"고 가르쳐주지 않습니다. 그냥 보고 따라 하는 것뿐입니다.
로봇도 비슷한 방식으로 배울 수 있습니다. 사람이 직접 로봇을 조작해서 어떤 동작을 보여주면, 로봇은 그 과정을 데이터로 기록합니다. 그리고 그 기록을 학습해서, 나중에는 혼자서도 같은 일을 할 수 있게 됩니다. 이걸 모방학습(Imitation Learning) 이라고 합니다.
강화학습처럼 보상 함수를 설계할 필요도 없고, 수천 번 실패를 반복할 필요도 없습니다. 사람이 잘하는 것을 보여주기만 하면 됩니다. 개념은 단순하지만, 최근 로봇 연구에서 가장 활발하게 발전하고 있는 분야 중 하나입니다.
이번 글에서는 Hugging Face의 오픈소스 로봇 학습 프레임워크인 LeRobot을 이용해서, 모방학습의 전체 흐름을 직접 돌려봅니다. 복잡한 하드웨어도 필요 없습니다. Google Colab에서 무료 GPU만 있으면 처음부터 끝까지 실행해볼 수 있습니다.
1. 우리가 무엇을 만들려는 걸까
이번 실습에서 하려는 일을 한 줄로 요약하면 이렇습니다.
사람이 조작한 데이터를 보고, 로봇이 스스로 움직이는 정책(policy)을 학습한다.
여기서 정책(policy) 이라는 단어가 낯설 수 있습니다. 쉽게 말하면, 로봇이 현재 상황을 보고 다음에 어떤 행동을 할지 결정하는 함수입니다. 딥러닝에 익숙한 분이라면, 입력을 받아 출력을 내는 신경망 하나라고 생각하면 편합니다.
입력: 카메라 영상 + 현재 관절 위치 (observation)
출력: 다음에 취할 행동 (action)
사람으로 치면, 눈으로 상황을 보고 손을 어떻게 움직일지 결정하는 뇌의 일부분에 해당합니다.
그리고 이 정책을 학습시키는 방식이 바로 Behavior Cloning입니다. 사람의 행동을 데이터로 삼아, 지도학습(supervised learning)으로 모방하는 것입니다. 정답 레이블이 사람의 행동이라는 점에서, 우리가 알고 있는 이미지 분류나 객체 탐지 학습과 구조적으로 같습니다.
일반 지도학습: (이미지 → 레이블) 쌍으로 학습
Behavior Cloning: (상황 → 사람의 행동) 쌍으로 학습
정답이 "사람이 이 순간에 한 행동"이라는 것만 다를 뿐입니다.
2. LeRobot이란 무엇인가
LeRobot은 Hugging Face가 만든 로봇 학습 오픈소스 프레임워크입니다. 2025~2026년을 기준으로 로봇 모방학습 분야에서 가장 널리 쓰이는 도구 중 하나가 됐습니다. GitHub에서 수만 개의 스타를 받았고, 수백 명의 기여자가 함께 개발하고 있습니다.
LeRobot이 등장하기 전, 로봇 학습 연구에서는 데이터 형식이 연구팀마다 달랐습니다. 어떤 팀은 영상을 따로 저장하고, 어떤 팀은 관절 각도를 별도 CSV로 관리했습니다. 그러다 보니 서로 다른 연구의 데이터를 가져다 쓰기도 어려웠고, 코드 재사용도 힘들었습니다.
LeRobot은 이 문제를 표준화로 풀었습니다. 데이터 수집부터 저장, 학습, 배포까지 하나의 파이프라인으로 연결하고, 데이터셋 형식을 통일했습니다.
LeRobot이 하는 일은 크게 네 가지입니다.
데이터 수집 텔레오퍼레이션(원격 조작)으로 로봇 시연 데이터를 기록합니다. 사람이 조이스틱이나 다른 입력 장치로 로봇을 직접 조작하면, 그 과정에서 카메라 영상과 관절 데이터가 함께 기록됩니다.
데이터 저장 수집한 데이터를 LeRobotDataset 형식으로 저장하고, HuggingFace Hub에 공유할 수 있습니다. Hub에는 이미 수천 개의 공개 로봇 데이터셋이 올라와 있어서, 직접 로봇이 없어도 학습을 시작할 수 있습니다.
정책 학습 저장된 데이터로 모방학습 정책을 훈련합니다. ACT, Diffusion Policy, SmolVLA 등 다양한 모델을 지원합니다.
정책 배포 학습된 정책을 실제 로봇에 올려 실행합니다. SO-101, ALOHA, Unitree G1 같은 다양한 하드웨어를 지원합니다.
이번 실습에서는 이 중 데이터 확인과 정책 학습 두 단계를 집중적으로 해봅니다.
3. 어떤 작업을 학습하는가 — pusht 태스크
실습에서 사용하는 데이터셋은 lerobot/pusht입니다.
이 태스크는 비교적 단순합니다. 2D 시뮬레이션 환경 안에 T자 모양의 블록이 있고, 초록색으로 표시된 목표 위치가 있습니다. 로봇의 end-effector(손끝을 나타내는 파란 점)가 T 블록을 밀어서, 초록색 목표 영역과 정확히 맞추면 성공입니다.

파란 점 → 로봇의 end-effector (손끝 위치, 사람이 조이스틱으로 조작)
회색 T블록 → 로봇이 밀어야 할 오브젝트
초록 T영역 → 블록이 도달해야 할 목표 위치와 방향
처음 보면 매우 쉬워 보입니다. 그냥 블록을 목표 자리로 밀면 되는 것 아닌가? 하지만 실제로 해보면 그렇지 않습니다.
T 블록은 위치만 맞으면 되는 게 아닙니다. 방향도 같이 맞아야 합니다. 즉, 블록을 초록 영역 위치에 갖다 놓는 것도 어렵지만, 동시에 T의 방향까지 정확하게 맞춰야 합니다. 블록을 어느 방향에서 어떻게 밀어야 원하는 자세로 들어가는지를 예측해야 합니다.
그래서 pusht는 단순한 위치 이동이 아니라, 물체 조작(object manipulation)의 특성을 갖는 벤치마크로 자주 쓰입니다.
이 데이터셋에는 사람이 직접 텔레오퍼레이션으로 조작해 수집한 206개의 에피소드, 총 25,650개의 프레임이 들어 있습니다. 각 에피소드는 한 번의 성공적인 조작 시도에 해당합니다.
4. 데이터가 어떻게 생겼는가
데이터를 직접 열어보면, 각 프레임이 아래와 같은 구조로 저장되어 있습니다.
| observation.image | 배열 (96×96×3) | 카메라 영상 |
| observation.state | 배열 [x, y] | 로봇 end-effector의 현재 위치 |
| action | 배열 [dx, dy] | 이 순간 사람이 입력한 행동 |
| episode_index | 숫자 | 몇 번째 에피소드인지 |
| frame_index | 숫자 | 에피소드 안에서 몇 번째 프레임인지 |
| timestamp | 숫자 | 데이터 수집 시각 |
| next.done | True/False | 에피소드가 이 프레임에서 끝났는지 |
| next.reward | 숫자 | 이 행동 이후 받은 보상 |
| next.success | True/False | 이 행동 이후 성공했는지 |
타입을 보면 재미있습니다. 배열도 있고, 단순 숫자도 있고, True/False도 있습니다. 이게 바로 로봇 데이터의 특성입니다. 이미지처럼 고차원 정보와, 관절 각도처럼 저차원 수치 정보가 함께 존재합니다.
모방학습의 핵심은 바로 이 구조에 있습니다.
(observation.image + observation.state) → action
이 쌍을 수만 번 학습하면, 정책 네트워크는 "이런 장면에서는 이렇게 움직이면 되는구나"를 배우게 됩니다.
한 가지 주목할 점은 next.reward와 next.success도 데이터에 포함되어 있다는 것입니다. Behavior Cloning에서는 이 값을 학습에 직접 쓰지 않습니다. 그냥 사람의 행동만 따라 배웁니다. 하지만 나중에 Offline RL처럼 더 발전된 방식으로 학습할 때는 이 보상 정보도 활용할 수 있습니다. LeRobot이 이 값들을 함께 저장하는 이유도 여기에 있습니다.
5. ACT란 어떤 모델인가

이번에 학습하는 정책 모델은 ACT(Action Chunking Transformer) 입니다. 2023년 스탠포드에서 발표된 논문 "Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware"에서 처음 제안됐습니다. 지금도 로봇 모방학습에서 가장 널리 쓰이는 기본 모델 중 하나입니다.
왜 Transformer인가
로봇 행동 예측에 Transformer가 자주 쓰이는 이유가 있습니다.
로봇의 움직임은 순서가 있습니다. 물체를 집으려면 먼저 접근해야 하고, 접근한 뒤에 잡아야 하고, 잡은 뒤에 들어올려야 합니다. 이런 시간적 순서를 잘 모델링하는 게 Transformer의 강점입니다. 텍스트에서 앞 단어들을 보고 다음 단어를 예측하듯, 로봇이 지금까지의 상황을 보고 다음 행동을 예측하는 데 자연스럽게 맞습니다.
Action Chunking이란
일반적인 Behavior Cloning은 매 프레임마다 행동 하나씩 예측합니다.
프레임 t → action_t
프레임 t+1 → action_t+1
프레임 t+2 → action_t+2
이 방식의 문제는 오차 누적(compounding error) 입니다. 매 스텝마다 예측이 조금씩 틀리면, 그 오차가 쌓여서 로봇이 학습 데이터에 없는 상황으로 벗어나게 됩니다. 그리고 거기서부터는 무엇을 해야 할지 전혀 모르는 상태가 됩니다.
ACT는 이 문제를 행동 묶음(action chunk) 으로 해결합니다. 한 번에 여러 스텝의 행동을 예측합니다.
프레임 t → [action_t, action_t+1, ..., action_t+99]
pusht 설정에서는 chunk_size=100이 기본값으로, 한 번에 100 스텝의 행동을 묶어서 예측합니다. 이렇게 하면 매 스텝마다 새로운 결정을 내리지 않아도 되고, 앞으로 수행할 행동의 흐름을 한 번에 계획하기 때문에 움직임이 훨씬 부드러워집니다.
사람으로 비유하면, "한 걸음씩 어디 발을 놓을지 생각"하는 게 아니라 "이 구간은 이렇게 걸어가겠다"고 한 번에 계획하는 것입니다.
VAE가 왜 들어가는가
ACT의 또 다른 특징은 학습에 VAE(Variational Autoencoder)를 함께 사용한다는 점입니다.
왜 VAE가 필요할까요? 사람의 조작 방식은 항상 일정하지 않습니다. 같은 목표를 달성하더라도, 오른쪽에서 접근하기도 하고 왼쪽에서 접근하기도 합니다. 이런 행동의 다양성(multimodality) 이 문제가 됩니다. 단순히 모든 데이터의 평균을 학습하면, 어느 쪽도 아닌 어정쩡한 행동이 나옵니다.
VAE는 이 다양한 행동 방식을 잠재 공간(latent space)으로 압축해서 표현합니다. 학습할 때는 VAE를 통해 행동의 다양성을 잠재 변수로 학습하고, 추론할 때는 잠재 변수를 고정한 채 일관된 행동 시퀀스를 예측하게 합니다.
모델 구조 정리
카메라 영상
↓
ResNet18 (이미지 특징 추출, ImageNet 사전학습)
↓
[이미지 특징 + 관절 상태] → Transformer Encoder (4 layers)
↓ ↑
VAE (학습 시 행동 다양성 처리) KL divergence 손실
↓
Transformer Decoder (1 layer)
↓
행동 시퀀스 출력 (chunk_size = 100 스텝)
전체 파라미터 수는 약 5200만 개로, 로봇 학습 모델치고는 비교적 가볍습니다. 그래서 Colab 무료 GPU에서도 학습이 가능합니다.
학습 설정을 보면 이렇습니다.
vision_backbone: resnet18 (이미지 인코더)
dim_model: 512 (Transformer 차원)
n_heads: 8 (어텐션 헤드 수)
n_encoder_layers: 4
n_decoder_layers: 1
chunk_size: 100 (한 번에 예측하는 행동 개수)
n_action_steps: 100 (실제로 실행하는 행동 개수)
kl_weight: 10.0 (VAE KL 손실 가중치)
optimizer: AdamW, lr=1e-5
6. 어떻게 학습되는가
학습 명령어를 실행하면 내부적으로 아래 순서로 진행됩니다.
6-1. 데이터셋 로딩
HuggingFace Hub에서 pusht 데이터셋을 자동으로 다운로드합니다. 영상 파일(MP4)과 관절 데이터(Parquet)가 함께 로드됩니다. 총 25,650 프레임이며, 배치 크기 8로 나누면 약 3,200개의 미니배치가 됩니다.
6-2. 정책 초기화
ResNet18은 ImageNet 사전학습 가중치에서 시작합니다. 자연 이미지로 학습한 특징이 시뮬레이션 이미지에도 어느 정도 전이됩니다. Transformer와 VAE 부분은 랜덤 초기화입니다.
6-3. 손실 계산과 역전파
각 미니배치에서 다음을 계산합니다.
총 손실 = 행동 예측 손실 (MSE) + KL 손실 × kl_weight
행동 예측 손실은 모델이 예측한 행동 시퀀스와 실제 사람의 행동 시퀀스 사이의 MSE입니다. KL 손실은 VAE의 잠재 분포가 표준 정규 분포에서 너무 멀어지지 않도록 정규화하는 역할을 합니다.
6-4. 학습 로그로 보는 실제 진행
학습이 진행될수록 loss가 이렇게 변합니다.
step:200 loss: 6.397 grdn: 158.944 ← 초반, 거의 랜덤에 가까운 예측
step:400 loss: 2.706 grdn: 84.991 ← 빠르게 학습 중
step:600 loss: 2.284 grdn: 73.943
step:800 loss: 2.025 grdn: 68.122
step:1000 loss: 1.819 grdn: 63.636 ← 꾸준히 감소
grdn은 gradient norm으로, 학습이 안정적으로 진행되고 있는지를 나타냅니다. 초반에 크게 시작해서 점점 줄어드는 것이 정상입니다. loss도, gradient norm도 모두 안정적으로 감소하고 있어서 학습이 제대로 진행되고 있음을 알 수 있습니다.
1000 스텝은 개념 확인용으로 매우 짧은 학습입니다. 실제로 로봇이 pusht 태스크를 수행하려면 100,000 스텝 이상 학습해야 하며, A100 GPU 기준 약 1.5시간이 걸립니다. 100k 스텝 학습된 모델은 약 70~80%의 성공률을 보입니다.
6-5. 체크포인트 저장
지정한 save_freq마다 모델 가중치를 outputs/train/act_pusht/checkpoints/ 아래에 저장합니다. 나중에 이 체크포인트를 불러와서 시뮬레이터에서 평가하거나, 실제 로봇에 배포할 수 있습니다.
7. 데이터를 직접 눈으로 확인하기
학습한 것을 더 잘 이해하려면, 데이터가 실제로 어떻게 생겼는지 보는 게 중요합니다.
아래 코드로 데이터셋의 첫 프레임을 열어보면 이런 정보가 나옵니다.
state: tensor([222., 97.]) ← 파란 점(로봇)의 현재 위치 (x=222, y=97)
action: tensor([233., 71.]) ← 사람이 파란 점을 이동시킬 목표 위치
이미지를 보면, 파란 점은 화면 위쪽에 있고 회색 T블록은 아래쪽에 있습니다. action 값 [233, 71]은 파란 점이 다음 프레임에서 이동할 위치입니다. 즉, 사람이 "파란 점을 여기로 이동시켜라"고 입력한 것입니다.
연속으로 여러 프레임을 보면 파란 점이 T블록 쪽으로 이동하면서, 블록을 조금씩 목표 위치로 밀어가는 흐름이 보입니다. GIF로 만들면 이 흐름을 한눈에 볼 수 있습니다.
에피소드 하나가 보통 100~200 프레임으로 구성되어 있고, 한 프레임은 약 1/10초에 해당합니다. 즉, 10~20초짜리 시연 영상 하나가 에피소드 하나입니다.

8. Behavior Cloning의 한계는 무엇인가
Behavior Cloning은 단순하고 강력하지만, 한계도 분명합니다.
분포 이탈 문제 (Distribution Shift)
학습 데이터에 없는 상황이 나오면 오류가 쌓입니다. 사람이 항상 완벽하게 조작했다면 그 분포 안에 머무를 수 있지만, 조금이라도 벗어나면 모델은 무엇을 해야 할지 모릅니다. 그 오류가 다음 프레임에 영향을 주고, 또 그다음 프레임에 영향을 줘서, 결국 완전히 실패로 이어집니다.
ACT의 Action Chunking은 이 문제를 일부 완화합니다. 매 프레임마다 새로운 결정을 내리지 않고, 미리 계획한 묶음을 실행하기 때문에 오류가 덜 빠르게 누적됩니다.
데이터 수집 비용
좋은 모방학습 모델을 만들려면 좋은 시연 데이터가 많아야 합니다. 그런데 데이터 수집 자체가 시간과 노력이 많이 드는 일입니다. 사람이 로봇을 직접 조작해야 하기 때문입니다.
그래서 최근에는 모방학습으로 정책의 뼈대를 먼저 학습한 뒤, 강화학습으로 추가 개선하는 방식도 활발히 연구되고 있습니다. 모방학습이 강화학습의 좋은 시작점을 제공하는 것입니다.
9. 전체 흐름을 한 번에 정리하면
오늘 실습한 내용을 처음부터 끝까지 정리하면 이렇습니다.
[1단계] 데이터 수집
사람이 텔레오퍼레이션으로 로봇을 조작
→ 카메라 영상 + 관절 상태 + 행동이 함께 기록됨
→ 206 에피소드, 25,650 프레임
[2단계] 데이터 구조
각 프레임: (observation.image, observation.state) → action
[3단계] ACT 정책 학습
ResNet18으로 이미지 특징 추출
Transformer로 행동 시퀀스 예측 (chunk_size=100)
VAE로 행동 다양성 처리
손실 = MSE(행동 예측) + KL divergence
[4단계] 학습 결과
loss: 6.4 → 1.8 (1000 steps)
실제 동작을 위해서는 100k steps 필요
[5단계] 배포 (다음 실습)
체크포인트 로드 → 시뮬레이터 평가 → 실제 로봇 배포
10. 실습 코드 전체
아래 코드를 Colab에서 셀 순서대로 실행하면 됩니다.
사전 준비: 런타임 → 런타임 유형 변경 → GPU(T4) 선택
# ============================================================
# Step 1. LeRobot v0.4.4 설치 (Python 3.11 호환 버전)
# ============================================================
# 최신 버전(0.5.x)은 Python 3.12 이상을 요구하므로
# Colab 기본 환경(Python 3.11)에서는 v0.4.4를 사용합니다.
!git clone https://github.com/huggingface/lerobot.git
!cd lerobot && git checkout v0.4.4
!pip install -e /content/lerobot --quiet
# ============================================================
# Step 2. 추가 의존성 설치
# ============================================================
# 일반 pip install은 다른 Python에 설치될 수 있으므로
# sys.executable을 사용해 현재 커널에 직접 설치합니다.
import sys
!{sys.executable} -m pip install av fsspec imageio --quiet
print("설치 완료!")
# ============================================================
# Step 3. ACT 정책 학습
# ============================================================
# dataset.repo_id : HuggingFace Hub의 데이터셋
# policy.type : 사용할 정책 모델 (act, diffusion, smolvla 등)
# steps : 학습 스텝 수 (개념 확인용 1000, 실제는 100k)
# push_to_hub : HuggingFace Hub 업로드 여부
!cd lerobot && python src/lerobot/scripts/lerobot_train.py \
--dataset.repo_id=lerobot/pusht \
--policy.type=act \
--output_dir=outputs/train/act_pusht \
--policy.device=cuda \
--wandb.enable=False \
--policy.push_to_hub=false \
--steps=1000
# ============================================================
# Step 4. 데이터셋 시각화 — 단일 프레임
# ============================================================
import sys
sys.path.insert(0, '/content/lerobot/src')
from lerobot.datasets.lerobot_dataset import LeRobotDataset
import matplotlib.pyplot as plt
dataset = LeRobotDataset("lerobot/pusht")
print(f"전체 프레임 수: {len(dataset)}")
print(f"Episode 수: {dataset.num_episodes}")
sample = dataset[0]
print(f"\n데이터 keys: {list(sample.keys())}")
print(f"state (로봇 위치): {sample['observation.state']}")
print(f"action (다음 행동): {sample['action']}")
img = sample["observation.image"].permute(1, 2, 0).numpy()
plt.figure(figsize=(4, 4))
plt.imshow(img)
plt.title("pusht episode 0, frame 0\n파란점=로봇 / 회색T=블록 / 초록T=목표")
plt.axis("off")
plt.show()
# ============================================================
# Step 5. 연속 프레임 비교 (10프레임 간격)
# ============================================================
fig, axes = plt.subplots(1, 5, figsize=(15, 3))
for i, ax in enumerate(axes):
sample = dataset[i * 10]
img = sample["observation.image"].permute(1, 2, 0).numpy()
action = sample['action'].numpy().astype(int)
ax.imshow(img)
ax.set_title(f"frame {i*10}\naction: {action}")
ax.axis("off")
plt.suptitle("Episode 0 — 파란 점이 T블록을 목표 위치로 밀어가는 과정")
plt.tight_layout()
plt.show()
# ============================================================
# Step 6. Episode GIF 생성
# ============================================================
import imageio
import numpy as np
from IPython.display import Image
# episode 0 전체 프레임 수집
episode_frames = []
for i in range(len(dataset)):
sample = dataset[i]
if sample["episode_index"] != 0:
break
img = sample["observation.image"].permute(1, 2, 0).numpy()
img = (img * 255).astype(np.uint8) if img.max() <= 1.0 else img.astype(np.uint8)
episode_frames.append(img)
print(f"Episode 0 총 {len(episode_frames)} 프레임")
imageio.mimsave("pusht_episode0.gif", episode_frames, fps=15)
print("GIF 저장 완료!")
Image("pusht_episode0.gif")
마치며
HuggingFace Hub에서 공개 데이터셋을 가져왔고, 그 데이터가 어떤 구조인지 직접 확인했습니다. ACT라는 Transformer 기반 모방학습 모델이 어떻게 학습되는지, loss가 어떻게 변하는지 봤습니다. 그리고 사람이 로봇을 직접 조작한 영상을 GIF로 만들어서, 실제 데이터가 어떤 모습인지도 확인했습니다.
로봇 학습이 멀게 느껴질 수 있습니다. 비싼 하드웨어가 있어야 하고, 복잡한 환경을 구축해야 하는 것처럼 느껴질 수 있습니다. 하지만 LeRobot 덕분에, Colab 무료 GPU 하나로도 모방학습의 전체 흐름을 직접 실행해볼 수 있습니다.
모방학습은 강화학습보다 시작하기 쉽습니다. 보상 함수를 설계할 필요 없이, 사람이 보여준 것만 따라 배우면 됩니다. 하지만 그 단순함이 오히려 한계이기도 합니다. 사람이 보여준 것 이상을 하기 어렵습니다.
그래서 최근 연구의 방향은, 모방학습으로 기본을 익히고 강화학습으로 그 위를 더 쌓아 올리는 것입니다. 사람의 시연이 좋은 출발점을 제공하고, 강화학습이 그 위에서 더 나은 전략을 찾아가는 방식입니다.
'Study Archives > Robotics' 카테고리의 다른 글
| [자율 조작 로봇 이해 ⑦] 학습이 끝난 로봇을 평가하는 법 — 추론, 일반화 검증, 정량적 평가 (0) | 2026.05.28 |
|---|---|
| [자율 조작 로봇 이해 ⑤] 행동 복제(BC)와 역강화학습(IRL) (0) | 2026.05.25 |
| [자율 조작 로봇 이해 ④] 조작 데이터 수집과 전처리 (0) | 2026.05.22 |
| [자율 조작 로봇 이해 ③] 기구학과 동역학 입문 (0) | 2026.05.22 |
| [자율 조작 로봇 이해 ②] MuJoCo로 로봇 팔 띄우고 움직여보기 (0) | 2026.05.22 |