
How to publish a LeRobot dataset properly: what is really in the repo, the dataset card fields that decide reproducibility, licence choice, and the version tag that moves under you.
What you need to know
- •A published dataset is a Hugging Face repo with three things: the data, a meta/ folder the loader trusts, and a README.md whose YAML block carries the licence and tags.
- •lerobot-record uploads for you. push_to_hub() defaults to license="apache-2.0" and tags the commit with the codebase version, which in lerobot 0.6.2 is the string v3.0.
- •That version tag is not cosmetic. LeRobotDataset() resolves revision to CODEBASE_VERSION by default, so it fetches the v3.0 tag rather than main. Push again and the tag moves.
- •The auto-generated card is a stub: Homepage, Paper and Citation all read [More Information Needed]. Everything that makes a run reproducible is the part you write yourself.
- •Licence is a choice with consequences. apache-2.0 is the lerobot default, cc-by-4.0 is the common data choice, cc-by-nc-4.0 quietly excludes most companies from fine-tuning on your data.
- •A licence is not consent. If a face, a colleague or a stranger's living room is in frame, no SPDX identifier fixes that. Reframe or do not publish.
- •GR00T will not read a v3.0 dataset. It wants LeRobot v2 plus a meta/modality.json that the standard format does not contain.
Published is not the same as uploaded
Uploading a LeRobot dataset takes one flag. Publishing one takes an afternoon. The difference shows up three months later, when somebody else, or you, tries to reproduce the run and cannot answer basic questions: which arm, which cameras, which firmware, how many episodes were thrown away and why, and whether the number in the card counts the deleted ones.
Most public robot datasets are uploads. They have data, they load, and the card says This dataset was created using LeRobot and nothing else. That is enough to train on and not enough to trust. This article is about the gap: what the repo actually contains, what the card has to say for a stranger to repeat your run, and which licence choice you are making without noticing. It assumes you already have episodes on disk; if you do not, start with recording your first dataset and with what makes VLA training data good in the first place.
Checked on 23 August 2026 against lerobot at main, where pyproject.toml reads version = "0.6.2" and lerobot_dataset.py imports CODEBASE_VERSION, currently the string "v3.0", from the dataset metadata module. The newest PyPI release that day is 0.6.1, so main is a version ahead of pip install lerobot. Hub docs were read the same day. Check flag names against --help before pasting anything below.
What is actually inside the repo
A LeRobot dataset repo is not a folder of videos. It is a schema plus shards plus a metadata layer that reconstructs episode boundaries, as the dataset documentation describes. In v3.0 the episode is no longer a file; it is a range of rows and a byte offset recorded in metadata, which is why deleting a file by hand corrupts the dataset in a way that is hard to see.
| Path | What it holds | Notes |
|---|---|---|
| meta/info.json | Schema: features, dtypes, shapes, fps, robot_type, total_episodes, total_frames, chunks_size, and the path templates for data and video shards | The one file a reader should open first |
| meta/stats.json | Global mean, std, min and max per feature, used for normalisation | Exposed in Python as dataset.meta.stats |
| meta/tasks.parquet | Natural-language task strings mapped to integer ids | v3.0 default. v2.1 used meta/tasks.jsonl, still referenced in lerobot as LEGACY_TASKS_PATH |
| meta/episodes/ | Per-episode records: length, task, byte and frame offsets, stored as chunked Parquet | v2.1 kept this as meta/episodes.jsonl plus meta/episodes_stats.jsonl |
| data/chunk-XXX/file-YYY.parquet | Frame-by-frame tabular data: state, action, timestamps, indices | Many episodes per file |
| videos/{video_key}/chunk-XXX/file-YYY.mp4 | Camera streams, one directory per camera key | Many episodes per file |
| README.md | The dataset card: YAML metadata block plus prose | The only file most humans will read |
The defaults in src/lerobot/datasets/utils.py are worth knowing because they determine how your repo looks to a downloader: DEFAULT_CHUNK_SIZE = 1000 files per chunk directory, DEFAULT_DATA_FILE_SIZE_IN_MB = 100 and DEFAULT_VIDEO_FILE_SIZE_IN_MB = 200. Those are the values used when a dataset is created. They are not a contract: every dataset writes its own numbers into info.json, so a repo built under an older default keeps that older default forever.
lerobot/svla_so101_pickplace, one of the reference SO-arm datasets, has a meta/info.json reading total_episodes: 50, total_frames: 11939, fps: 30 and chunks_size: 1000. Its data_files_size_in_mb is 100, matching the constant, but its video_files_size_in_mb is 500 against a constant of 200. Same format version, different shard sizing: read shard sizes from info.json, never from the source.
my-user/so100-cube-to-bowl/
README.md <- the card, YAML + prose
meta/
info.json <- codebase_version, fps, robot_type, features
stats.json <- normalisation statistics
tasks.parquet <- task strings -> ids (v2.1: tasks.jsonl)
episodes/chunk-000/file-000.parquet
data/
chunk-000/file-000.parquet <- many episodes per file in v3.0
videos/
observation.images.front/chunk-000/file-000.mp4
observation.images.wrist/chunk-000/file-000.mp4Because episode boundaries live in meta/episodes/ and not in filenames, deleting an mp4 or a parquet through the Hub web UI leaves a dataset that still loads and quietly returns garbage for the affected indices. Use lerobot-edit-dataset --operation.type=delete_episodes --operation.episode_indices "[3, 17]", which writes a new dataset with the metadata rebuilt, and push that.
Getting it onto the Hub
The path most people take is that lerobot-record uploads at the end of the session. That is fine, and it is also why so many half-finished datasets exist: the upload happens before you have looked at the data. The sequence below separates recording from publishing on purpose.
- 1Authenticate with a write token
Create the token at Settings, Access Tokens on huggingface.co with write access. Never paste it into a notebook you will commit.
bashhf auth login --token ${HUGGINGFACE_TOKEN} --add-to-git-credential HF_USER=$(NO_COLOR=1 hf auth whoami | awk -F': *' 'NR==1 {print $2}') echo $HF_USER - 2Record without pushing
Add
--dataset.push_to_hub=Falseso nothing leaves the machine yet. Defaults you are accepting silently:--dataset.num_episodes=50,--dataset.episode_time_s=60,--dataset.reset_time_s=60. The dataset lands in~/.cache/huggingface/lerobot/{repo-id}.bashlerobot-record \ --robot.type=so100_follower \ --robot.port=/dev/ttyACM0 \ --robot.id=my_follower_arm \ --robot.cameras="{ front: {type: opencv, index_or_path: 1, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30} }" \ --teleop.type=so100_leader \ --teleop.port=/dev/ttyACM1 \ --teleop.id=my_leader_arm \ --dataset.repo_id=${HF_USER}/so100-cube-to-bowl \ --dataset.num_episodes=50 \ --dataset.single_task="Pick the yellow cube and put it in the bowl" \ --dataset.push_to_hub=False \ --display_data=true - 3Look at every episode before you publish
Load it locally and read the metadata back. If total_episodes does not match what you think you recorded, stop here.
bashlerobot-edit-dataset \ --repo_id=${HF_USER}/so100-cube-to-bowl \ --operation.type=info \ --operation.show_features=true - 4Drop the bad episodes, then check what happened to the statistics
delete_episodeswrites a new dataset: it re-indexes episodes, rebuildsmeta/episodes/, and re-aggregatesmeta/stats.jsonfrom the per-episode statistics of the episodes it kept. You do not need to recompute stats to get a consistent dataset.recompute_statsis the stronger, optional operation that rebuildsstats.jsonfrom scratch by iterating every frame - with the default output trap described below.bashlerobot-edit-dataset \ --repo_id=${HF_USER}/so100-cube-to-bowl \ --operation.type=delete_episodes \ --operation.episode_indices "[7, 23, 41]" \ --new_repo_id=${HF_USER}/so100-cube-to-bowl-clean # optional, and note the two flags: without them this writes a THIRD dataset lerobot-edit-dataset \ --repo_id=${HF_USER}/so100-cube-to-bowl-clean \ --new_repo_id=${HF_USER}/so100-cube-to-bowl-clean \ --operation.type=recompute_stats \ --operation.overwrite true - 5Push with the card fields filled in
This is the step that turns an upload into a publication.
push_to_hub()forwards unknown keyword arguments into the card template, sodataset_description,url,paperandcitation_bibtexall land in the README instead of staying as[More Information Needed].pythonfrom lerobot.datasets import LeRobotDataset ds = LeRobotDataset("my-user/so100-cube-to-bowl-clean") ds.push_to_hub( tags=["so100", "pick-and-place", "teleoperation"], license="cc-by-4.0", # default is "apache-2.0" private=False, push_videos=True, # everything below is forwarded into card_template.md dataset_description=( "47 teleoperated episodes of an SO-100 follower arm picking a 25 mm " "yellow cube from a 30x40 cm mat and dropping it into a white bowl. " "Two cameras at 640x480/30 fps: a fixed front view and a wrist view." ), url="https://github.com/<your-name>/so100-cube-to-bowl", citation_bibtex=( "@misc{so100cube2026,\n" " title = {SO-100 cube-to-bowl teleoperation dataset},\n" " author = {Your Name},\n" " year = {2026},\n" " url = {https://huggingface.co/datasets/<your-name>/so100-cube-to-bowl-clean}\n" "}" ), )
With only --repo_id and --operation.type=recompute_stats, lerobot-edit-dataset writes to a new dataset called {repo_id}_recomputed_stats and leaves the original untouched. People run it, see no error, push the original, and ship stale statistics. For an in-place update pass --new_repo_id equal to --repo_id and --operation.overwrite true. reencode_videos has the same habit, landing in {repo_id}_reencoded.
push_to_hub() ends with delete_tag then create_tag for CODEBASE_VERSION, currently the literal string v3.0. And LeRobotDataset.__init__ sets self.revision = revision if revision else CODEBASE_VERSION. So the loader pulls the v3.0 git tag, not main, and every push silently re-points that tag at the newest commit. Anyone who cited your dataset last month is now getting different data under the same name. If you want a citable snapshot, create your own immutable tag: hf repos tag create my-user/so100-cube-to-bowl-clean 2026-08-23 --repo-type dataset, and put that tag in the card.

The dataset card
The Hub renders README.md as the dataset card. It has two halves that do completely different jobs: a YAML front matter block the Hub parses for filtering, licence display and viewer configuration, and everything below it, which only humans read. LeRobot generates both from src/lerobot/datasets/card_template.md, and the generated prose half is close to empty.
The YAML block
What lerobot writes for you is: tags: [LeRobot] plus anything you passed, task_categories: [robotics], a configs entry pointing the viewer at data/*/*.parquet, and the licence. Everything else is yours to add. This is the block that makes your dataset findable, so it is worth ten minutes.
---
license: cc-by-4.0
pretty_name: SO-100 cube-to-bowl (47 episodes, 2 cameras)
task_categories:
- robotics
size_categories:
- 10K<n<100K
language:
- en
tags:
- LeRobot
- so100
- so101
- pick-and-place
- teleoperation
- imitation-learning
- video
configs:
- config_name: default
data_files: data/*/*.parquet
---| YAML key | Why it matters here | Written by lerobot? |
|---|---|---|
| license | Displayed on the dataset page and used by every downstream filter. Defaults to apache-2.0 in push_to_hub | yes |
| tags | LeRobot is added automatically. Search huggingface.co/datasets?other=LeRobot to see the whole community set | partly |
| task_categories | Always set to robotics by the lerobot card helper | yes |
| configs | Points the Data Studio viewer at your parquet shards | yes |
| pretty_name | The human title. Put the episode count and camera count in it | no |
| size_categories | Coarse bucket, e.g. 10K| no | |
| license_name and license_link | Required when license: other, for example a custom research licence | no |
| gated, extra_gated_fields, extra_gated_prompt | Turn the repo into an access-request dataset with a custom form | no |
The half that decides whether anyone can reproduce you
The prose half of card_template.md has six substitution points, and only two get filled for you: license from the push_to_hub argument, and dataset_structure with a JSON dump of info.json. The other four are yours. dataset_description defaults to an empty string; url (rendered as Homepage), paper and citation_bibtex each default to the literal text [More Information Needed]. That triple is the signature of an unedited card, and you can see it on a large share of public LeRobot datasets. Fill them through push_to_hub, then add the sections below by editing README.md directly. Nothing enforces any of it, which is precisely why it does not happen.
- Hardware. Arm and variant (SO-100, SO-101, Koch v1.1, LeKiwi), servo model, supply voltage, and whether the leader and follower are the same model. A policy trained on your data will be deployed on hardware with different backlash. The SO-100 setup guide lists the variables that differ between two nominally identical builds.
- Cameras. One line per camera: key name, physical placement, resolution, fps, and lens. "observation.images.front, tripod 45 cm in front of the mat, 640x480, 30 fps" beats any photo.
- Calibration. Whether the arms were freshly calibrated and against which reference pose. Joint values from an uncalibrated arm are not comparable to yours.
- The task string, verbatim. It is embedded in the data and language-conditioned policies read it. LeRobot's own guidance is 25 to 50 characters and no names like task1 or demo2.
- Scene and variation. Object, its size, the surface, lighting, how many distinct start positions, how many episodes per position. This is what tells a reader whether your 50 episodes cover one pose or ten.
- What you removed. Episode indices deleted, and why. If you deleted 3 of 50, say 47 everywhere and say where the other 3 went.
- Known defects. The camera that dropped frames in episodes 12 to 15. The gripper that stuck. Nobody will hold this against you; discovering it after a training run, they will.
- A version tag you control, plus the date, so a citation resolves to fixed bytes.
If that list feels arbitrary, it is a compressed robot-specific version of the datasheet proposed in Datasheets for Datasets by Gebru and colleagues (arXiv 1803.09010, first posted 23 March 2018, revised through December 2021), which organises dataset documentation into motivation, composition, collection process, preprocessing, uses, distribution and maintenance. The robotics-specific part is that composition includes physical geometry: where the camera was, is part of the data.
Choosing a licence, and what it does not cover
Hugging Face requires a licence identifier from a fixed list before it will display one on the page. lerobot picks apache-2.0 unless you say otherwise, which is a software licence being applied to a video dataset. It works in practice, and it is not what most data publishers actually intend.
| Identifier | What it allows | Who it fits |
|---|---|---|
| apache-2.0 | Commercial use, redistribution, modification, with attribution and a patent grant | The lerobot default. Fine if you want maximum reuse and do not mind a software licence on video |
| cc-by-4.0 | Any use including commercial, requires attribution | The usual choice for data you want cited |
| cc-by-sa-4.0 | Same, but derivatives must carry the same licence | Use when you want merged datasets to stay open |
| cc-by-nc-4.0 | Non-commercial only | Excludes most companies from fine-tuning on your data. Choose deliberately, not by reflex |
| cc0-1.0 | Public domain dedication, no attribution required | Maximum reuse, zero credit |
| odc-by | Open Data Commons Attribution, written for databases rather than creative works | Legally the cleanest fit for tabular robot logs |
| cdla-permissive-2.0 | Community Data License Agreement, permissive | Common in industry data consortia |
| other | Anything else. Requires license_name and a LICENSE file or license_link | Institutional or embargoed research releases |
- Anyone can reproduce your training run, which is the only real check on a reported success rate
- The LeRobot tag makes it discoverable to everyone browsing robot data on the Hub
- Merging with other public datasets is legally trivial when the licences are compatible
- Public storage on a free account is best-effort rather than capped, and the Hub's own condition for hosting a large dataset is that you are sharing it for community reuse
- Someone else finding a defect in your data is a gift, not an embarrassment
- Gating (gated plus extra_gated_fields) makes every downloader share username and email, and the dataset settings page gives you a user access report listing each request with its status and timestamp, which some institutions require
- Private repos on a free account are capped at 100 GB, and the Data Studio viewer on private datasets needs PRO, Team or Enterprise
- cc-by-nc-4.0 protects a commercialisation plan but also removes your data from most industrial benchmarking
- Gating has two modes and both cost you something: automatic approval grants access as soon as someone hands over their details, manual approval means a human answers every request, and either way the extra click sits between your data and a casual reader
- Restricting after the fact does not work: a public dataset has already been cloned
Robot manipulation footage is filmed in real rooms. Check every camera view for faces, name badges, screens with email open, whiteboards, letters on the desk, and windows showing a recognisable street. No licence identifier turns recorded people into licensed content, and in the EU the GDPR question is not answered by cc-by-4.0. Practical fix: point the fixed camera down at the workspace so the frame ends at the table edge, and check the wrist camera too, since it sweeps the whole room. If you find a face after publishing, delete the episode with lerobot-edit-dataset and republish; the old commit still exists in git history, so you also need to squash or delete the repo.
Two ways to get a dataset published
You own the arm, you install lerobot from source, and you drive the whole chain by hand. This is the path the commands above describe and it is the one that teaches you the format.
- Install lerobot from source. Dataset v3 landed in release 0.4.0 on 23 October 2025; the newest release is 0.6.1 and
mainis 0.6.2 as of 23 August 2026. - Wire the leader and follower arms, find the ports with
lerobot-find-port, find cameras withlerobot-find-cameras, calibrate withlerobot-calibrate. - Record with
--dataset.push_to_hub=False, review, delete bad episodes, recompute stats. - Push with
push_to_hub()and the card kwargs filled in, then edit README.md by hand for the hardware, camera and defect sections. - Create your own immutable git tag so citations resolve to fixed bytes.
Not the upload. Reviewing 50 episodes at 30 fps for a wrist camera that drifted or a gripper that failed to close is roughly an hour of watching video, and there is no shortcut that is honest.
AY-Robots covers the recording and the training end, not the Hub publishing end. The desktop client records LeRobot-format datasets straight from a teleoperation session, so episodes, camera streams and joint states come out in the right schema without you assembling it. The dataset directory lists public datasets, and training can take a dataset from a Hugging Face repo id or from your own machine.
- Record with the desktop client from a teleop session, or drive a real arm first at /live with no signup to see what the data looks like.
- Check the dataset against the model you intend to train on the policies page: the minimum episode count and required format differ per model.
- Point a training run at either a Hub repo id or the local dataset. The backend rents a GPU by required VRAM and writes checkpoints to object storage.
- Do the actual Hub publishing yourself with
hf uploadand a hand-written card. That step is not automated here.
AY-Robots does not write your dataset card, does not pick your licence, and does not push to your Hugging Face namespace on your behalf. It removes the schema-assembly work at record time and the GPU-wrangling work at training time. The documentation, licensing and consent decisions in this article stay yours. Anyone telling you a platform solves those is selling something.
Make it trainable, not just downloadable
A dataset that loads is not a dataset that trains. The five policies you are most likely to point at it disagree about which format version they accept and how many episodes they need before fine-tuning produces anything. ACT trains from scratch by imitation learning and SmolVLA needs the fewest episodes of the five. Say in the card which one you built for.
| Policy | Dataset format | Minimum episodes | GPU tier |
|---|---|---|---|
| GR00T N1.7 | LeRobot v2.0 or v2.1 | 50 | A100 80 GB or H100 80 GB |
| GR00T N1.5 | LeRobot v2.0 or v2.1 | 50 | A100 80 GB or H100 80 GB |
| Pi0.5 | LeRobot v3.0 | 50 | A100 80 GB or H100 80 GB |
| SmolVLA | LeRobot v3.0 | 30 | RTX 4090 or any 24 GB card |
| ACT | LeRobot v3.0 | 50 | RTX 4090 or any 24 GB card |
That first column is the trap. GR00T N1.7 will not read a v3.0 dataset at all, and NVIDIA says so plainly: GR00T uses a flavour of the LeRobot v2 format because upstream datasets like DROID and LIBERO are published in v2. Publishing v3.0 is correct and current; it also means every GR00T user has to convert first. Publishing both, as two repos or two branches, is the friendly move, and the GR00T N1.7 on SO-100 guide assumes you have done it.
# v2.1 -> v3.0, run from a lerobot checkout against a dataset on the Hub.
# This one converts, pushes to main and moves the v3.0 tag for you.
python src/lerobot/scripts/convert_dataset_v21_to_v30.py \
--repo-id=my-user/so100-cube-to-bowl
# convert a local copy instead, without touching the Hub
python src/lerobot/scripts/convert_dataset_v21_to_v30.py \
--repo-id=my-user/so100-cube-to-bowl \
--root=/path/to/local/dataset \
--push-to-hub=false
# v3.0 -> v2, from the Isaac-GR00T repo, in its own venv
cd scripts/lerobot_conversion
uv venv && source .venv/bin/activate
uv pip install -e . --verbose
python convert_v3_to_v2.py --repo-id my-user/so100-cube-to-bowlConverting to v2 is not enough. Isaac-GR00T requires meta/modality.json, which the standard LeRobot format does not contain. The schema is {"state": {"<key>": {"start": int, "end": int}}, "action": {...}, "video": {"<new_key>": {"original_key": "..."}}, "annotation": {...}}: it slices the concatenated state and action arrays into named fields, renames video keys, and declares annotation channels. For a 6-DoF SO-100 you would typically split the arm joints from the gripper. Indices are zero-based and follow Python slicing. If you publish an SO-100 dataset you want people to fine-tune GR00T on, ship this file. It is about fifteen lines and it saves every downstream user an hour of guessing. See also the dataset-rejected-v3 failure page.

The check before you make it public
Hugging Face publishes conditions for hosting a large dataset, and the list starts with the card. They require a dataset card, require that you are sharing for community reuse rather than as private backup, require you to stay inside the repository limits, and ask for formats the ecosystem reads, naming Parquet and WebDataset. A LeRobot v3.0 repo meets the format condition through its Parquet shards, with the camera streams alongside as MP4. The limits that matter for robot data: fewer than 100k files per repo, fewer than 10k entries per folder, files under 200 GB. v3.0 sharding keeps you inside all three; v2.1, with one parquet and one mp4 per episode per camera, does not once you pass a few thousand episodes. The CLI and MCP server expose the same dataset operations if you would rather script this check.
- Open
meta/info.jsonand readtotal_episodes,total_frames,fpsandrobot_typeout loud. Do they match the card? - Load the dataset fresh in a clean environment:
LeRobotDataset("my-user/name"). If it needed a local cache to work, it is broken. - Open the dataset in the visualize_dataset Space and scrub through at least the first, middle and last episode.
- Check the Data Studio viewer renders on the Hub page. If it does not, your
configsYAML entry is wrong. - Scan every camera view for faces, screens, documents and windows.
- Confirm the licence identifier in the YAML matches what you actually intend, not the apache-2.0 default.
- Create your own dated git tag and reference it in the card.
- Have somebody who was not in the room read the card and tell you what they still cannot determine.

One honest limit on all of this: a well-documented dataset does not make a policy work. The dataset card is upstream of the parts that break. A vision-language-action model fine-tuned on 50 clean episodes still fails when the camera moves 5 cm, and inference latency between 20 and 485 ms per action step decides whether the policy runs smoothly on the arm regardless of how good the data was. Publishing well is a courtesy to the next person, and a debugging aid for yourself. It is not a performance improvement.
Is the extra afternoon worth it
- You can reproduce your own run in six months, which is the case that actually happens
- Failures become diagnosable: the card tells you whether the camera geometry changed
- Other people's fine-tunes are comparable to yours, because the setup is written down
- Filling dataset_description, url and citation_bibtex is one push_to_hub call, not manual editing
- Reviewing every episode is real time, roughly an hour per 50 episodes at 30 fps
- Nothing enforces any of it, so the incentive is entirely internal
- The v2 and v3 split means a genuinely useful publication is often two repos, not one
- Republishing moves the v3.0 tag, so anyone pinned to it silently gets the new data
Record the dataset before you worry about publishing it
The AY-Robots desktop client records LeRobot-format datasets straight from a teleoperation session: episodes, camera streams and joint states in the right schema, so the only work left is the card, the licence and the push.
Get the desktop clientQuestions people actually ask
Which licence should I put on a robot dataset?▾
If you want citations and broad reuse, cc-by-4.0. If you want the cleanest legal fit for tabular logs, odc-by. lerobot's push_to_hub defaults to apache-2.0, which is a software licence and works in practice but is probably not what you meant. Avoid cc-by-nc-4.0 unless you have a specific commercialisation reason, because it removes your data from most industrial use.
How many episodes should I record before publishing?▾
LeRobot's own recording guide suggests at least 50 episodes with 10 per object location. On AY-Robots the minimum episode counts per policy are 30 for SmolVLA and 50 for ACT, Pi0.5, GR00T N1.5 and GR00T N1.7. Publishing fewer is still useful if the card says clearly what the dataset is for; publishing 20 episodes described as a training set is not.
Do I have to convert my dataset to v2.1 for GR00T?▾
Yes. GR00T uses a flavour of the LeRobot v2 format and a v3.0 dataset will not load. Convert with the convert_v3_to_v2.py script in the Isaac-GR00T repo, then add meta/modality.json, which the standard LeRobot format does not write. If you expect GR00T users, publishing both versions saves everyone the round trip.
Why does my dataset load different data than it did last week?▾
Because LeRobotDataset resolves its revision to CODEBASE_VERSION when you do not pass one, so it fetches the v3.0 git tag rather than main, and push_to_hub deletes and recreates that tag on every push. Any republish moves it. Create your own dated tag and pass revision= explicitly if you need stable bytes.
Can I delete an episode after publishing?▾
You can, but do it with lerobot-edit-dataset --operation.type=delete_episodes rather than through the Hub file browser, because episode boundaries live in meta/episodes/ and not in filenames. That operation writes a new dataset and re-aggregates stats.json for the episodes it kept, so you do not have to recompute statistics separately; recompute_stats is only for a from-scratch rebuild, and it writes to {repo_id}_recomputed_stats unless you pass new_repo_id and operation.overwrite. Note that the old commit remains in git history, so for a privacy problem you need to squash the history or delete the repo, not just push a fix.
Does the Hub dataset viewer work for LeRobot datasets?▾
Yes, as long as the configs entry in your YAML points at data/*/*.parquet, which the lerobot card helper writes for you. Data Studio auto-converts the first 5 GB to Parquet, and for larger Parquet datasets sorting, filtering and search stay limited to those first 5 GB. On private datasets the viewer requires PRO, Team or Enterprise.
Sources
- Hugging Face dataset card YAML metadata specification
- Hugging Face Hub: Licenses, the accepted licence identifiers
- Hugging Face Hub: Gated datasets, extra_gated_fields and approval modes
- Hugging Face Hub: Storage limits, plans and repository recommendations
- Hugging Face Hub: Data Studio, the dataset viewer
- LeRobotDataset v3.0 format documentation
- LeRobot: Imitation Learning on Real-World Robots, recording and upload
- LeRobot Community Datasets: The ImageNet of Robotics - When and How? (11 May 2025)
- lerobot: LeRobotDataset.push_to_hub, revision resolution and version tagging
- lerobot: metadata paths, chunk and file size defaults, dataset card construction
- lerobot: dataset card template and its placeholders
- lerobot: delete_episodes, recompute_stats and statistics aggregation
- lerobot-edit-dataset: operations, flags and default output repositories
- Isaac-GR00T: LeRobot v2 requirements and the meta/modality.json schema
- Gebru et al., Datasheets for Datasets (arXiv 1803.09010)
Sources
- Hugging Face dataset card YAML metadata specification
- Hugging Face Hub: Licenses, the accepted licence identifiers
- Hugging Face Hub: Gated datasets, extra_gated_fields and approval modes
- Hugging Face Hub: Storage limits, plans and repository recommendations
- Hugging Face Hub: Data Studio, the dataset viewer
- LeRobotDataset v3.0 format documentation
- LeRobot: Imitation Learning on Real-World Robots, recording and upload
- LeRobot Community Datasets: The ImageNet of Robotics - When and How? (11 May 2025)
- lerobot: LeRobotDataset.push_to_hub, revision resolution and version tagging
- lerobot: metadata paths, chunk and file size defaults, dataset card construction
- lerobot: dataset card template and its placeholders
- lerobot: delete_episodes, recompute_stats and statistics aggregation
- lerobot-edit-dataset: operations, flags and default output repositories
- Isaac-GR00T: LeRobot v2 requirements and the meta/modality.json schema
- Gebru et al., Datasheets for Datasets (arXiv 1803.09010)
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started