FAQ

Physical AI

The LeRobotDataset format, and what changed in v3

Parquet for signals, MP4 per camera, JSON for schema — and why v3 stopped using filenames to find episode boundaries.

LeRobotDataset has become the de-facto packaging standard for community robot data. Its v3 redesign is a good lesson in what breaks when a dataset format meets a million episodes.

What it standardises

The LeRobot v3 docs describe it as “a standardized format for robot learning data” — one interface over sensorimotor signals and multi-camera video, plus the collection metadata that makes a recording interpretable: task description, robot type, frame rates.

Robot data is awkward precisely because it is heterogeneous. A single episode is a high-frequency stream of joint states and actions, several synchronised video feeds at a different rate, and a natural-language task label. Storing that well means storing each part in the format suited to it, which is what the three pillars do.

A node diagram titled Node Communication: a Master node publishes to a Joint states topic; Puppet and Data nodes subscribe to it; an Images topic collects Top, Front and Pruner camera nodes, which also feed the Data node. Notes explain each node's role.
How one lab's leader–follower rig records demonstrations in ROS 2: the master arm publishes its joint angles, the puppet arm subscribes and mirrors them, and a data node records the joint states together with images from three cameras (top, front and pruner). Every rig produces the same ingredients, joint streams, several video feeds and timestamps, and that is what a shared format has to package. Image: Figure 4 of the article · CC BY 4.0 · from Kasu & Um 2026, Frontiers in Robotics and AI, “Object-centric diffusion policies for real-world robotic-arm imitation learning”, doi:10.3389/frobt.2026.1829436

The three pillars

The docs state the division explicitly.

  • Tabular — “low-dimensional, high-frequency signals (states, actions, timestamps) stored in Apache Parquet.” Columnar, so you can scan actions across a whole dataset without touching the video.
  • Visual — “camera frames concatenated and encoded into MP4. Frames from the same episode are grouped; videos are sharded per camera for practical sizes.” Video codecs rather than per-frame images, which is a very large storage difference.
  • Metadata — “JSON/Parquet records describing schema (feature names, dtypes, shapes), frame rates, normalization stats, and episode segmentation (start/end offsets into shared Parquet/MP4 files).”
the v3 on-disk layout, from the docs
meta/info.json        canonical schema (features, shapes/dtypes), FPS, codebase version,
                      and path templates to locate data/video shards
meta/stats.json       global feature statistics (mean/std/min/max) for normalization
                      -> exposed as dataset.meta.stats
meta/tasks.parquet    natural-language task descriptions mapped to integer IDs
meta/episodes/        per-episode records (lengths, tasks, offsets) as chunked Parquet
data/                 frame-by-frame Parquet shards; each file holds many episodes
videos/               MP4 shards per camera; each file holds many episodes
A vision-language-action architecture diagram: a wrist-camera image and the instruction 'Pick up the apple and place it into the bottom shelf' feed a frozen Vision Encoder and Text Tokenizer into a frozen Eagle-2 VLM, while robot state and noised actions pass through State and Action Encoders into N DiT blocks of alternating cross-attention and self-attention, an Action Decoder emitting motor actions for a humanoid over K iterations.
A vision-language-action policy with the VLM frozen while the state and action encoders, the DiT action head and the action decoder are trained. Everything the trained part sees arrives through the dataset's state and action fields, so their units and frame conventions have to be right. Image: huggingface/lerobot · Apache-2.0 repository

Why v3 abandoned one-file-per-episode

In v2, each episode was its own file and episode boundaries were recovered from filenames. That is the obvious design and it works well up to a point.

The limit is file count. A million small files makes dataset initialisation slow, strains object stores and filesystems, and turns listing the dataset into a significant operation. The docs state the motivation directly: “to scale to millions of episodes… fewer, larger files ⇒ faster initialization and fewer issues at scale.”

So v3 concatenates many episodes into each Parquet and MP4 shard and resolves boundaries through “relational metadata: episode boundaries and lookups are resolved through metadata, not filenames.” The stated design principle is “decoupling storage from the user API” — the Python interface still hands you episodes while the layout underneath is free to change.

