LeRobot documentation
Kolom bahasa dan resep
Kolom bahasa dan resep
Sebagian besar dataset LeRobot menyertakan satu string task per episode — cukup untuk keterampilan singkat dengan instruksi tunggal, tetapi tidak memadai untuk kebijakan robot ber-horizon panjang dan multi-modal yang menjadi arah perkembangan bidang ini (perencanaan tingkat tinggi, memori, interupsi, VQA, penggunaan alat). Untuk mendukung kebijakan tersebut tanpa mem-fork format dataset, LeRobot memperluas LeRobotDataset dengan dua kolom bahasa opsional dan lapisan resep kecil yang mengubah baris-baris tersebut menjadi sampel pelatihan bergaya chat secara langsung.
Desainnya terbagi dengan jelas menjadi tiga lapisan:
- Data dalam dataset — anotasi bahasa yang disimpan di samping frame dalam
data/chunk-*/file-*.parquetsebagai dua kolom opsional (language_persistentdanlanguage_events). Dataset tanpa kolom-kolom ini mempertahankan perilaku yang ada. - Resep — file YAML yang menyatakan baris anotasi mana yang akan diikat dan bagaimana menyusunnya sebagai giliran chat (
role,content, gambar opsional, panggilan tool opsional). Resep adalah konfigurasi murni; tidak diperlukan Python untuk menambahkan resep baru. - Format pelatihan — pada saat pengambilan sampel,
RenderTrainingMessagesStepmenyelesaikan resep terhadap anotasi per-frame dan mengeluarkanmessagesbergaya HF beserta sidecar khusus LeRobot (message_streams,target_message_indices) yang dikonsumsi oleh pemroses kebijakan.
Halaman ini menjelaskan setiap lapisan secara berurutan.
Lapisan 1 — kolom bahasa dalam dataset
Dua kolom opsional ini berada di samping data frame di data/chunk-*/file-*.parquet:
language_persistent: daftar baris yang disiarkan ke setiap frame dalam episode untuk status yang tetap aktif, sepertisubtask,plan, danmemory.language_events: daftar baris hanya pada frame persis di mana sebuah event dipancarkan, sepertiinterjection,vqa, dan panggilan speech tool.
Kedua kolom berbagi bentuk baris yang sama (baris event mengabaikan timestamp karena
frame tempat baris tersebut berada sudah menyediakannya):
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
Bidang camera memberi tag pada baris yang content-nya berakar pada tampilan kamera tertentu. Baris dari gaya yang bergantung pada tampilan (vqa dan trace) WAJIB mengatur camera ke kunci fitur observation.images.* yang sesuai. Baris dari semua gaya lainnya — termasuk motion, yang menjelaskan primitif bingkai robot dalam istilah sendi / Kartesius — WAJIB membiarkan camera sebagai null. Penulis pipeline dan validator menegakkan hal ini melalui validate_camera_field(style, camera).
meta/tasks.parquet tetap menjadi sumber kanonik untuk tugas tersebut. Binding resep khusus ${task} selalu membaca string tugas itu dan tidak bergantung pada anotasi bahasa.
Arsitektur
Stack bahasa itu sendiri memiliki tiga modul internal yang mendukung lapisan 1:
lerobot.datasets.languagemendefinisikan skema, registri gaya, dancolumn_for_style.lerobot.datasets.language_rendermenyelesaikan baris dan merender pesan.RenderTrainingMessagesStepmengubah sampel dataset menjadimessages,message_streams, dantarget_message_indices.
LeRobotDataset tetap tidak bergantung pada resep. Ia meneruskan language_persistent dan language_events saat ada, dan dataset tanpa anotasi mempertahankan perilaku yang ada.
Lapisan 2 — anatomi resep
Recipes adalah file YAML yang didukung oleh TrainingRecipe dan MessageTurn dari lerobot.datasets.recipe. Mereka
menyatakan baris anotasi mana yang akan diambil (melalui bindings) dan bagaimana menyusunnya
menjadi giliran chat (messages).
messages:
- { role: user, content: "${task}", stream: high_level }
- { role: assistant, content: "${subtask}", stream: low_level, target: true }Resep juga dapat bercabang menjadi blend berbobot dari sub-resep. Pada waktu pengambilan sampel, tepat satu cabang dipilih secara deterministik dari indeks sampel, sehingga frame yang berbeda melatih tujuan yang berbeda (misalnya pembaruan memori vs. eksekusi tingkat rendah vs. VQA) tanpa perlu pengkabelan Python.
Semantik temporal
Gaya persisten aktif setelah emisi hingga diganti:
active_at(t, style=subtask)nth_prev(style=memory, offset=1)nth_next(style=subtask, offset=1)
Gaya event hanya ada pada timestamp persisnya:
emitted_at(t, style=interjection)emitted_at(t, style=vqa, role=user, camera=observation.images.top)emitted_at(t, role=assistant, tool_name=say)
Pencocokan peristiwa yang persis tidak memiliki jendela toleransi, sehingga penulis harus memberi cap baris peristiwa dengan stempel waktu bingkai dari data parquet.
Resolusi yang bergantung pada tampilan
Untuk gaya yang bergantung pada tampilan (vqa dan trace), resolver memperoleh filter camera= yang sejajar dengan role= dan tool_name=. Dataset dengan beberapa kamera biasanya mengeluarkan satu pasangan (vqa, user) + (vqa, assistant) per kamera pada timestamp yang sama; tanpa camera=, resolver tersebut melihat dua kecocokan dan memicu error ambiguitas. Resep mengonsumsi setiap kamera melalui binding-nya sendiri beserta blok gambar yang sesuai, misalnya
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,
}Tambahkan satu sub-resep seperti itu untuk setiap kamera yang direkam oleh dataset. Penanda eksplisit route: vqa membuat anotasi VQA sparse yang cocok memiliki prioritas di atas pemilihan blend berbobot normal; nama komponen bersifat deskriptif murni.
Lapisan 3 — format pelatihan
Contoh yang dirender menggunakan pesan chat bergaya HF plus sidecar LeRobot:
sample["messages"]
sample["message_streams"]
sample["target_message_indices"]Renderer tidak menerapkan template chat tokenizer. Prosesor kebijakan menentukan cara untuk menserikan pesan untuk backbone mereka, yang membuat dataset yang sama tetap dapat digunakan di SmolVLA, Pi0.5, dan VLM masa depan mana pun yang mengharapkan pesan chat bergaya OpenAI.
Blends
Resep blend memilih satu sub-resep berbobot secara deterministik dari indeks sampel. recipes/subtask_mem.yaml melatih inti blend yang ringkas — prediksi subtask tingkat tinggi, eksekusi tingkat rendah, dan memori. recipes/subtask_mem_vqa_speech.yaml adalah varian yang lebih lengkap, yang juga menambahkan respons VQA dan interupsi lisan.
recipes/subtask_joint.yaml mendemonstrasikan pelatihan urutan gabungan, bukan campuran berbobot. Untuk sampel yang sama, subtask asistennya diawasi dengan cross-entropy teks pada stream low_level sementara prediksi aksi tetap aktif, sesuai dengan setup gabungan dari paper π0.5. Saat ini hanya untuk pelatihan: runtime belum dapat membangun ulang prefix gabungan ini saat inferensi.
Kehilangan yang anggun
Jika kedua kolom bahasa tidak ada, None, atau kosong, RenderTrainingMessagesStep menggunakan string tugas sebagai supervisi tingkat rendah jika tersedia, dan jika tidak, sampel dibiarkan tanpa perubahan. Untuk sampel yang telah di anotasi, jika tidak ada cabang resep yang berlaku dan tidak ada fallback tugas, rendering mengembalikan None, sehingga loader dapat mencoba sampel lain.