본문으로 건너뛰기

Strands Robots로 잇는 로봇 학습 데이터 루프

Strands Robots가 LeRobotDataset을 Bucket에 증분 동기화하고 GPU로 스트리밍해 로봇 정책 배포까지 잇습니다.

이 요약은 AI가 원문을 분석해 생성했습니다. 정확한 내용은 원문 기준으로 확인하세요.

TL;DR

Strands Robots는 Robot() 하나를 통해 로봇 시연 기록, Hugging Face Storage Bucket 동기화, LeRobotDataset 스트리밍 학습, 물리 하드웨어 배포를 하나의 데이터 루프로 연결합니다. Storage Bucket은 Xet의 content-defined chunking으로 바뀐 청크만 업로드하므로 500 MB 파일에서 1%가 바뀐 경우 5.5 MB만 전송하고, stream_dataset()은 MP4와 Parquet 샤드에서 필요한 데이터를 읽어 전체 데이터셋의 로컬 복사를 건너뜁니다. 단일 NVIDIA L4에서 ACT 500 optimizer steps를 120프레임 에피소드에 실행한 구성은 133초가 걸렸으며, 생성된 checkpoint는 mode="real"로 전환한 Robot()에 다시 연결할 수 있습니다. 다만 Bucket은 버전이 없으므로 고유한 run_id와 별도 자격 증명을 사용하고, 보존할 산출물은 versioned dataset repository에 저장해야 합니다.

섹션별 상세

01
Strands Robots는 AWS의 Apache 2.0 오픈 소스 SDK로 Robot() 추상화, 시뮬레이션, LeRobot 스택을 Strands agent의 AgentTools로 묶습니다. 이 글의 Robot("so100")은 시뮬레이션에서 시연을 기록하고 같은 객체로 Storage Bucket의 데이터를 읽으며, mode="real"로 바꾸면 물리 SO-101에 정책을 실행할 수 있습니다. 따라서 수집·학습·배포 단계가 서로 다른 포맷이나 로봇 API를 오가는 대신 하나의 Robot()과 LeRobotDataset 형식을 공유합니다.
python
from strands import Agent
from strands_robots import Robot

sim = Robot("so100")  # mode="sim" (default - safe, no hardware)
agent = Agent(tools=[sim])

# Record a demonstration and sync it to a bucket.
agent("Record a pick-the-cube demo and sync it to my-org/robot-fave.")

# Stream it back from the bucket to train, without downloading it first.
for batch in sim.stream_dataset("my-org/robot-fave/cube_pick", repo_type="bucket").dataloader(batch_size=64):
    ...

시뮬레이션 Robot()이 자연어 명령으로 시연을 기록하고 Storage Bucket에 동기화한 뒤 같은 데이터셋을 스트리밍 학습에 연결합니다.

Robot()을 중심으로 기록, 저장, 학습, 배포가 순환하는 네 단계 데이터 루프를 나타낸 도식입니다.
Diagram도식은 Robot("so100")이 공유 DatasetRecorder를 통해 LeRobotDataset을 기록하고, Storage Bucket에 저장한 뒤 stream_dataset()으로 GPU에 직접 공급하며, mode="real"로 정책을 하드웨어에 배포하는 흐름을 보여줍니다. 데이터는 전 과정에서 LeRobot 형식을 유지하고, 배포된 로봇의 새 시연이 다시 기록 단계로 돌아갑니다.
Strands Agent가 시뮬레이션 로봇과 물리 SO-101을 같은 Robot("so100") 인터페이스로 연결하고 정책 제공자와 Robot mesh로 이어지는 구조도입니다.
Diagram상단의 Strands Agent는 Robot("so100")을 호출하고, 이 객체는 MuJoCo 기반 시뮬레이션 로봇 또는 LeRobot driver layer를 사용하는 Physical SO-101로 분기됩니다. 두 경로는 공통 Policy providers를 거쳐 LAN, Cloud fleet, Device Connect로 구성된 Robot mesh에 연결되며, 시뮬레이션과 실제 하드웨어 사이에서 동일한 데이터 형식을 유지하는 구조를 나타냅니다.
02
기록된 LeRobotDataset는 hf://buckets/{bucket}/{run_id} 경로에 Storage Bucket으로 동기화됩니다. sync_dataset_to_bucket(root, bucket, run_id=...)은 기록 수명주기와 분리된 동기화 방식이고, DatasetRecorder.sync_to_bucket(...)과 stop_recording(bucket=...)은 직접 기록하거나 중단하는 시점에 동기화하는 경로입니다. Bucket은 하루 동안 데이터를 쌓는 작업 계층이며, 되돌릴 수 있는 버전 산출물은 push_to_hub()로 versioned dataset repository에 따로 게시해야 합니다.
첫 동기화와 다음 동기화에서 변경된 청크만 Hugging Face Bucket으로 전송하는 과정을 비교한 도식입니다.
Diagram첫 번째 동기화는 500 MB의 모든 청크를 보내지만, 다음 동기화는 새 청크만 보내며 예시에서는 5.5 MB가 전송됩니다. 이는 Xet의 content-defined chunking이 변경되지 않은 데이터를 건너뛰어 반복적인 로봇 데이터 업로드 비용을 줄이는 원리를 시각화합니다.
03
Storage Buckets는 Xet의 content-defined chunking으로 변경된 바이트가 포함된 청크만 전송합니다. 500 MB 파일에서 변경량이 1%면 5.5 MB, 5%면 27.5 MB, 10%면 55 MB가 이동했으며, Strands Robots가 쓰는 LeRobot의 100 MB Parquet 및 200 MB MP4 샤드 구조는 새로 채워진 후행 샤드와 커진 부분 샤드 중심의 동기화를 가능하게 합니다. 이 방식은 매일 커지는 로봇 기록 전체를 다시 업로드하지 않고 증분 데이터만 저장하게 만듭니다.
python
reader = sim.stream_dataset("my-org/robot-fave/cube_pick", repo_type="bucket", shuffle=False, max_num_shards=1, buffer_size=1, # one episode, in capture order
)
print(reader.num_episodes, reader.num_frames, reader.fps)
for frame in reader:
    frame["observation.images.front"] # (3, H, W) tensor, decoded on the fly from the MP4 shard
    frame["observation.state"] # joint vector, from the Parquet shard
    frame["action"]
    break

