LeRobot 数据集 v3.0 迁移实操指南:3 条路径搞定中小到 TB 级数据
【免费下载链接】lerobot🤗 LeRobot: Making AI for Robotics more accessible with end-to-end learning项目地址: https://gitcode.com/GitHub_Trending/le/lerobot
假设你手上有一份 1.7TB 的 DROID 数据集,或者一批自己遥操作录下来的 v2.1 格式数据,而你的训练脚本已经只认 LeRobot 数据集 v3.0 格式了——加载一报错,就得先把格式迁过去。这篇指南把迁移拆成三条按数据量选择的路径:百 GB 以内的单机一键转换、外部格式(如 DROID)的单机导入、以及 TB 级数据的 SLURM 集群分片方案,每一步都给出能直接跑的命令和"做到什么算完成"的判断标准。
先判断:你的迁移走哪条路
三个迁移工具各管一段,先对号入座再动手。仓库里对应的是三个入口:
- 官方转换脚本:把手头的 v2.1 数据集原地升到 v3.0,元数据一并迁移。适合 <100GB、已经在本地或 Hub 上的数据。
- DROID 导入示例:把 TensorFlow Datasets/RLDS 这类外部格式转成 v3.0,单机跑适合百 GB 到 1TB 量级,或用它先拿一个分片做冒烟测试。
- SLURM 分片脚本:配合 Hugging Face 的 datatrove 做集群分片(分片就是把大任务切成 N 份并行处理,最后拼回来),>1TB 的 DROID 这类数据基本只能走这条路。
两个判断依据:du -sh看一眼体积,再问一句"我的数据本来就是 LeRobot 格式,还是得先导入"。
两种目录长什么样
v2.1 按 episode 存文件,一个 episode 一套文件:
dataset/ ├── data/chunk-000/episode_000000.parquet ├── data/chunk-000/episode_000001.parquet ├── videos/chunk-000/camera/episode_000000.mp4 └── meta/episodes.jsonlv3.0 改成了按文件块存,多个 episode 合并进同一块:
dataset/ ├── data/chunk-000/file_000.parquet # 多 episode 合并 ├── videos/camera/chunk-000/file_000.mp4 # 视频流合并 └── meta/episodes/chunk-000/file_000.parquet # 元数据也走 Parquet差别就一句话:v2.1 里几万个小文件各占各的,v3.0 里文件数量约为原来的十分之一,块大小(数据块 100MB、视频块 500MB)可配。落盘文件少了,读取时就省掉大量随机 IO,加载初始化也从"逐个打开"变成"按块打开"。
路径一:单机跑完中小数据集
确认环境
先把版本和相关依赖装好。转换脚本依赖jsonlines、pandas、pyarrow和datasets,DROID 导入额外需要 TensorFlow 全家桶:
pip install -U lerobot # 确保带 v3.0 支持 pip install tensorflow tensorflow_datasets # 仅导入 DROID 时需要另外留意磁盘:目标分区剩余空间要明显大于源数据体积,视频合并时会产生临时文件。做到什么算完成:python -c "from lerobot.datasets import CODEBASE_VERSION"不报 ImportError。
执行转换
已有 v2.1 数据集直接用官方脚本,它会重排 data/videos 目录、把 JSONL 元数据转成 Parquet、重算统计量,再推回 Hub 并打上 v3.0 标签:
python src/lerobot/scripts/convert_dataset_v21_to_v30.py \ --repo-id your_namespace/your_dataset数据只在本地不想上 Hub 时,加--root /path/to/local/dataset --push-to-hub false,脚本会原地转换(注意它会把原目录备份成*_old再换上新目录)。第三方格式以 DROID 为例,下载原始 RLDS 数据后跑:
python examples/port_datasets/port_droid.py \ --raw-dir /data/droid/1.0.1 \ --repo-id your_namespace/droid_v3想先验证流程,加--num-shards 2048 --shard-index 0只处理一个分片即可,不用重复跑整条链路。
抽查结果
转换结束后看一眼目录树和数据集元信息。做到什么算完成:meta/info.json里codebase_version是v3.0,且 data、videos、meta 三层都能找到file_000系列文件。
路径二:SLURM 集群处理 TB 级数据
SLURM 是 HPC 集群上最常用的作业调度系统,你提交任务,它排队分机器。没碰过也没关系,下面每条命令都是"复制→改路径→回车"。
确认资源
pip install datatrove # datatrove:Hugging Face 的分布式管道执行库 sinfo --format="%R %c %m" # 看可用分区(%R)、每节点 CPU 数、内存选一个 CPU 分区就够,迁移不需要 GPU。
提交分片任务
python examples/port_datasets/slurm_port_shards.py \ --raw-dir /data/droid/1.0.1 \ --repo-id your_namespace/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 固定 2048 个分片),每个 worker 领一个分片。--cpus-per-task 8:每个 worker 占 8 核,帧编码和压缩是并行吃核的,8 核是脚本默认值。--mem-per-cpu 1950M:每核 1.95GB 内存,单 worker 合计 8 × 1950M ≈ 16GB,要按这个值确认分区里单节点内存够。- 脚本还内置了 8 小时任务时限;
--slurm 0可切换成本地串行模式,用来在集群外先跑通流程。
做到什么算提交成功:命令返回后squeue -u $USER里能看到 droid_port 的排队/运行中任务。
盯进度
datatrove 会把日志和 SLURM 输出都落到--logs-dir下:
squeue -u $USER -p cpu_high # 找出还没跑完的分片编号 python examples/port_datasets/display_error_files.py \ --logs-dir /data/logs/porting --job-name droid_port # 看某个分片的原始输出 less /data/logs/porting/droid_port/slurm_jobs/12345_0.out每个分片处理完会写一个完成标记,display_error_files.py 就是拿全量编号减掉已完成编号,列出还差哪些。做到什么算收工:该脚本不再打印任何缺失编号。
聚合与上传
分片结果散落在 2048 个..._world_2048_rank_N仓库里,先用 聚合脚本 拼回一个数据集,再用 上传脚本 并行传上 Hub:
python examples/port_datasets/slurm_aggregate_shards.py \ --repo-id your_namespace/droid_v3 \ --logs-dir /data/logs/aggregation \ --job-name droid_agg \ --partition cpu_high python examples/port_datasets/slurm_upload.py \ --repo-id your_namespace/droid_v3 \ --workers 50 \ --logs-dir /data/logs/upload \ --job-name droid_upload \ --partition cpu_high上传阶段瓶颈在网络不在 CPU,所以 workers 用默认 50 就行。做到什么算完成:上传日志里每个分片的文件都走完,Hub 上仓库出现 v3.0 标签。
验收清单:怎么算迁移成功
跑一段代码把版本号、episode 数、数据块结构一次验完:
from lerobot.datasets import LeRobotDatasetMetadata meta = LeRobotDatasetMetadata("your_namespace/droid_v3") print(meta.info["codebase_version"], meta.total_episodes) print(meta.get_data_file_path(0)) # 应是 data/chunk-xxx/file_xxx.parquet print(meta.get_video_file_path(0, meta.video_keys[0]))对照检查:
codebase_version为v3.0- episode 总数与源数据一致(转换前记一下)
- 数据文件路径是
file_XXX.parquet而不是episode_XXXXXX.parquet - 真实加载测试:
next(iter(LeRobotDataset(...)))或取一个样本跑通一次前向,帧率和图像 shape 正常
顺手记下的几个坑
Q:加载时抛格式不兼容/旧版本错误?多半是本地缓存还停在旧版本。把该数据集在 Hugging Face 缓存里的目录删掉重新拉取即可;本地转换时如果目录里残留上次的*_old备份,也会让脚本在交换目录时踩到状态不一致,清干净再跑。
Q:视频合并阶段失败或卡住?优先查目标分区剩余空间是否够——合并视频要额外缓冲;另外确认 ffmpeg 在 worker 节点可用(集群不同节点环境可能不齐)。
Q:SLURM 任务超时?脚本默认时限是 8 小时,个别分片大或节点慢会吃满。对策是减小单分片数据量(用更细的分片切法)或加大--workers让单任务更轻,而不是硬调时限。
Q:迁移完想加速日常训练读取?三招:把HF_DATASETS_CACHE指到高速存储(SSD/NFS 快的分区);在LeRobotDatasetMetadata(...)里用precompute_statistics_for_new_episode=True让新增数据提前算好统计量,训练时省一段冷启动;转换和上传链路本身支持断点续跑——分片已完成的会被跳过,聚合前的分片仓库不用重算,中断后重跑对应命令即可接着来。
接下来会怎样
v3.0 已经把"episode 一文件"换成了"文件块",解决了小文件爆炸和元数据查询慢这两个最疼的点。后续版本方向上,增量更新、更细的统计与质量检查都在演进中,具体参数和行为以仓库内的 迁移教程 和 贡献指南 为准,版本升级前跑一遍上面的验收清单最稳妥。
【免费下载链接】lerobot🤗 LeRobot: Making AI for Robotics more accessible with end-to-end learning项目地址: https://gitcode.com/GitHub_Trending/le/lerobot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考