LeRobot v3.0 数据集迁移完整指南:单机脚本与 SLURM 集群双路径实操
【免费下载链接】lerobot🤗 LeRobot: Making AI for Robotics more accessible with end-to-end learning项目地址: https://gitcode.com/GitHub_Trending/le/lerobot
这篇文章带你把 LeRobot 数据集迁移到 v3.0 格式:既覆盖已有 v2.1 数据集的一键转换,也覆盖 DROID 这类 TB 级外部数据集的导入。适用于从几 GB 到 1.7TB 的数据规模。耗时预期:中小数据集单机几小时内完成;DROID 全量在单机上处理需 7 天以上、上传 Hub 需 3 天以上,改用 SLURM 集群分片并行后可压缩到几天内。
你需要做吗:3 条自检清单
满足任意一条,本文与你相关:
- 你的数据集是用旧版 LeRobot 录制或上传的,
meta/info.json里codebase_version为 2.1 - 你想把 DROID 等第三方格式的大数据集导入 LeRobot 格式
- 数据集 episode 数量巨大,"一个 episode 一个文件"的结构已经拖慢训练加载
如果数据已经是 v3.0 格式且规模不大,直接开始训练即可,无需迁移。
准备清单:环境与资源核查
- LeRobot 版本:升级到包含 v3.0 支持的最新版,本地没有仓库时先克隆:
git clone https://gitcode.com/GitHub_Trending/le/lerobot pip install -U lerobot- 磁盘空间:目标分区预留源数据 1.5~2 倍的剩余空间。以 DROID 为例,1.7TB 原始数据转换后约占 400GB,加上下载与缓存开销,建议预留 4TB 以上
- 源格式依赖:DROID 需要 TensorFlow 读取器:
pip install tensorflow tensorflow_datasets- 集群依赖(仅大规模路径需要):分布式执行框架 datatrove:
pip install datatrove- SLURM 权限:确认可用 CPU 分区、每节点核数与内存(迁移过程不需要 GPU)
- Hub 账号:需要推送结果时,先完成 Hugging Face 登录认证
分步实施
第 1 步:确认数据版本,判定迁移路线
目的:区分"v2.1 转 v3.0"与"外部格式导入"两条路线,避免用错脚本。
操作:查看数据集元信息中的版本号。
python -c "import json; print(json.load(open('meta/info.json'))['codebase_version'])"meta/info.json路径在你的本地数据集根目录下,即包含meta/、data/、videos/的那一层。
验证:输出2.1走第 2 步的转换脚本;若是外部原始格式(如 TensorFlow Records),直接进入"按数据规模分路"章节。
第 2 步:执行 v2.1 到 v3.0 转换
目的:把按 episode 存放的文件重组为按文件块存放,并同步迁移元数据。
操作:运行官方转换脚本。
python src/lerobot/scripts/convert_dataset_v21_to_v30.py \ --repo-id your_id/existing_dataset--repo-id:Hub 上的数据集标识,脚本据此拉取数据- 本地数据集可加
--root=/path/to/dataset原地转换,并加--push-to-hub=false只改本地
脚本会自动生成 per-episode 统计、把episodes.jsonl迁移为 Parquet、更新codebase_version,并在 Hub 上以v3.0打 tag。
验证:转换完成后检查文件结构:
ls data/chunk-000/ # 应出现 file-000.parquet,而非 episode_000000.parquet ls videos/*/chunk-000/ # 视频路径中 camera 位于 chunk 之前第 3 步:加载验证
目的:确认新版格式可被正常读取、episode 数量无丢失。
操作:用标准入口加载数据集。
python -c " from lerobot.datasets import get_dataset ds = get_dataset('your_id/existing_dataset') print(len(ds.meta.episodes)) "验证:打印的 episode 数与迁移前一致,且无异常抛出,说明转换链路完整。
按数据规模分路:导入外部大型数据集
以 DROID 1.0.1 为例:1.7TB(RLDS 格式)、预分为 2048 个分片、含 76000+ 条操作轨迹。两条路径的选择依据很简单——单机 7 天能跑完就走单机,否则上集群。
中小数据 · 单机路径
第 1 步:下载原始数据。以下命令从 Google Cloud Storage 下载 DROID,也可以只下 2GB 的 100-episode 样本做调试。
# 全量(1.7TB) gsutil -m cp -r gs://gresearch/robotics/droid/1.0.1 /data/droid_raw # 测试样本(2GB) gsutil -m cp -r gs://gresearch/robotics/droid_100 /data/droid_test验证:本地目录大小与源一致,分片文件数符合预期。
第 2 步:执行单机导入。该脚本把原始分片读入并写出 v3.0 结构的数据集。
python examples/port_datasets/port_droid.py \ --raw-dir /data/droid_raw \ --repo-id your_id/droid_v3 \ --push-to-hub--raw-dir:原始数据目录--repo-id:目标数据集标识--push-to-hub:转换完直接上传
开发调试时只处理单个分片,几分钟内可跑通全链路:
python examples/port_datasets/port_droid.py \ --raw-dir /data/droid_raw \ --repo-id your_id/droid_test \ --num-shards 2048 \ --shard-index 0--num-shards 2048:DROID 的总分片数--shard-index 0:只处理第 0 个分片
验证:本地生成的数据集能通过第 3 步的加载检查。
大规模 · SLURM 集群路径
第 1 步:检查集群资源。确认分区名、CPU 与内存规格。
sinfo --format="%R %c %m" sinfo -N -p cpu_high -h -o "%N cpus=%c mem=%m"验证:拿到一个可提交的 CPU 分区名,且单节点资源满足下述每任务规格。
第 2 步:提交分片并行任务。每个 SLURM 任务处理一个 DROID 分片,互不依赖。
python examples/port_datasets/slurm_port_shards.py \ --raw-dir /data/droid_raw \ --repo-id your_id/droid_v3 \ --logs-dir /data/logs/porting \ --job-name droid_port \ --partition cpu_high \ --workers 2048 \ --cpus-per-task 8 \ --mem-per-cpu 1950M--workers 2048:并行任务数,等于 DROID 分片数,即一分片一任务--cpus-per-task 8:每任务 8 核,用于视频帧编码并行--mem-per-cpu 1950M:每核约 2GB,单任务总内存约 16GB- 建议先用
--workers 100小规模试跑,确认集群配置无误再全量提交
验证:squeue -u $USER能看到提交的任务开始调度。
第 3 步:监控进度与失败任务。三个工具分别看整体状态、失败日志清单、单任务日志。
jobs_status /data/logs/porting # 整体进度 python examples/port_datasets/display_error_files.py \ --logs-dir /data/logs/porting --job-name droid_port # 列出失败 worker less /data/logs/porting/droid_port/slurm_jobs/<JOB_ID>_0.out # 单任务日志验证:失败 worker 清单为空,或全部失败任务已重跑成功。
第 4 步:聚合分片结果。所有分片数据集合并为一个完整 v3.0 数据集(单任务即可完成,无需多 worker)。
python examples/port_datasets/slurm_aggregate_shards.py \ --repo-id your_id/droid_v3 \ --logs-dir /data/logs/porting \ --job-name droid_agg \ --partition cpu_high验证:聚合任务的日志中无报错,且 Hub 上数据集的 episode 总数等于各分片之和。
第 5 步:并行上传。上传是网络密集型任务,worker 数明显少于转换阶段。
python examples/port_datasets/slurm_upload.py \ --repo-id your_id/droid_v3 \ --logs-dir /data/logs/porting \ --job-name droid_upload \ --partition cpu_high \ --workers 50 \ --cpus-per-task 4 \ --mem-per-cpu 1950M验证:Hub 页面文件齐全,且能按第 3 步的方式正常加载。
常见问题
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 加载时仍报 v2.1 旧结构错误 | 本地缓存了转换前的旧数据 | 删除本地缓存目录($HF_LEROBOT_HOME下对应数据集)后重新下载 |
| 部分 SLURM 任务失败、聚合报缺少分片 | 单任务资源不足或超时 | 用display_error_files.py定位失败 worker,检查日志后单独重跑对应分片 |
import datatrove报错 | 集群节点环境未装依赖 | 在集群 conda 环境中执行pip install datatrove |
| 视频编码阶段任务被 OOM 杀掉 | 帧缓存超出内存预算 | 调低--cpus-per-task并同比例降低--mem-per-cpu,保证总内存不降 |
| 上传阶段耗时长 | 网络带宽瓶颈而非计算瓶颈 | worker 保持 50 左右即可,增加 worker 收益有限 |
迁移验收清单
data/chunk-000/下是file-000.parquet这类文件块,不再存在episode_*.parquet- 视频路径为
videos/<camera>/chunk-000/file-000.mp4,camera 在 chunk 之前 meta/episodes/下为 Parquet 元数据,旧版episodes.jsonl已移除meta/info.json中codebase_version为 3.0- episode 总数与源数据一致,
get_dataset可正常读取任意帧 - per-episode 统计已生成且通过脚本内置的一致性检查
延伸
- 迁移教程原文:docs/source/porting_datasets_v3.mdx,含 DROID 完整 schema 说明
- v3.0 格式定义:docs/source/lerobot-dataset-v3.mdx,理解文件块切分与元数据布局
- v3.0 转换脚本源码:src/lerobot/scripts/convert_dataset_v21_to_v30.py,查看统计一致性检查的实现细节
【免费下载链接】lerobot🤗 LeRobot: Making AI for Robotics more accessible with end-to-end learning项目地址: https://gitcode.com/GitHub_Trending/le/lerobot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考