Storage Bucket의 LeRobot 샤드에서 카메라 영상과 로봇 상태·행동을 한 프레임씩 원격으로 읽고 영상은 순회 중 디코딩합니다.

python
# policy here is a LeRobot policy you constructed, such as ACTPolicy.
for batch in reader.dataloader(batch_size=64, num_workers=4):
    loss, _ = policy(batch) # lerobot ACTPolicy.forward returns (loss, loss_dict)
    loss.backward()

스트리밍 reader를 PyTorch DataLoader에 넘겨 4개 worker로 배치를 만들고 LeRobot 정책의 손실을 계산해 역전파합니다.

python
import os
os.environ["STRANDS_TRUST_REMOTE_CODE"] = "1" # create_policy loads with trust_remote_code=True
from strands_robots import create_policy
from strands_robots.training import TrainSpec, create_trainer
trainer = create_trainer("lerobot_local", device="cuda")
spec = TrainSpec(dataset_root="/tmp/cube_pick", output_dir="/tmp/cube_pick_ft", base_model="", steps=500, extra={"policy_type": "act"})
result = trainer.train(spec)
# train ACT on the streamed dataset
policy = create_policy(result.checkpoint_dir) # load the checkpoint straight back

lerobot_local Trainer가 학습 설정을 실행하고 생성된 checkpoint를 같은 create_policy() 진입점으로 다시 불러옵니다.

전체 데이터셋 다운로드 방식과 Bucket에서 GPU로 직접 스트리밍하는 방식을 비교한 도식입니다.
Diagram다운로드 경로에서는 데이터셋을 로컬 디스크에 모두 복사하는 동안 GPU가 대기하지만, 스트리밍 경로에서는 stream_dataset()이 Bucket에서 필요한 데이터를 읽어 GPU가 즉시 학습을 시작합니다. 스트리밍 방식의 로컬 디스크 사용량은 도식에서 100 KB로 표시되며, 글의 meta/ 폴더만 로컬에 남는다는 설명과 연결됩니다.
04
stream_dataset()은 전체 데이터셋을 로컬 디스크에 복사하지 않고 Storage Bucket의 Parquet·MP4 샤드에서 필요한 바이트 범위를 읽습니다. 카메라 프레임은 MP4에서 순회 중 디코딩하고 상태와 행동은 Parquet에서 가져오며, 로컬에는 schema·statistics·episode index가 담긴 작은 meta/ 폴더만 남습니다. StreamingLeRobotDataset은 DataLoader와 연결되고 4개 worker를 사용해 배치를 만들 수 있어 GPU가 수백 GB 다운로드를 기다리지 않고 첫 배치부터 학습을 시작합니다.
python
robot = Robot("so100", mode="real", port="/dev/ttyACM0", cameras={"front": {"type": "opencv", "index_or_path": "/dev/video0", "fps": 30}})
agent = Agent(tools=[robot])
agent("Pick up the red cube.")

mode="real"과 실제 장치 포트를 지정해 학습한 정책을 SO-100 계열 물리 로봇에 연결하고 다음 시연을 수집합니다.