This is the same lesson the Parquet ecosystem learned about small files, arriving in robotics.

In v2 each episode was its own Parquet file and its own MP4 per camera, and the filename marked where it began and ended. v3 packs many episodes into each shard and looks the boundaries up in meta/episodes/, so a million episodes no longer means a million small files.

The feature keys

The docs show sample keys — observation.state, action, observation.images.<camera>, timestamp — presented as an example rather than as a required schema.

That distinction matters. The format does not mandate a fixed set of features; it mandates that whatever features you have are declared in meta/info.json with their shapes and dtypes. The dotted naming convention is a convention, and the loader reads your declaration.

Worth knowing what the docs do not publish: chunking and file-size defaults, the required info.json field list, the column names inside meta/episodes/, and codec details. If you are writing a converter rather than using the library's own writer, read the library source rather than relying on the documentation page.

Two small 3D-printed robot arms on a white table: an orange follower arm ending in a two-finger gripper and a yellow leader arm ending in a handle, both built from servo motors with exposed cables.
A leader arm (yellow, with a handle) and the follower arm it drives (orange). Recording with a pair like this, LeRobot stores the leader's joint positions as action and the follower's measured joints as observation.state, so both streams need their names and shapes declared in meta/info.json. Image: huggingface/lerobot · Apache-2.0 repository

What consumes it

The strongest argument for the format is the breadth of what now reads it. LeRobot implements policies in pure PyTorch, all consuming LeRobotDataset, across imitation learning (ACT, Diffusion, VQ-BeT), reinforcement learning (HIL-SERL, TD-MPC) and vision-language-action models (the Pi0 family, SmolVLA and others).

One on-disk layout feeding imitation learning, RL and VLAs is precisely why the v3 scaling change mattered — the format outgrew its original use. Evaluation runs through lerobot-eval against standard benchmarks including LIBERO and MetaWorld.

The library is Apache 2.0. Datasets published in the format carry their own per-repository licences, and the format implies nothing whatsoever about them — a point worth internalising given how many large robotics datasets are non-commercial.

A stacked bar chart of datasets per month from 2024-08 to 2025-09 by robot type (Other in grey, koch, panda, so100 in red, so101 in brown) with a red trend line, rising from 30 to a peak around June 2025 and easing afterwards; bar segments are labelled with counts such as 896 and 1k.
New datasets published in the LeRobot format each month from August 2024 to September 2025, by robot: from 30 in the first month to more than 2,000 a month by mid-2025, most recorded on the low-cost SO-100 and SO-101 arms. A popular format says nothing about any one dataset's licence or quality. Image (cropped and edited): Figure 5 (one panel) of the paper · CC BY 4.0 · from “LeRobot: An Open-Source Library for End-to-End Robot Learning”, arXiv:2602.22818

Questions people ask

Can I convert Open X-Embodiment data to LeRobot format?

Yes, and community ports exist for much of it. OXE ships as RLDS in TFRecord files, so a conversion step is needed, which is exactly why those ports are popular. Check the licence of each constituent dataset rather than assuming the port's licence covers it.

How do I publish my own dataset in this format?

Record with the library's own dataset writer, which produces the layout and metadata correctly, then push to the Hub. Writing the files by hand is possible but you then own the correctness of meta/info.json and the episode offsets, which is the fiddly part.

Why MP4 rather than individual frames?

Storage and read throughput. Video codecs exploit temporal redundancy between consecutive frames, which for a static camera watching a slow manipulation is enormous. The cost is that random access to a single frame requires seeking into a compressed stream, which the sharding and offset metadata are designed to make tractable.

Does the format handle tactile or force sensing?

Yes — any low-dimensional, high-frequency signal belongs in the Parquet tier alongside joint states, declared in meta/info.json with its shape and dtype. The format is agnostic about which sensors you have, which is the point of declaring features rather than fixing them.

Stop hunting. Start searching.

Tens of thousands of curated datasets, searchable in plain language — with the licence and size checked before you download anything.

Search Dataset Finder →