LeRobot 文件

在 LeRobot 資料集中使用子任務

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

在 LeRobot 資料集中使用子任務

機器人資料集對子任務的支援,已被證實能有效提升機器人的推理與理解能力。子任務特別適用於:

  • 階層式策略 (Hierarchical policies):建立包含子任務預測的策略,以便即時視覺化機器人的推理過程。
  • 獎勵建模 (Reward modeling):協助獎勵模型理解任務進度(例如:SARM 型的階段感知獎勵模型)。
  • 任務分解 (Task decomposition):將複雜的操作任務拆解為原子化、可解釋的步驟。

LeRobotDataset 現在支援將子任務作為其資料集結構的一部分,與任務並列。

什麼是子任務?

任務描述的是整體目標(例如:「撿起蘋果並放入籃子」),那麼子任務則是將執行過程拆解為更細緻的步驟:

  1. 「接近蘋果」
  2. 「抓取蘋果」
  3. 「抬起蘋果」
  4. 「移動至籃子」
  5. 「釋放蘋果」

資料集中的每一幀都可以標註其對應的子任務,使模型能夠學習並預測這些中間階段。

An overview of subtask annotation showing how frames are labeled with intermediate subtask stages

圖:子任務標註概覽。

參考資料: 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

完成標註後:

  1. 點擊「Push to Hub」即可上傳您的標註資料集。
  2. 您也可以按照 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_logits

2. 階段感知獎勵建模 (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, progress

3. 進度視覺化

透過追蹤子任務進度來監控機器人的執行狀況。

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 自然語言的子任務描述

相關資源

在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.