LeRobot documentation
Datasets
Datasets
LeRobotDataset is the format every LeRobot script reads and writes. It is episode-aware, decodes video
observations on the fly, and round-trips to the Hugging Face Hub.
See Using LeRobotDataset for the format and the common operations, Porting Large Datasets for migration, and Tools for the CLI.
LeRobotDataset
class lerobot.datasets.LeRobotDataset
< source >( repo_id: strroot: str | pathlib.Path | None = Noneepisodes: list[int] | None = Noneepisode_filter: collections.abc.Callable[[dict], bool] | None = Noneimage_transforms: collections.abc.Callable | None = Nonedelta_timestamps: dict[str, list[float]] | None = Nonetolerance_s: float = 0.0001revision: str | None = Noneforce_cache_sync: bool = Falsedownload_videos: bool = Truevideo_backend: str | None = Nonereturn_uint8: bool = Falsedepth_output_unit: str = 'mm'batch_encoding_size: int = 1rgb_encoder: lerobot.configs.video.RGBEncoderConfig | None = Nonedepth_encoder: lerobot.configs.video.DepthEncoderConfig | None = Noneencoder_threads: int | None = Nonestreaming_encoding: bool = Falseencoder_queue_maxsize: int = 30token: str | bool | None = None )
add_frame
< source >( frame: dict )
Add a single frame to the current episode buffer.
Delegates to DatasetWriter.add_frame. The dataset must be in
write mode (created via create or resume).
clear_episode_buffer
< source >( delete_images: bool = True )
Discard the current episode buffer without saving.
Delegates to DatasetWriter.clear_episode_buffer. Useful for
discarding a failed or interrupted recording episode.
Remove the transform applied to visual observations.
create
< source >( repo_id: strfps: intfeatures: dictroot: str | pathlib.Path | None = Nonerobot_type: str | None = Noneuse_videos: bool = Truetolerance_s: float = 0.0001image_writer_processes: int = 0image_writer_threads: int = 0video_backend: str | None = Nonebatch_encoding_size: int = 1rgb_encoder: lerobot.configs.video.RGBEncoderConfig | None = Nonedepth_encoder: lerobot.configs.video.DepthEncoderConfig | None = Nonemetadata_buffer_size: int = 10streaming_encoding: bool = Falseencoder_queue_maxsize: int = 30encoder_threads: int | None = Nonevideo_files_size_in_mb: int | None = Nonedata_files_size_in_mb: int | None = None )
Parameters
- repo_id — Repository identifier, typically
'{hf_user}/{dataset_name}'. - fps — Frames per second used during data collection.
- features — Feature specification dict mapping feature names to their type/shape metadata.
- root — Local directory for dataset storage. Defaults to
$HF_LEROBOT_HOME/{repo_id}. - robot_type — Optional robot type string stored in metadata.
- use_videos — If
True, visual modalities are stored as MP4 videos. IfFalse, they are stored as images. - tolerance_s — Timestamp synchronization tolerance in seconds.
- image_writer_processes — Number of subprocesses for async image
writing.
0means use threads only. - image_writer_threads — Number of threads for async image writing.
- video_backend — Video decoding backend (used when reading back).
- batch_encoding_size — Number of episodes to accumulate before
batch-encoding videos.
1means encode immediately. - rgb_encoder — Video encoder settings for cameras (codec, quality, etc.).
When
None,rgb_encoder_defaults()is used. - depth_encoder — Video encoder settings for depth cameras (codec, quality, etc.).
When
None,depth_encoder_defaults()is used. - encoder_threads — Number of encoder threads (global).
Nonelets the codec decide. - metadata_buffer_size — Number of episode metadata records to buffer before flushing to parquet.
- streaming_encoding — If
True, encode video frames in real-time during capture instead of writing images first. - encoder_queue_maxsize — Max buffered frames per camera when using streaming encoding.
Create a new LeRobotDataset from scratch for recording data.
Returns a write-mode dataset with an active DatasetWriter. Use add_frame / save_episode to populate it, then finalize when done.
Flush all pending work and close writers.
Must be called after data collection/conversion, otherwise footer metadata won’t be written to the parquet files and the dataset will be invalid.
Idempotent — safe to call multiple times. DatasetWriter.del acts as a safety net if this is never called explicitly.
Get a raw frame without image transforms applied.
Unlike __getitem__, this returns the raw HF dataset row at the given
index with no delta-timestamp expansion, video decoding, or image transforms.
Check if there are unsaved frames in the episode buffer.
push_to_hub
< source >( branch: str | None = Nonetags: list | None = Nonelicense: str | None = 'apache-2.0'tag_version: bool = Truepush_videos: bool = Trueprivate: bool | None = Noneallow_patterns: list[str] | str | None = Noneupload_large_folder: bool = False**card_kwargs )
Parameters
- branch — Optional branch to push to. Created from the current revision if it does not exist.
- tags — Optional list of tags for the dataset card.
- license — License identifier for the dataset card.
- tag_version — If
True, create a Git tag for the current codebase version. - push_videos — If
False, skip uploading thevideos/directory. - private — If
True, create a private repository. IfNone(default), defer to the org default on the Hub (only affects orgs). - allow_patterns — Glob pattern(s) restricting which files to upload.
- upload_large_folder — If
True, useupload_large_folderinstead ofupload_folderfor very large datasets. - **card_kwargs — Additional keyword arguments forwarded to dataset card creation.
Upload the dataset to the Hugging Face Hub.
Creates the repository if it does not exist, uploads all dataset files (optionally excluding videos), generates a dataset card, and tags the revision with the current codebase version.
resume
< source >( repo_id: strroot: str | pathlib.Path | None = Nonetolerance_s: float = 0.0001revision: str | None = Noneforce_cache_sync: bool = Falsevideo_backend: str | None = Nonebatch_encoding_size: int = 1rgb_encoder: lerobot.configs.video.RGBEncoderConfig | None = Nonedepth_encoder: lerobot.configs.video.DepthEncoderConfig | None = Noneencoder_threads: int | None = Noneimage_writer_processes: int = 0image_writer_threads: int = 0streaming_encoding: bool = Falseencoder_queue_maxsize: int = 30token: str | bool | None = None )
Parameters
- repo_id — Repository identifier of the existing dataset.
- root — Local directory of the dataset. When provided, Hub downloads
are materialized directly into this directory. When omitted,
Hub downloads use a revision-safe snapshot cache under
$HF_LEROBOT_HOME/hub. - tolerance_s — Timestamp synchronization tolerance in seconds.
- revision — Git revision (branch, tag, or commit hash). Defaults to current codebase version tag.
- force_cache_sync — If
True, re-download metadata from the Hub even if a local cache exists. - video_backend — Video decoding backend for reading back data.
- batch_encoding_size — Number of episodes to accumulate before batch-encoding videos.
- rgb_encoder — Video encoder settings for cameras (codec, quality, etc.).
When
None,rgb_encoder_defaults()is used. - depth_encoder — Video encoder settings for depth cameras (codec, quality, etc.).
When
None,depth_encoder_defaults()is used. - encoder_threads — Number of encoder threads (global).
Nonelets the codec decide. - image_writer_processes — Subprocesses for async image writing.
- image_writer_threads — Threads for async image writing.
- streaming_encoding — If
True, encode video in real-time during capture. - encoder_queue_maxsize — Max buffered frames per camera for streaming.
- token — Authentication token used if metadata must be downloaded from the Hub. The token is not retained on the dataset instance.
Resume recording on an existing dataset.
Loads metadata from an existing dataset (local or Hub) and creates a DatasetWriter for appending new episodes. The underlying HF
dataset is not loaded until finalize is called and data is
subsequently read.
save_episode
< source >( episode_data: dict | None = Noneparallel_encoding: bool = True )
Parameters
- episode_data — Optional pre-built episode dict. If
None, uses the internal episode buffer populated byadd_frame. - parallel_encoding — If
Trueand multiple cameras exist, encode videos in parallel using a process pool.
Raises
RuntimeError
RuntimeError— If the dataset is read-only (no writer).
Save the current episode buffer to disk.
Delegates to DatasetWriter.save_episode. Encodes videos, writes
parquet data, and updates metadata. The episode buffer is reset afterward.
Select specific columns from the underlying dataset.
Useful for extracting action sequences during replay without loading all features.
Returns a datasets.Dataset containing only the requested columns.
Replace the transform applied to visual observations.
LeRobotDatasetMetadata
class lerobot.datasets.LeRobotDatasetMetadata
< source >( repo_id: strroot: str | pathlib.Path | None = Nonerevision: str | None = Noneforce_cache_sync: bool = Falsemetadata_buffer_size: int = 10repo_type: typing.Literal['dataset', 'bucket'] = 'dataset'token: str | bool | None = None )
Metadata container for a LeRobot dataset.
Manages the info.json, stats.json, tasks.parquet, and episodes/ parquet files that describe a dataset’s structure, content,
and statistics.
create
< source >( repo_id: strfps: intfeatures: dictrobot_type: str | None = Noneroot: str | pathlib.Path | None = Noneuse_videos: bool = Truemetadata_buffer_size: int = 10chunks_size: int | None = Nonedata_files_size_in_mb: int | None = Nonevideo_files_size_in_mb: int | None = None )
Parameters
- repo_id — Repository identifier (e.g.
'user/my_dataset'). - fps — Frames per second used during data collection.
- features — Feature specification dict mapping feature names to their type/shape metadata.
- robot_type — Optional robot type string stored in metadata.
- root — Local directory for the dataset. Defaults to
$HF_LEROBOT_HOME/{repo_id}. Must not already exist. - use_videos — If
True, visual modalities are encoded as MP4 videos. - metadata_buffer_size — Number of episode metadata records to buffer before flushing to parquet.
- chunks_size — Max number of files per chunk directory.
Noneuses the default. - data_files_size_in_mb — Max parquet file size in MB.
Noneuses the default. - video_files_size_in_mb — Max video file size in MB.
Noneuses the default.
Create metadata for a new LeRobot dataset from scratch.
Initializes the info.json file on disk with the provided feature
schema and dataset settings. No episode data is written yet.
Guarantee metadata is fully loaded for read operations.
Idempotent — when metadata is already in memory this is a single is None check. Call this before transitioning from write to
read mode on the same instance.
filter_episodes
< source >( predicate: Callablecandidates: list[int] | None = None )
Filter episodes whose metadata satisfies a given predicate.
Flush metadata buffer and close the parquet writer.
Idempotent — safe to call multiple times.
Get current chunk and file size settings.
get_data_file_path
< source >( ep_index: int )
Return the relative parquet file path for the given episode index.
Given a task in natural language, returns its task_index if the task already exists in the dataset, otherwise return None.
get_video_file_path
< source >( ep_index: intvid_key: str )
Return the relative video file path for the given episode and video key.
Rescale depth feature stats in place from their recorded unit to output_unit.
Depth stats are stored in the unit the frames were recorded in
(features[key]["info"]["depth_unit"]), while frames are returned in output_unit on read. This converts the unit-bearing stat entries so
stats match the frames consumers see.
save_episode
< source >( episode_index: intepisode_length: intepisode_tasks: listepisode_stats: dictepisode_metadata: dict )
Parameters
- episode_index — Zero-based index of the episode being saved.
- episode_length — Number of frames in this episode.
- episode_tasks — List of task descriptions for this episode.
- episode_stats — Per-feature statistics for this episode.
- episode_metadata — Additional metadata (chunk/file indices, frame ranges, video timestamps, etc.).
Persist episode metadata, update dataset info, and aggregate stats.
Writes the episode’s metadata to the buffered parquet writer, increments
the total episode/frame counters in info.json, and merges the
episode’s statistics into the running dataset statistics.
save_episode_tasks
< source >( tasks: list )
Register tasks for the current episode and persist to disk.
New tasks that do not already exist in the dataset are assigned sequential task indices and appended to the tasks parquet file.
update_chunk_settings
< source >( chunks_size: int | None = Nonedata_files_size_in_mb: int | None = Nonevideo_files_size_in_mb: int | None = None )
Update chunk and file size settings after dataset creation.
This allows users to customize storage organization without modifying the constructor. These settings control how episodes are chunked and how large files can grow before creating new ones.
update_video_info
< source >( video_key: str | None = Nonevideo_encoder: lerobot.configs.video.VideoEncoderConfig | None = Nonepreserve_keys: collections.abc.Iterable[str] | None = None )
Parameters
- video_key — If provided, only update this video key. Otherwise update all video keys in the dataset.
- video_encoder — Encoder configuration used to produce the
videos. When provided, its fields are recorded as
video.<field>entries alongside the stream-derivedvideo.*entries (seeget_video_info). - preserve_keys — Keys whose existing values are kept instead of being
recomputed.
None(default) recomputes every key.
Populate or refresh per-feature video info in info.json.
Warning: this function writes info from first episode videos, implicitly assuming that all videos have been encoded the same way. Also, this means it assumes the first episode exists.
Always re-probes the videos and overwrites existing info for every recomputed
key. preserve_keys lists keys whose existing values must be kept (e.g.
data-intrinsic entries like is_depth_map and depth quantization params)
instead of being recomputed.
MultiLeRobotDataset
class lerobot.datasets.MultiLeRobotDataset
< source >( repo_ids: listroot: str | pathlib.Path | None = Noneepisodes: dict | None = Noneimage_transforms: collections.abc.Callable | None = Nonedelta_timestamps: dict[str, list[float]] | None = Nonetolerances_s: dict | None = Nonedownload_videos: bool = Truevideo_backend: str | None = Nonetoken: str | bool | None = None )
A dataset consisting of multiple underlying LeRobotDatasets.
The underlying LeRobotDatasets are effectively concatenated, and this class adopts much of the API
structure of LeRobotDataset.
Remove the transform from this dataset and its children.
Replace the transform for this dataset and its children.
StreamingLeRobotDataset
class lerobot.datasets.StreamingLeRobotDataset
< source >( repo_id: strroot: str | pathlib.Path | None = Noneepisodes: list[int] | None = Noneimage_transforms: collections.abc.Callable | None = Nonedelta_timestamps: dict[list[float]] | None = Nonetolerance_s: float = 0.0001revision: str | None = Noneforce_cache_sync: bool = Falsestreaming: bool = Truebuffer_size: int = 1000max_num_shards: int = 16seed: int = 42rng: numpy.random._generator.Generator | None = Noneshuffle: bool = Truereturn_uint8: bool = Falsedepth_output_unit: str = 'mm'repo_type: typing.Literal['dataset', 'bucket'] = 'dataset'token: str | bool | None = None )
LeRobotDataset with streaming capabilities.
This class extends LeRobotDataset to add streaming functionality, allowing data to be streamed rather than loaded entirely into memory. This is especially useful for large datasets that may not fit in memory or when you want to quickly explore a dataset without downloading it completely.
The key innovation is using a Backtrackable iterator that maintains a bounded buffer of recent items, allowing us to access previous frames for delta timestamps without loading the entire dataset into memory.
Example:
Basic usage:
from lerobot.common.datasets.streaming_dataset import StreamingLeRobotDataset
# Create a streaming dataset with delta timestamps
delta_timestamps = {
"observation.image": [-1.0, -0.5, 0.0], # 1 sec ago, 0.5 sec ago, current
"action": [0.0, 0.1, 0.2], # current, 0.1 sec future, 0.2 sec future
}
dataset = StreamingLeRobotDataset(
repo_id="your-dataset-repo-id",
delta_timestamps=delta_timestamps,
streaming=True,
buffer_size=1000,
)
# Iterate over the dataset
for i, item in enumerate(dataset):
print(f"Sample {i}: Episode {item['episode_index']} Frame {item['frame_index']}")
# item will contain stacked frames according to delta_timestamps
if i >= 10:
breakMakes a frame starting from a dataset iterator