Strands Robots and LeRobot streaming data loop with Hugging Face Storage Buckets
TL;DR
Hugging Face released a workflow that connects Strands Robots, the LeRobot dataset stack, and Hugging Face Storage Buckets so you can record robot demonstrations, sync them efficiently, stream the data straight from the Hub for training, and redeploy the policy to the same robot in a single loop.
What the loop does
The loop consists of four stages that share a single Robot() instance:
- Record – a LeRobotDataset is written by the robot (simulation or hardware).
- Store – the dataset is synced to a Hugging Face Storage Bucket, which deduplicates uploads at the byte level.
- Train – the dataset is streamed directly from the bucket to GPUs using LeRobot’s
StreamingLeRobotDataset, eliminating the need for a full download. - Deploy – the trained checkpoint is loaded back into the same
Robot()(now inmode="real") and the robot records the next set of demonstrations, closing the loop.
Each stage is a single function call or a few lines of code, making the entire pipeline runnable on a laptop or a GPU cluster.
Prerequisites
Minimal (simulation) setup
- Python 3.12+ on Linux or macOS (Apple Silicon supported).
- A Strands‑compatible LLM provider (Amazon Bedrock, Anthropic, OpenAI, or local Ollama).
- Strands Robots with the
lerobotextra:
This installs LeRobot ≥ 0.6.1,uv pip install -U "strands-robots[sim-mujoco,lerobot]>=0.5.1"datasets,av, andtorchcodec.
Advanced (buckets, hardware, real policies)
- Hugging Face account with a write‑scoped token and the
hfCLI (pip install "huggingface-hub>=1.6.0,<2.0.0"). - Physical robot (e.g., SO‑101) with calibration files under
~/.cache/huggingface/lerobot/calibration/. - NVIDIA GPU for training (or a GPU cluster for large datasets).
lerobot[training]extra for the trainer (uv pip install "lerobot[training]").
Step 1 – Record a demonstration into a bucket
The robot records a LeRobotDataset in its native on‑disk format (Parquet for state/action, MP4 for video). After the episode finishes, the dataset is synced to a Storage Bucket:
from strands import Agent
from strands_robots import Robot, sync_dataset_to_bucket
sim = Robot("so100") # default mode="sim"
agent = Agent(tools=[sim])
# Prompt drives world creation, recording, and a mock policy run.
agent(
"Create a world with the so100 robot, add a red cube and a front camera, "
"start recording (repo_id='local/cube_pick', root='/tmp/cube_pick', fps=30, "
"overwrite=True, task='pick up the red cube'), run the mock policy for 60 steps, then stop recording."
)
# Sync the completed dataset to a bucket.
sync_dataset_to_bucket("/tmp/cube_pick", "my-org/robot-fave")
# → {"status": "success", "bucket_uri": "hf://buckets/my-org/robot-fave/cube_pick"}
The sync writes to hf://buckets/{bucket}/{run_id}; run_id defaults to the dataset folder name. The same call works for recordings made on a physical SO‑101 via the lerobot-record CLI.
Step 2 – Store with byte‑level deduplication
Storage Buckets are backed by Xet, which performs content‑defined chunking and deduplicates uploads at the byte level. LeRobot shards data into 100 MB Parquet files and 200 MB MP4 files, so a daily sync only uploads newly created shards and the partially‑filled shard that grew. Benchmarks cited by Hugging Face show a 4× reduction in transferred bytes compared with naïve overwrites.
Step 3 – Train by streaming from the Hub
Instead of copying the whole dataset to local disk, stream_dataset() reads directly from the bucket using byte‑range requests:
reader = sim.stream_dataset(
"my-org/robot-fave/cube_pick",
repo_type="bucket",
shuffle=False,
max_num_shards=1,
buffer_size=1,
)
print(reader.num_episodes, reader.num_frames, reader.fps)
for frame in reader:
# Observation tensors are decoded on the fly from remote MP4 shards.
img = frame["observation.images.front"]
state = frame["observation.state"]
action = frame["action"]
break
Only the small meta/ folder is cached locally; video frames are decoded on demand. For training, wrap the reader in a PyTorch DataLoader:
for batch in reader.dataloader(batch_size=64, num_workers=4):
loss, _ = policy(batch)
loss.backward()
LeRobot’s CLI also supports streaming directly:
lerobot-train \
--policy.type=act \
--dataset.repo_id=my-org/robot-fave/cube_pick \
--dataset.repo_type=bucket \
--dataset.streaming=true \
--num_workers=4
A single NVIDIA L4 instance completed 500 optimizer steps on a 120‑frame episode in 133 seconds, producing a checkpoint that can be loaded with create_policy().
Step 4 – Deploy the policy and return data to the loop
Deploy the newly trained checkpoint to a physical robot by switching the Robot mode to real:
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.")
The robot records the execution in the same LeRobot format, which can be synced back to the bucket for the next training iteration.
Sample application
A complete notebook is provided at examples/notebooks/05_streaming_data_loop.ipynb. It runs the full loop in simulation with a mock policy and requires no GPU or Hugging Face credentials. To try it locally:
git clone https://github.com/strands-labs/robots.git
cd robots
uv pip install -U "strands-robots[sim-mujoco,lerobot]>=0.5.1"
jupyter notebook examples/notebooks/05_streaming_data_loop.ipynb
Set BUCKET = "my-org/robot-fave" and optionally RUN_ID to control where the dataset lands.
Security considerations
- Prompt injection – agents execute LLM‑generated prompts; restrict tools and only feed trusted inputs.
- Training data trust boundary – separate credentials for data collection (write) and training (read); use unique
run_ids to trace episodes. - Bucket token scope – use a token limited to the target namespace and prefer private buckets for collection data.
- No revision history in buckets – an overwrite replaces the previous run; publish a reviewed version to a regular Hub dataset for auditability.
- Trusted model loading –
trust_remote_code=Trueis required for custom policies; load checkpoints only from organizations you trust and prefersafetensorswhen available.
Clean‑up
Remove bucket contents and temporary files to avoid storage charges:
hf buckets rm my-org/robot-fave/cube_pick/ --recursive --dry-run # preview
hf buckets rm my-org/robot-fave/cube_pick/ --recursive # delete
hf buckets delete my-org/robot-fave # delete whole bucket
rm -rf /tmp/cube_pick /tmp/cube_pick_ft /tmp/nb5_dataset /tmp/nb5_ft
Versioned repositories created with push_to_hub() remain untouched.
Next steps
- Explore the Strands Robots docs for the robot catalog, simulation backends, and multi‑robot mesh.
- Use different policy providers (GR00T, Cosmos 3, SmolVLA, etc.) by changing the
providerstring inTrainSpec. - Scale to fleets: give each robot a unique
run_idand let them write concurrently to the same bucket. - Combine with external storage such as Amazon S3; the LeRobot format is storage‑agnostic, and bucket streaming adds a Hub‑native path without extra wiring.
Resources
Strands Robots
- SDK &
Robot()factory: https://github.com/strands-labs/robots (Apache 2.0) - Documentation: https://strands-labs.github.io/robots/
- Recording guide: https://strands-labs.github.io/robots/recording/
- Notebook for this post: https://github.com/strands-labs/robots/blob/main/examples/notebooks/05_streaming_data_loop.ipynb
- Agents SDK: https://github.com/strands-agents/harness-sdk
LeRobot & Hub
- LeRobot repo: https://github.com/huggingface/lerobot
- Storage Buckets docs: https://huggingface.co/docs/hub/storage-buckets
- Xet deduplication blog: https://huggingface.co/blog/from-files-to-chunks
- Example pick‑and‑place dataset: https://huggingface.co/datasets/lerobot/svla_so101_pickplace
Policies
- SmolVLA: https://huggingface.co/lerobot/smolvla_base
- Pi0: https://huggingface.co/lerobot/pi0_base
- NVIDIA GR00T‑N1.7‑3B: https://huggingface.co/nvidia/GR00T-N1.7-3B
- NVIDIA Cosmos 3 Nano: https://huggingface.co/nvidia/Cosmos3-Nano
- MolmoAct2 for SO‑100/101: https://huggingface.co/allenai/MolmoAct2-SO100_101
Background
- First post in the series: https://huggingface.co/blog/amazon/strands-lerobot-hub-to-hardware
- Physical‑AI data loop overview: https://huggingface.co/spaces/imstevenpmwork/LeRobot_and_HF_Buckets#phase-1-collect-and-ingest
- Bucket throughput benchmarks: https://huggingface.co/spaces/h-m-t/hf-buckets-benchmark
Sources
Related
- Dispatch
- Dispatch
- Dispatch
- Dispatch