LeRobot documentation
言語カラムとレシピ
言語カラムとレシピ
ほとんどのLeRobotデータセットでは、エピソードごとに単一のtask文字列が付属しています。これは短い単一指示のスキルには十分ですが、この分野が進もうとしている長時間ホライズンでマルチモーダルなロボットポリシー(高レベルな計画、メモリ、割り込み、VQA、ツール使用)には不十分です。データセット形式をフォークせずにこれらのポリシーをサポートするために、LeRobotはLeRobotDatasetを2つの任意の言語カラムと、これらの行をオンザフライでチャット形式の学習サンプルに変換する小さなレシピレイヤーで拡張しています。
この設計は、明確に3つのレイヤーに分割できます。
- データセット内のデータ —
data/chunk-*/file-*.parquet内のフレームの隣に保存される言語アノテーションは、2つの任意の列(language_persistentとlanguage_events)として格納されます。これらの列を持たないデータセットは、既存の動作を維持します。 - レシピ — アノテーション行をどのように関連付け、チャットターン(
role、content、任意の画像、任意のツール呼び出し)としてレイアウトするかを宣言する YAML ファイルです。レシピは純粋な設定であり、新しいレシピを追加するために Python は不要です。 - 学習形式 — サンプル時に、
RenderTrainingMessagesStepはレシピをフレームごとのアノテーションと照合して解決し、HF 形式のmessagesと、ポリシープロセッサが消費する LeRobot 固有のサイドカー(message_streams、target_message_indices)を出力します。
このページでは、各レイヤーを順番に説明します。
レイヤー 1 — データセット内の言語カラム
2つの任意の列は、data/chunk-*/file-*.parquet内のフレームデータの隣に配置されています:
language_persistent: エピソード内のすべてのフレームにブロードキャストされる行のリスト。アクティブな状態を保持するために使用されます。例:subtask、plan、memory。language_events: イベントが出力された正確なフレームでのみ存在する行のリスト。例えば、interjection、vqa、および音声ツール呼び出しなど。
両方のカラムは同じ行の形状を共有しています(イベント行はtimestampを省略しますが、これは行が配置されているフレームがすでにそれを提供しているためです):
role: string content: string | null style: string | null timestamp: float32 # persistent rows only camera: string | null # observation.images.* feature key, view-dependent rows only tool_calls: list[Json] | null
camera フィールドは、content が特定のカメラビューに基づいている行をタグ付けします。ビュー依存のスタイル(vqa および trace)の行は、camera を対応する observation.images.* のフィーチャーキーに設定する必要があります。その他のすべてのスタイルの行(ロボットフレームのプリミティブを関節 / デカルト座標で記述する motion を含む)は、camera を null のままにしておく必要があります。パイプラインのライターとバリデータは、validate_camera_field(style, camera) を通じてこれを強制します。
meta/tasks.parquet がタスクの正規ソースであり続けます。特別な${task}レシピバインディングは常にそのタスク文字列を読み取り、言語アノテーションに依存しません。
アーキテクチャ
言語スタック自体には、レイヤー1を支える3つの内部モジュールがあります:
lerobot.datasets.languageは、スキーマ、スタイルレジストリ、およびcolumn_for_styleを定義します。lerobot.datasets.language_renderは行を解決し、メッセージをレンダリングします。RenderTrainingMessagesStepは、データセットのサンプルをmessages、message_streams、およびtarget_message_indicesに変換します。
LeRobotDataset はレシピに依存しません。language_persistent と language_events が存在する場合はそれらをそのまま渡し、アノテーションのないデータセットは既存の動作を維持します。
レイヤー2 — レシピの構造
Recipes は lerobot.datasets.recipe の TrainingRecipe と MessageTurn によって裏付けられた YAML ファイルです。これらは、bindings を介してどのアノテーション行を取得するか、およびそれらをどのようにチャットターン (messages) に構成するかを宣言します。
messages:
- { role: user, content: "${task}", stream: high_level }
- { role: assistant, content: "${subtask}", stream: low_level, target: true }レシピは、サブレシピの重み付きブレンドに枝分かれすることもできます。サンプリング時、サンプルインデックスから決定論的に1つのブランチが選択されるため、Pythonでの配線なしで、異なるフレームが異なる目的(メモリ更新、低レベル実行、VQAなど)を学習できます。
時間的セマンティクス
永続スタイルは、出力された後、置き換えられるまで有効です:
active_at(t, style=subtask)nth_prev(style=memory, offset=1)nth_next(style=subtask, offset=1)
イベントスタイルは、正確なタイムスタンプでのみ存在します:
emitted_at(t, style=interjection)emitted_at(t, style=vqa, role=user, camera=observation.images.top)emitted_at(t, role=assistant, tool_name=say)
完全なイベントマッチングには許容ウィンドウがないため、ライターはparquetデータからのフレームタイムスタンプでイベント行にスタンプを付与する必要があります。
ビュー依存の解像度
ビュー依存スタイル(vqa および trace)では、role= および tool_name= と並行して、camera= フィルターがリゾルバーに追加されます。複数のカメラを持つデータセットでは、通常、同じタイムスタンプでカメラごとに 1 つの (vqa, user) + (vqa, assistant) ペアが出力されます。camera= を指定しないと、これらのリゾルバーは 2 つの一致を検出し、曖昧性エラーを発生させます。レシピでは、各カメラを独自のバインディングと対応する画像ブロックを通じて消費します。例:
ask_vqa_top:
route: vqa
bindings:
vqa_query: "emitted_at(t, style=vqa, role=user, camera=observation.images.top)"
vqa: "emitted_at(t, style=vqa, role=assistant, camera=observation.images.top)"
messages:
- role: user
stream: high_level
if_present: vqa_query
content:
- { type: image, feature: observation.images.top }
- { type: text, text: "${vqa_query}" }
- {
role: assistant,
content: "${vqa}",
stream: high_level,
target: true,
if_present: vqa,
}データセットが記録するカメラごとに、そのようなサブレシピを1つずつ追加します。明示的なroute: vqaマーカーにより、通常の重み付きブレンド選択よりも、一致するスパースなVQAアノテーションが優先的に適用されます。コンポーネント名は単なる説明用です。
レイヤー 3 — トレーニング形式
レンダリングされたサンプルは、HFスタイルのチャットメッセージとLeRobotのサイドカーを使用します:
sample["messages"]
sample["message_streams"]
sample["target_message_indices"]レンダラーはトークナイザーのチャットテンプレートを適用しません。ポリシープロセッサがバックボーン用にメッセージをシリアライズする方法を決定するため、OpenAIスタイルのチャットメッセージを期待するSmolVLA、Pi0.5、および将来のVLM間で同じデータセットを再利用できます。
ブレンド
Blendレシピは、サンプルインデックスから重み付きサブレシピを決定論的に1つ選択します。recipes/subtask_mem.yamlは、コンパクトなコアブレンドを学習します。具体的には、高レベルのサブタスク予測、低レベルの実行、およびメモリです。recipes/subtask_mem_vqa_speech.yamlは、VQAと口頭での割り込み応答も追加した、より完全なバリアントです。
recipes/subtask_joint.yaml は、重み付きブレンドではなく、ジョイントシーケンス学習を示しています。同じサンプルに対して、アシスタントサブタスクはlow_levelストリーム上でテキストクロスエントロピーによって教師信号を与えられ、アクション予測も引き続き有効になります。これはπ0.5論文のジョイント設定と一致しています。現時点では学習専用です。ランタイムは推論時にこのジョイントプレフィックスを再構築する機能はまだ実装されていません。
優雅な不在
両方の言語カラムが欠落している、None、または空の場合、RenderTrainingMessagesStep は利用可能な場合はタスク文字列を低レベルの教師信号として使用し、利用できない場合はサンプルを変更せずにそのままにします。アノテーション付きのサンプルについて、適用されるレシピのブランチがなく、タスクのフォールバックも存在しない場合、レンダリングはNoneを返し、ローダーが別のサンプルを再試行できるようにします。