05
학습은 stream_dataset()과 LeRobot Trainer 두 경로로 수행할 수 있으며, Storage Bucket을 사용할 때는 repo_type="bucket"과 streaming=true를 함께 지정해야 합니다. 단일 NVIDIA L4에서 51.6M 파라미터 ACT를 유효 배치 크기 8, optimizer 500회로 120프레임 에피소드에 학습한 구성은 133초가 걸렸지만, 글은 이를 일반 벤치마크가 아닌 한 가지 측정 조건으로 한정합니다. 학습한 checkpoint는 create_policy()로 다시 로드한 뒤 Robot("so100", mode="real")에 연결하고, 물리 로봇이 수집한 다음 시연을 같은 Bucket으로 되돌려 루프를 이어갑니다.
06
이 데이터 루프는 효율성뿐 아니라 에이전트와 로봇의 안전 경계도 함께 다룹니다. 수집 Bucket에 쓰는 자격 증명과 학습 작업이 읽는 자격 증명을 분리하고, 각 수집 실행에 고유한 run_id를 부여하며, 검토가 필요한 데이터는 revision이 보존되는 dataset repository에 저장해야 합니다. 또한 untrusted data의 prompt injection, trust_remote_code=True로 로드되는 임의 코드, 반복 run_id의 덮어쓰기와 같이 물리 로봇과 공유 저장소에 직접 영향을 주는 위험을 제한해야 합니다.

용어 해설

콘텐츠 정의 청킹(Content-Defined Chunking)
파일 내용을 기준으로 청크 경계를 정하는 저장 방식입니다. 데이터가 삽입되거나 일부 바뀌어도 전체 파일의 청크 경계가 연쇄적으로 밀리지 않아 변경된 바이트가 포함된 청크만 다시 업로드합니다. 이 글에서는 Xet 기반 Storage Buckets의 중복 제거와 증분 동기화를 가능하게 하는 핵심 메커니즘으로 쓰입니다.
LeRobotDataset
로봇 관측값, 상태, 행동과 에피소드 메타데이터를 Parquet 및 MP4 샤드로 저장하는 데이터 형식입니다. 시뮬레이션과 실제 로봇에서 만든 데이터가 같은 디스크 구조를 유지하므로 별도 변환 없이 학습과 재생에 사용할 수 있습니다. 이 글의 전체 데이터 루프가 의존하는 공통 형식입니다.
StreamingLeRobotDataset
LeRobot 샤드에서 필요한 데이터만 원격 바이트 범위 읽기로 가져오는 스트리밍 데이터셋입니다. 카메라 프레임은 MP4에서 순회 중 디코딩하고 상태와 행동은 Parquet에서 읽어 전체 데이터셋을 로컬 디스크에 복사하지 않습니다. PyTorch iterable 및 DataLoader와 연결해 GPU 학습에 사용할 수 있습니다.
Storage Bucket
Hugging Face Hub의 hf:// 네임스페이스에서 데이터 작업 계층으로 사용하는 변경 가능하고 버전이 없는 저장소입니다. 하루 동안 수집한 로봇 데이터를 기록 시점부터 다음 학습 시점까지 보관하며 hf CLI로 동기화합니다. 버전 관리가 필요한 공개 산출물은 별도의 versioned dataset repository에 저장해야 합니다.
Robot mesh
여러 로봇을 하나의 에이전트 흐름에 연결하는 Strands Robots의 구성 방식입니다. 시뮬레이션 로봇과 물리 로봇이 같은 Robot() 인터페이스와 데이터 형식을 사용하고, LAN·클라우드·디바이스 연결 계층을 통해 정책 제공자와 이어집니다. 여러 로봇의 수집 작업을 같은 버킷으로 병렬화할 때 활용됩니다.

기술

  • Strands Robots
  • Strands Agents
  • LeRobot
  • Hugging Face Storage Buckets
  • Xet
  • PyTorch
  • MuJoCo
  • torchcodec
  • Hugging Face Hub
  • Amazon S3
  • ACTPolicy
  • GR00T
  • Cosmos 3

활용 사례

  • 시뮬레이션에서 pick-and-place 로봇 시연 수집
  • Storage Bucket에 로봇 에피소드 증분 동기화
  • 원격 LeRobotDataset을 GPU로 스트리밍 학습
  • 학습한 정책을 SO-101 물리 로봇에 배포
  • 여러 로봇이 하나의 Bucket에 데이터를 병렬 수집
AI 분석 전체 내용 보기

AI 요약 · 북마크 · 개인 피드 설정 — 무료

출처 · 인용 안내

원문 발행 2026. 08. 14.수집 2026. 08. 14.출처 타입 RSS

인용 시 "요약 출처: AI Trends (aitrends.kr)"를 표기하고, 사실 확인은 원문 보기 기준으로 진행해 주세요. 자세한 기준은 운영 정책을 참고해 주세요.