Skip to content
← OpenK Arm

Project files

5 KB

Machine-translated by Robotheca from the original in Japanese (opens in a new tab). License: Apache-2.0 (opens in a new tab).

LeRobot Hugging Face Dataset Guide (OpenK)

This note summarizes how to register, update, and read LeRobot datasets on the Hugging Face Hub with OpenK, based on scripts/ and config/.

Reference sources:

  • scripts/openk_record.py
  • scripts/lerobot_replay.py
  • config/record_example.yaml

1. Registration (Creating a Dataset on the Hub)

A dataset is created at recording time. The key setting is dataset.repo_id, which should be in the <hf_username>/<dataset_name> format.

Example (from the README):

uv run openk-record \
  --robot.type=openk-1-alpha_follower --robot.port=<follower-port> --robot.id=follower \
  --teleop.type=openk_leader --teleop.port=<leader-port> --teleop.id=leader \
  --dataset.repo_id=<user>/<dataset> --dataset.num_episodes=2 --dataset.single_task="Describe task" \
  --log_file=logs/openk_record.log

Main options (of scripts/openk_record.py DatasetRecordConfig):

  • --dataset.repo_id: The repository ID on the Hub. Required.
  • --dataset.single_task: A description of the recorded task. Saved as the task of each frame.
  • --dataset.push_to_hub: Default true. Uploaded after recording finishes.
  • --dataset.private: Set to private with true.
  • --dataset.tags: A list of tags to attach.

Note: Uploading to the Hub requires authentication (for example, huggingface-cli login or HF_TOKEN).

2. Local storage location

If --dataset.root is not specified, the data is saved to the default HF datasets cache (~/.cache/huggingface/datasets/) (see the comment in config/record_example.yaml).

Example:

--dataset.root=./data

3. Updating an Existing Dataset (Appending)

Passing the same repo_id with --resume=true appends episodes to the existing dataset. When root is specified, the same path is used.

Flow of scripts/openk_record.py:

  • If resume=true, create LeRobotDataset(...)
  • Save frames with dataset.add_frame(...)
  • Finalize the episode with dataset.save_episode()
  • If push_to_hub=true, then dataset.push_to_hub(...)

Example:

uv run openk-record \
  --config_path=config/record_example.yaml \
  --dataset.repo_id=<user>/<dataset> \
  --resume=true

Tip: To record locally first, set --dataset.push_to_hub=false, and later you can call dataset.push_to_hub(...).

4. Data Structure (What Gets Stored)

The dataset schema is constructed dynamically, combining:

  • Robot observation feature
  • Teleoperation or policy action features
  • Additional features added by the pipeline

scripts/openk_record.py constructs dataset.features, and each frame contains:

  • task: string (single_task)
  • Observation fields (prefix OBS_STR)
  • Action fields (prefix ACTION)
  • Episode information such as episode_index

Column names change depending on the robot, camera, and policy configuration, so it is safest to check dataset.features before analyzing the data.

For --dataset.video=true, the frames are turned into video by VideoEncodingManager, and for false, they are saved as PNG images.

5. Reading and Parsing

A. Loading with LeRobotDataset (this repository's standard)

from lerobot.datasets.lerobot_dataset import LeRobotDataset

ds = LeRobotDataset("<user>/<dataset>", root=None)
print("fps:", ds.fps)
print("num_episodes:", ds.num_episodes)
print("features:", ds.features)

hf = ds.hf_dataset
print("columns:", hf.column_names)

# 例: あるエピソードだけ抽出
ep0 = hf.filter(lambda x: x["episode_index"] == 0)
actions = ep0.select_columns("action")

B. Action extraction along the replay flow

(Equivalent to scripts/lerobot_replay.py)

episode_frames = ds.hf_dataset.filter(lambda x: x["episode_index"] == 0)
actions = episode_frames.select_columns("action")
for i in range(len(episode_frames)):
    action_vec = actions[i]["action"]
    # action 名は ds.features["action"]["names"] を参照

C. pandas で簡易集計

df = ds.hf_dataset.to_pandas()
counts = df.groupby("episode_index").size()
print(counts)

※ to_pandas() はデータ量が多いと重くなる点に注意してください。

6. Practical Operational Notes

  • The FPS must match: check it within record_loop using dataset.fps == cfg.dataset.fps.
  • The schema depends on the configuration. Do not fix column names; check features before handling them.
  • When changing observation or action names, use --dataset.rename_map to maintain compatibility.
  • When saving video, adjust --dataset.video_encoding_batch_size and the number of image writer threads to keep the FPS stable.

7. Related files

  • Recording and upload: scripts/openk_record.py
  • Replay (episode extraction): scripts/lerobot_replay.py
  • Configuration examples: config/record_example.yaml, config/record_one_motor_test.yaml

Files by @CleanKDev, at commit 26b149e, read from GitHub in your browser. Hardware license: Apache-2.0; software license: Apache-2.0. Robotheca doesn't review code: read it before running it.