LeRobot 文件
在 LeRobot 資料集中使用子任務
並獲得增強的文件體驗
開始使用
在 LeRobot 資料集中使用子任務
機器人資料集對子任務的支援,已被證實能有效提升機器人的推理與理解能力。子任務特別適用於:
- 階層式策略 (Hierarchical policies):建立包含子任務預測的策略,以便即時視覺化機器人的推理過程。
- 獎勵建模 (Reward modeling):協助獎勵模型理解任務進度(例如:SARM 型的階段感知獎勵模型)。
- 任務分解 (Task decomposition):將複雜的操作任務拆解為原子化、可解釋的步驟。
LeRobotDataset 現在支援將子任務作為其資料集結構的一部分,與任務並列。
什麼是子任務?
若任務描述的是整體目標(例如:「撿起蘋果並放入籃子」),那麼子任務則是將執行過程拆解為更細緻的步驟:
- 「接近蘋果」
- 「抓取蘋果」
- 「抬起蘋果」
- 「移動至籃子」
- 「釋放蘋果」
資料集中的每一幀都可以標註其對應的子任務,使模型能夠學習並預測這些中間階段。
圖:子任務標註概覽。
參考資料: Subtask-learning based for robot self-assembly in flexible collaborative assembly in manufacturing,原始文章,發表於 2022 年 4 月 19 日。
資料集結構
子任務資訊儲存在資料集的中繼資料 (metadata) 中。
my-dataset/
├── data/
│ └── ...
├── meta/
│ ├── info.json
│ ├── stats.json
│ ├── tasks.parquet
│ ├── subtasks.parquet # Subtask index → subtask string mapping
│ └── episodes/
│ └── ...
└── videos/
└── ...Subtasks Parquet 檔案
meta/subtasks.parquet 檔案將子任務索引對應至其自然語言描述。
| subtask_index | subtask(索引欄位) |
|---|---|
| 0 | 「接近蘋果」 |
| 1 | 「抓取蘋果」 |
| 2 | 「抬起蘋果」 |
| … | … |
幀級標註
資料集中的每一幀都可以包含一個 subtask_index 欄位,用以參照 subtasks parquet 檔案。
# Example frame data in the parquet file
{
"index": 42,
"timestamp": 1.4,
"episode_index": 0,
"task_index": 0,
"subtask_index": 2, # References "Lift the apple"
"observation.state": [...],
"action": [...],
}為資料集標註子任務
我們提供了一個 HuggingFace Space,讓您可以輕鬆地為任何 LeRobotDataset 標註子任務。
https://huggingface.co/spaces/lerobot/annotate
完成標註後:
- 點擊「Push to Hub」即可上傳您的標註資料集。
- 您也可以按照 github.com/huggingface/lerobot-annotate 的說明,在本地執行標註工具。
載入包含子任務的資料集
當您載入包含子任務標註的資料集時,子任務資訊將會自動可用。
from lerobot.datasets.lerobot_dataset import LeRobotDataset
# Load a dataset with subtask annotations
dataset = LeRobotDataset("jadechoghari/collect-fruit-annotated")
# Access a sample
sample = dataset[100]
# The sample includes both task and subtask information
print(sample["task"]) # "Collect the fruit"
print(sample["subtask"]) # "Grasp the apple"
print(sample["task_index"]) # tensor(0)
print(sample["subtask_index"]) # tensor(2)檢查子任務支援
您可以檢查資料集是否具備子任務標註。
# Check if subtasks are available
has_subtasks = (
"subtask_index" in dataset.features
and dataset.meta.subtasks is not None
)
if has_subtasks:
print(f"Dataset has {len(dataset.meta.subtasks)} unique subtasks")
print("Subtasks:", list(dataset.meta.subtasks.index))使用子任務進行訓練
配合分詞處理器 (Tokenizer Processor)
TokenizerProcessor 會自動處理視覺-語言行動 (VLA) 模型的子任務分詞。
from lerobot.processor.tokenizer_processor import TokenizerProcessor
from lerobot.processor.pipeline import ProcessorPipeline
# Create a tokenizer processor
tokenizer_processor = TokenizerProcessor(
tokenizer_name_or_path="google/paligemma-3b-pt-224",
padding="max_length",
max_length=64,
)
# The processor will automatically tokenize subtasks if present in the batch
# and add them to the observation under:
# - "observation.subtask.tokens"
# - "observation.subtask.attention_mask"當批次中存在子任務時,分詞處理器會加入:
observation.subtask.tokens:已分詞的子任務文字observation.subtask.attention_mask:子任務 Token 的注意力遮罩 (Attention mask)
使用子任務的 DataLoader
import torch
from lerobot.datasets.lerobot_dataset import LeRobotDataset
dataset = LeRobotDataset("jadechoghari/collect-fruit-annotated")
dataloader = torch.utils.data.DataLoader(
dataset,
batch_size=16,
shuffle=True,
)
for batch in dataloader:
# Access subtask information in the batch
subtasks = batch["subtask"] # List of subtask strings
subtask_indices = batch["subtask_index"] # Tensor of subtask indices
# Use for training hierarchical policies or reward models
print(f"Batch subtasks: {set(subtasks)}")帶有子任務標註的資料集範例
嘗試載入帶有子任務標註的資料集
from lerobot.datasets.lerobot_dataset import LeRobotDataset
# Example dataset with subtask annotations
dataset = LeRobotDataset("jadechoghari/collect-fruit-annotated")
# Explore the subtasks
print("Available subtasks:")
for subtask_name in dataset.meta.subtasks.index:
print(f" - {subtask_name}")
# Get subtask distribution
subtask_counts = {}
for i in range(len(dataset)):
sample = dataset[i]
subtask = sample["subtask"]
subtask_counts[subtask] = subtask_counts.get(subtask, 0) + 1
print("\nSubtask distribution:")
for subtask, count in sorted(subtask_counts.items(), key=lambda x: -x[1]):
print(f" {subtask}: {count} frames")使用案例
1. 階層式策略訓練
訓練同時預測動作與目前子任務的策略。
class HierarchicalPolicy(nn.Module):
def __init__(self, num_subtasks):
super().__init__()
self.action_head = nn.Linear(hidden_dim, action_dim)
self.subtask_head = nn.Linear(hidden_dim, num_subtasks)
def forward(self, observations):
features = self.encoder(observations)
actions = self.action_head(features)
subtask_logits = self.subtask_head(features)
return actions, subtask_logits2. 階段感知獎勵建模 (SARM)
建立能理解任務進度的獎勵模型。
# SARM predicts:
# - Stage: Which subtask is being executed (discrete)
# - Progress: How far along the subtask (continuous 0-1)
class SARMRewardModel(nn.Module):
def forward(self, observations):
features = self.encoder(observations)
stage_logits = self.stage_classifier(features)
progress = self.progress_regressor(features)
return stage_logits, progress3. 進度視覺化
透過追蹤子任務進度來監控機器人的執行狀況。
def visualize_execution(model, observations):
for t, obs in enumerate(observations):
action, subtask_logits = model(obs)
predicted_subtask = subtask_names[subtask_logits.argmax()]
print(f"t={t}: Executing '{predicted_subtask}'")API 參考
LeRobotDataset 屬性
| 屬性 | 類型 | 說明 |
|---|---|---|
meta.subtasks | pd.DataFrame \| None | 將子任務名稱對應至索引的 DataFrame |
features["subtask_index"] | dict | 若存在,則為 subtask_index 的特徵規格 (Feature spec) |
樣本鍵 (Sample Keys)
當子任務可用時,每個樣本包含:
| 金鑰 | 類型 | 說明 |
|---|---|---|
subtask_index | torch.Tensor | 目前子任務的整數索引 |
subtask | str | 自然語言的子任務描述 |
相關資源
- SARM 論文 - 長時程機器人操作的階段感知獎勵建模
- LeRobot 標註 Space - 互動式標註工具
- LeRobotDataset v3.0 - 資料集格式文件