Strands 机器人与 LeRobot 流式数据循环结合 Hugging Face 存储桶
概要
Hugging Face 发布了一个工作流,将 Strands 机器人、LeRobot 数据集栈和 Hugging Face 存储桶连接起来,使您能够记录机器人演示,高效同步数据,直接从 Hub 流式传输数据用于训练,并将训练好的策略重新部署到同一台机器人上,形成一个完整的闭环。
该循环的工作原理
该循环包含四个阶段,共用一个 Robot() 实例:
- 记录 – 机器人(仿真或硬件)将数据写入 LeRobotDataset。
- 存储 – 数据集同步到 Hugging Face 存储桶,该存储桶在字节级别进行去重。
- 训练 – 数据集通过 LeRobot 的
StreamingLeRobotDataset直接从存储桶流式传输到 GPU,无需完整下载。 - 部署 – 训练好的检查点被加载回同一个
Robot()(现在处于mode="real"状态),机器人记录下一组演示,从而完成闭环。
每个阶段仅需一次函数调用或几行代码,整个流程可在笔记本电脑或 GPU 集群上运行。
先决条件
最小化(仿真)设置
- Linux 或 macOS 上的 Python 3.12+(支持 Apple Silicon)。
- 一个与 Strands 兼容的 LLM 提供商(Amazon Bedrock、Anthropic、OpenAI 或本地 Ollama)。
- 安装了
lerobot扩展的 Strands 机器人:
此命令将安装 LeRobot ≥ 0.6.1、uv pip install -U "strands-robots[sim-mujoco,lerobot]>=0.5.1"datasets、av和torchcodec。
高级(存储桶、硬件、真实策略)
- Hugging Face 账户,带有写入权限的令牌,以及
hfCLI(pip install "huggingface-hub>=1.6.0,<2.0.0")。 - 实体机器人(例如 SO-101),其校准文件位于
~/.cache/huggingface/lerobot/calibration/下。 - 用于训练的 NVIDIA GPU(或用于大规模数据集的 GPU 集群)。
- 用于训练器的
lerobot[training]扩展(uv pip install "lerobot[training]")。
第一步 – 将演示记录到存储桶
机器人以原生磁盘格式(状态/动作为 Parquet,视频为 MP4)记录 LeRobotDataset。在 episode 完成后,数据集将同步到存储桶:
from strands import Agent
from strands_robots import Robot, sync_dataset_to_bucket
sim = Robot("so100") # 默认 mode="sim"
agent = Agent(tools=[sim])
# 提示驱动世界创建、记录和模拟策略运行。
agent(
"创建一个包含 so100 机器人的世界,添加一个红色方块和一个前向摄像头,
开始记录(repo_id='local/cube_pick', root='/tmp/cube_pick', fps=30,
overwrite=True, task='拿起红色方块'),运行模拟策略 60 步,然后停止记录。"
)
# 将完成的数据集同步到存储桶。
sync_dataset_to_bucket("/tmp/cube_pick", "my-org/robot-fave")
# → {"status": "success", "bucket_uri": "hf://buckets/my-org/robot-fave/cube_pick"}
同步操作写入 hf://buckets/{bucket}/{run_id};run_id 默认为数据集文件夹名称。同一调用也适用于通过 lerobot-record CLI 在物理 SO-101 上录制的数据。
第二步 – 以字节级别去重的方式存储
存储桶由 Xet 支持,执行内容定义的分块并以字节级别去重上传。LeRobot 将数据分片为 100 MB 的 Parquet 文件和 200 MB 的 MP4 文件,因此每日同步仅上传新创建的分片以及部分填充的分片。Hugging Face 提供的基准测试显示,与简单的覆盖写入相比,传输字节数减少了 4 倍。
第三步 – 从 Hub 流式传输以进行训练
无需将整个数据集复制到本地磁盘,stream_dataset() 使用字节范围请求直接从存储桶读取:
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:
# 观测张量从远程 MP4 分片实时解码。
img = frame["observation.images.front"]
state = frame["observation.state"]
action = frame["action"]
break
仅小的 meta/ 文件夹在本地缓存;视频帧按需解码。用于训练时,将 reader 包装在 PyTorch DataLoader 中:
for batch in reader.dataloader(batch_size=64, num_workers=4):
loss, _ = policy(batch)
loss.backward()
LeRobot 的 CLI 也支持直接流式传输:
lerobot-train \
--policy.type=act \
--dataset.repo_id=my-org/robot-fave/cube_pick \
--dataset.repo_type=bucket \
--dataset.streaming=true \
--num_workers=4
单个 NVIDIA L4 实例在 120 帧的 episode 上完成了 500 次优化器步骤,耗时 133 秒,生成的检查点可使用 create_policy() 加载。
第四步 – 部署策略并返回数据到循环
通过将 Robot 模式切换为 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("拿起红色方块。")
机器人以相同的 LeRobot 格式记录执行过程,该数据可再次同步回存储桶,用于下一次训练迭代。
示例应用
在 examples/notebooks/05_streaming_data_loop.ipynb 提供了一个完整笔记本。它在仿真中运行完整循环,使用模拟策略,无需 GPU 或 Hugging Face 凭据。要本地尝试:
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
将 BUCKET = "my-org/robot-fave" 设置为控制数据落地位置,可选地设置 RUN_ID。
安全注意事项
- 提示注入 – 代理执行 LLM 生成的提示;限制工具并仅输入可信内容。
- 训练数据信任边界 – 数据收集(写入)和训练(读取)使用不同的凭据;使用唯一的
run_id追踪 episode。 - 存储桶令牌范围 – 使用仅限目标命名空间的令牌,并优先使用私有存储桶存放收集数据。
- 存储桶中无版本历史 – 覆盖操作会替换之前运行;将审核后的版本发布到常规 Hub 数据集以实现可审计性。
- 可信模型加载 – 自定义策略需要
trust_remote_code=True;仅从您信任的组织加载检查点,并在可用时优先使用safetensors。
清理
删除存储桶内容和临时文件以避免存储费用:
hf buckets rm my-org/robot-fave/cube_pick/ --recursive --dry-run # 预览
hf buckets rm my-org/robot-fave/cube_pick/ --recursive # 删除
hf buckets delete my-org/robot-fave # 删除整个存储桶
rm -rf /tmp/cube_pick /tmp/cube_pick_ft /tmp/nb5_dataset /tmp/nb5_ft
使用 push_to_hub() 创建的版本化仓库不受影响。
下一步
- 探索 Strands 机器人 文档,了解机器人目录、仿真后端和多机器人网格。
- 通过更改
TrainSpec中的provider字符串,使用不同的策略提供者(GR00T、Cosmos 3、SmolVLA 等)。 - 扩展到机器人车队:为每台机器人分配唯一的
run_id,并让它们并发写入同一存储桶。 - 与外部存储(如 Amazon S3)结合使用;LeRobot 格式与存储无关,而存储桶流式传输提供了无需额外布线的 Hub 原生路径。
资源
Strands 机器人
- SDK 与
Robot()工厂:https://github.com/strands-labs/robots (Apache 2.0) - 文档:https://strands-labs.github.io/robots/
- 录制指南:https://strands-labs.github.io/robots/recording/
- 本文的笔记本:https://github.com/strands-labs/robots/blob/main/examples/notebooks/05_streaming_data_loop.ipynb
- 代理 SDK:https://github.com/strands-agents/harness-sdk
LeRobot 与 Hub
- LeRobot 仓库:https://github.com/huggingface/lerobot
- 存储桶文档:https://huggingface.co/docs/hub/storage-buckets
- Xet 去重博客:https://huggingface.co/blog/from-files-to-chunks
- 示例抓取与放置数据集:https://huggingface.co/datasets/lerobot/svla_so101_pickplace
策略
- 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 用于 SO-100/101:https://huggingface.co/allenai/MolmoAct2-SO100_101
背景
Sources
相关
- Dispatch
- Dispatch
- Dispatch
- Dispatch