LeRobot 文件
LeRobotDataset v3.0
並獲得增強的文件體驗
開始使用
LeRobotDataset v3.0
LeRobotDataset v3.0 是機器人學習資料的標準化格式。它提供對多模態序列資料、感測運動訊號與多鏡頭影片的統一存取,並提供豐富的元數據(metadata),以便在 Hugging Face Hub 上進行索引、搜尋與視覺化。
此文件將引導您:
- 瞭解 v3.0 的設計與目錄結構
- 錄製資料集並推送到 Hub
- 使用
LeRobotDataset載入資料集進行訓練 - 使用
StreamingLeRobotDataset在不下載的情況下串流資料集 - 在訓練期間應用影像轉換(Image Transforms)進行資料增強
- 將現有的
v2.1資料集遷移至v3.0
v3 版本的新功能
- 基於文件的存儲:每個 Parquet/MP4 文件包含多個章節(v2 中一個章節一個文件)。
- 關聯式元數據:章節邊界與查詢透過元數據解析,而非文件名。
- Hub 原生串流:使用
StreamingLeRobotDataset直接從 Hub 取用資料集。 - 降低文件系統壓力:更少且更大的文件 ⇒ 初始化更快,且大規模運作時問題更少。
- 統一組織:簡潔的目錄佈局,資料與影片共用一致的路徑模板。
安裝
LeRobotDataset v3.0 將包含在 lerobot >= 0.4.0 中。
在該穩定版本發佈之前,您可以按照 從源碼構建說明 使用 main 分支。
記錄資料集
運行下方命令以使用 SO-101 錄製資料集並推送到 Hub:
lerobot-record \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem585A0076841 \
--robot.id=my_awesome_follower_arm \
--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 1920, height: 1080, fps: 30}}" \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem58760431551 \
--teleop.id=my_awesome_leader_arm \
--display_data=true \
--dataset.repo_id=${HF_USER}/record-test \
--dataset.num_episodes=5 \
--dataset.single_task="Grab the black cube" \
--dataset.streaming_encoding=true \
# --dataset.vcodec=auto \
--dataset.encoder_threads=2請參閱 錄製指南 瞭解更多細節。
格式設計
v3 的核心原則是將存儲與用戶 API 解耦:資料以高效方式存儲(少量大文件),而公共 API 則提供直觀的章節級別存取。
v3 有三大支柱:
- 表格資料:低維度、高頻率訊號(狀態、動作、時間戳記)存儲在 Apache Parquet 中。透過
datasets套件進行記憶體映射(memory-mapped)或串流存取。 - 視覺資料:相機影格被串聯並編碼為 MP4。同一章節的影格會被歸類;影片按相機分片以維持實用的文件大小。
- 元數據:描述架構(特徵名稱、資料類型、形狀)、影格率、正規化統計數據以及 章節分割(在共用的 Parquet/MP4 文件中的起止偏移量)的 JSON/Parquet 記錄。
為了擴展至數百萬個章節,來自多個章節的表格列和影片影格被 串聯 到較大的文件中。特定章節的視圖是 透過元數據 重建的,而非依賴文件邊界。
目錄佈局(簡化版)
meta/info.json:正式架構(特徵、形狀/資料類型)、FPS、代碼版本,以及定位資料/影片分片所需的 路徑模板。meta/stats.json:用於正規化的全局特徵統計數據(均值/標準差/最小/最大);透過dataset.meta.stats呈現。meta/tasks.jsonl:自然語言任務描述,映射至整數 ID,供任務條件策略(task-conditioned policies)使用。meta/episodes/:每個章節的記錄(長度、任務、偏移量),以 分塊 Parquet 格式存儲以利擴充。data/:逐格的 Parquet 分片;每個文件通常包含 多個章節。videos/:每個相機的 MP4 分片;每個文件通常包含 多個章節。
載入訓練用資料集
LeRobotDataset 會返回由 PyTorch 張量組成的 Python 字典,並與 torch.utils.data.DataLoader 整合。以下是顯示其用法的程式碼範例:
import torch
from lerobot.datasets.lerobot_dataset import LeRobotDataset
repo_id = "yaak-ai/L2D-v3"
# 1) Load from the Hub (cached locally)
dataset = LeRobotDataset(repo_id)
# 2) Random access by index
sample = dataset[100]
print(sample)
# {
# 'observation.state': tensor([...]),
# 'action': tensor([...]),
# 'observation.images.front_left': tensor([C, H, W]),
# 'timestamp': tensor(1.234),
# ...
# }
# 3) Temporal windows via delta_timestamps (seconds relative to t)
delta_timestamps = {
"observation.images.front_left": [-0.2, -0.1, 0.0] # 0.2s and 0.1s before current frame
}
dataset = LeRobotDataset(repo_id, delta_timestamps=delta_timestamps)
# Accessing an index now returns a stack for the specified key(s)
sample = dataset[100]
print(sample["observation.images.front_left"].shape) # [T, C, H, W], where T=3
# 4) Wrap with a DataLoader for training
batch_size = 16
data_loader = torch.utils.data.DataLoader(dataset, batch_size=batch_size)
device = "cuda" if torch.cuda.is_available() else "cpu"
for batch in data_loader:
observations = batch["observation.state"].to(device)
actions = batch["action"].to(device)
images = batch["observation.images.front_left"].to(device)
# model.forward(batch)串流資料集(無需下載)
使用 StreamingLeRobotDataset 直接從 Hub 進行迭代,無需本機副本。這允許串流大型資料集,而無需將其下載至磁碟或載入至記憶體,這是新資料集格式的一個關鍵特點。
from lerobot.datasets.streaming_dataset import StreamingLeRobotDataset
repo_id = "yaak-ai/L2D-v3"
dataset = StreamingLeRobotDataset(repo_id) # streams directly from the Hub
影像轉換(Image transforms)
影像轉換是在訓練期間應用於相機影格的資料增強,旨在提高模型的魯棒性與泛化能力。LeRobot 支援多種轉換,包括亮度、對比度、飽和度、色調與銳利度的調整。
在資料集創建/錄製期間使用轉換
目前,轉換 僅在訓練時間 應用,而非在錄製期間。當您創建或錄製資料集時,原始影像是以未經轉換的形式存儲的。這讓您之後可以嘗試不同的增強方式,而無需重新錄製資料。
向現有資料集添加轉換 (API)
載入訓練用資料集時使用 image_transforms 參數:
from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.datasets.transforms import ImageTransforms, ImageTransformsConfig, ImageTransformConfig
# Option 1: Use default transform configuration (disabled by default)
transforms_config = ImageTransformsConfig(
enable=True, # Enable transforms
max_num_transforms=3, # Apply up to 3 transforms per frame
random_order=False, # Apply in standard order
)
transforms = ImageTransforms(transforms_config)
dataset = LeRobotDataset(
repo_id="your-username/your-dataset",
image_transforms=transforms
)
# Option 2: Create custom transform configuration
custom_transforms_config = ImageTransformsConfig(
enable=True,
max_num_transforms=2,
random_order=True,
tfs={
"brightness": ImageTransformConfig(
weight=1.0,
type="ColorJitter",
kwargs={"brightness": (0.7, 1.3)} # Adjust brightness range
),
"contrast": ImageTransformConfig(
weight=2.0, # Higher weight = more likely to be selected
type="ColorJitter",
kwargs={"contrast": (0.8, 1.2)}
),
"sharpness": ImageTransformConfig(
weight=0.5, # Lower weight = less likely to be selected
type="SharpnessJitter",
kwargs={"sharpness": (0.3, 2.0)}
),
}
)
dataset = LeRobotDataset(
repo_id="your-username/your-dataset",
image_transforms=ImageTransforms(custom_transforms_config)
)
# Option 3: Use pure torchvision transforms
from torchvision.transforms import v2
torchvision_transforms = v2.Compose([
v2.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),
v2.GaussianBlur(kernel_size=3, sigma=(0.1, 2.0)),
])
dataset = LeRobotDataset(
repo_id="your-username/your-dataset",
image_transforms=torchvision_transforms
)可用的轉換類型
LeRobot 提供幾種轉換類型:
ColorJitter:調整亮度、對比度、飽和度與色調SharpnessJitter:隨機調整影像銳利度Identity:無轉換(適用於測試)
您也可以直接將任何 torchvision.transforms.v2 轉換傳遞給 image_transforms 參數。
配置選項
enable:啟用/停用轉換(預設:False)max_num_transforms:每影格應用的最大轉換數量(預設:3)random_order:以隨機順序或標準順序應用轉換(預設:False)weight:各轉換的取樣機率(權重越高機率越高;若權重總和不為 1,則會進行正規化)kwargs:轉換特定參數(例如:亮度範圍)
視覺化轉換
使用視覺化腳本來預覽轉換如何影響您的資料:
lerobot-imgtransform-viz \ --repo-id=your-username/your-dataset \ --output-dir=./transform_examples \ --n-examples=5
這會儲存顯示各項轉換效果的範例影像,幫助您調校參數。
最佳實踐
- 從小規模開始:從較小範圍開始(例如:亮度 0.9-1.1)並逐漸增加。
- 先測試:使用視覺化腳本確保轉換看起來合理。
- 監控訓練:若過度劇烈,強大的增強可能會損害效能。
- 符合您的場景:如果您的機器人在變化的光照下運作,請使用亮度/對比度轉換。
- 明智組合:同時使用過多轉換可能會使訓練不穩定。
遷移 v2.1 → v3.0
轉換器會將各章節的文件匯集成較大的分片,並寫入章節偏移量/元數據。請按照以下說明轉換您的資料集。
# Pre-release build with v3 support:
pip install "https://github.com/huggingface/lerobot/archive/33cad37054c2b594ceba57463e8f11ee374fa93c.zip"
# Convert an existing v2.1 dataset hosted on the Hub:
python -m lerobot.datasets.v30.convert_dataset_v21_to_v30 --repo-id=<HF_USER/DATASET_ID>用途
- 匯總 parquet 文件:
episode-0000.parquet,episode-0001.parquet, … →file-0000.parquet, … - 匯總 mp4 文件:
episode-0000.mp4,episode-0001.mp4, … →file-0000.mp4, … - 更新
meta/episodes/*(分塊 Parquet),包含各章節長度、任務、以及位元組/影格偏移量。
常見問題
推送前務必調用 finalize()
在創建或錄製資料集時,您 必須 調用 dataset.finalize() 以正確關閉 parquet 寫入器。詳見 PR #1903。
from lerobot.datasets.lerobot_dataset import LeRobotDataset
# Create dataset and record episodes
dataset = LeRobotDataset.create(...)
for episode in range(num_episodes):
# Record frames
for frame in episode_data:
dataset.add_frame(frame)
dataset.save_episode()
# Call finalize() when done recording and before push_to_hub()
dataset.finalize() # Closes parquet writers, writes metadata footers
dataset.push_to_hub()為什麼這是必要的?
資料集 v3.0 為了效率,使用了帶有緩衝元數據的增量式 parquet 寫入。finalize() 方法會:
- 將緩衝的所有章節元數據刷新至磁碟
- 關閉 parquet 寫入器以寫入頁尾元數據,否則 parquet 文件將損壞
- 確保資料集可以正常載入
若未調用 finalize(),您的 parquet 文件將不完整,資料集也無法正常載入。