LeRobot documentation
SARM: Pemodelan Hadiah yang Mengetahui Tahap
SARM: Pemodelan Hadiah yang Mengetahui Tahap
SARM (Stage-Aware Reward Modeling) adalah kerangka pemodelan reward berbasis video untuk tugas manipulasi robot jangka panjang. Panduan ini membahas cara melatih model reward SARM dan, secara opsional, menggunakannya dengan Reward-Aligned Behavior Cloning (RA-BC).
Makalah: SARM: Stage-Aware Reward Modeling for Long Horizon Robot Manipulation
Mengapa Model Reward?
Behavior cloning standar memperlakukan semua frame demonstrasi secara setara, tetapi dataset robot di dunia nyata bersifat berantakan. Dataset tersebut mengandung keraguan, koreksi, dan trajektori dengan kualitas yang bervariasi. Model reward menyelesaikan masalah ini dengan mempelajari konsep progres tugas yang dapat digeneralisasi dari demonstrasi: diberikan frame video dan deskripsi tugas, model memprediksi seberapa dekat robot dalam menyelesaikan tugas (0→1). Sinyal “progres” yang dipelajari ini dapat digunakan dengan berbagai cara, dua aplikasi yang menjanjikan adalah: (1) weighted imitation learning (RA-BC), di mana frame dengan progres tinggi menerima bobot lebih besar selama pelatihan kebijakan, dan (2) reinforcement learning, di mana model reward menyediakan reward padat untuk perbaikan kebijakan secara online atau offline.
Ikhtisar
SARM memiliki fitur-fitur berikut:
- Arsitektur yang sadar tahap: Memprediksi secara bersama-sama tahap tugas tingkat tinggi dan kemajuan terperinci di dalam setiap tahap
- Anotasi subtask: Menggunakan anotasi subtask dalam bahasa alami untuk menurunkan label progres yang konsisten
- Proporsi temporal: Menghitung prior pada tingkat dataset (α̅_k) untuk setiap subtask guna menormalisasi kemajuan di antara demonstrasi dengan panjang yang bervariasi
SARM melatih pada target stage+tau yang ringkas untuk setiap frame:
- stage: indeks stage integer
k ∈ {0, ..., K-1} - τ (tau): kemajuan dalam tahap
τ ∈ [0, 1] - target encoding:
y = k + τ(ini adalah apa yang dihasilkan oleh pemroses dataset)
Pada saat inferensi (dan dalam RA-BC turunan), SARM mengonversi nilai mentah k + τ menjadi progres ternormalisasi dalam [0, 1] menggunakan proporsi temporal tingkat dataset α̅_k (disimpan di meta/temporal_proportions_*.json).
Ini sesuai dengan Rumus (2) dari makalah:
progress_t = P_{k-1} + α̅_k × τ_tDi mana:
τ_t = (t - s_k) / (e_k - s_k)adalah waktu ternormalisasi dalam subtaskP_{k-1}adalah kumulatif sebelumnya (jumlah proporsi subtask sebelumnya)α̅_kadalah proporsi temporal untuk subtask k
Hal ini memastikan bahwa status tugas yang identik dipetakan ke nilai progres yang konsisten, bahkan di antara demonstrasi dengan panjang yang berbeda.
Input dan Target (Apa yang diharapkan kode baru)
SARM dilatih melalui prosesor-nya (src/lerobot/rewards/sarm/processor_sarm.py), yang:
- Mengodekan gambar dan teks tugas dengan CLIP (ViT-B/32) menjadi
video_featuresdantext_features - Menambahkan padding/memotong status robot menjadi
state_features(hinggamax_state_dim) - Membangun target sebagai
sparse_targets(dandense_targetsdalamdense_only/dual) menggunakan enkoding stage+tauy = k + τ - Masks memutar ulang frame menggunakan tensor
lengthsper sampel (rewind adalah augmentasi saat pelatihan)
Setidaknya, setiap sampel pelatihan membutuhkan:
task(string): deskripsi tugas- gambar
reward_model.image_keydan statereward_model.state_keydari dataset
Mode Anotasi
Anda dapat memilih dari 3 mode anotasi yang menentukan bagaimana label progres dihitung:
| Mode | Anotasi Diperlukan | Kepala | Kasus Penggunaan |
|---|---|---|---|
single_stage | None | Hanya Sparse | Tugas sederhana, eksperimen cepat, tidak perlu VLM |
dense_only | Dense (VLM) | Dual (sparse auto-generated) | Pelacakan subtask terperinci tanpa mendefinisikan tahap tingkat tinggi |
dual | Sparse + Dense (VLM) | Dual | Setup lengkap paper SARM dengan kedua granularitas |
Mode Detail
Tidak diperlukan anotasi. Seluruh episode diperlakukan sebagai satu tahap yang disebut "task", dan progresnya linear dari 0 hingga 1 selama durasi episode.
- Head sparse: 1 tahap (“task”), progres linear
- Dense head: Tidak digunakan
- Paling cocok untuk: Tugas sederhana, eksperimen cepat, atau ketika anotasi VLM tidak tersedia
Siapkan Lingkungan Anda
- Install LeRobot dengan mengikuti Panduan Instalasi kami.
- Instal dependensi SARM dengan menjalankan:
pip install -e ".[sarm]"Alur kerja:
1. Train SARM → 2. Visualize predictions → 3. (Optional) Train policy with RA-BCHanya anotasi padat (halus) dari VLM. Kepala spars secara otomatis menggunakan satu tahap "task" yang mencakup seluruh episode, sementara kepala padat mempelajari kemajuan subtask yang terperinci.
- Sparse head: 1 tahap (“task”), progres linear (dibuat otomatis)
- Head padat: Beberapa tahap bergranularitas halus dari anotasi VLM
- Paling cocok untuk: Ketika Anda ingin pelacakan subtask yang detail tetapi tidak perlu mendefinisikan tahap tingkat tinggi
Alur kerja:
1. Annotate (dense) → 2. Verify → 3. Train SARM → 4. Visualize → 5. (Optional) Train policy with RA-BCKedua anotasi sparse dan dense dari VLM. Mode dual-head penuh seperti yang dijelaskan dalam paper SARM, dengan prediksi tahap high-level (sparse) dan fine-grained (dense).
- Head sparse: Tahapan tingkat tinggi dari anotasi VLM
- Head padat: Tahapan terperinci dari anotasi VLM
- Paling cocok untuk: Tugas multi-tahap kompleks di mana kedua granularitas berguna
Alur kerja:
1. Annotate (sparse+dense) → 2. Verify → 3. Train SARM → 4. Visualize → 5. (Optional) Train policy with RA-BCLangkah 1: Anotasi Subtugas
Tidak perlu anotasi! Lewati langkah ini sepenuhnya. Model akan menggunakan deskripsi tugas episode dan menghitung kemajuan linear secara otomatis.
Generate hanya anotasi padat (halus) menggunakan VLM. Tahap jarang akan dibuat secara otomatis.
python src/lerobot/data_processing/sarm_annotations/subtask_annotation.py \
--repo-id your-username/your-dataset \
--dense-only \
--dense-subtasks "Bring robot arms up from starting position,Grab near side and do 1st fold,Grab side and do 2nd fold,Grab side and do 3rd fold to finish folding" \
--video-key observation.images.base \
--num-workers 4 \
--push-to-hubYang disimpan:
meta/temporal_proportions_sparse.json- Proporsi sparse yang dibuat otomatis ({"task": 1.0})meta/temporal_proportions_dense.json- Proporsi temporal padat- Kolom per episode di
episodes/*.parquet:dense_subtask_names,dense_subtask_start_frames,dense_subtask_end_frames- (juga kolom berbasis waktu:
dense_subtask_start_times,dense_subtask_end_times)
Buat kedua anotasi sparse (tingkat tinggi) dan dense (halus) menggunakan VLM.
python src/lerobot/data_processing/sarm_annotations/subtask_annotation.py \
--repo-id your-username/your-dataset \
--sparse-subtasks "Bring arms up from starting position,Fold the towel (3 folds in total)" \
--dense-subtasks "Bring robot arms up from starting position,Grab near side and do 1st fold,Grab side and do 2nd fold,Grab side and do 3rd fold to finish folding" \
--video-key observation.images.base \
--num-workers 4 \
--push-to-hubYang disimpan:
meta/temporal_proportions_sparse.json- Proporsi temporal sparsemeta/temporal_proportions_dense.json- Proporsi temporal padat- Kolom per episode di
episodes/*.parquet:sparse_subtask_names,sparse_subtask_start_frames,sparse_subtask_end_framesdense_subtask_names,dense_subtask_start_frames,dense_subtask_end_frames- (juga kolom berbasis waktu:
*_subtask_start_times,*_subtask_end_times)
Argumen Anotasi
| Argumen | Deskripsi |
|---|---|
--repo-id | ID repositori dataset HuggingFace |
--sparse-subtasks | Daftar nama subtask tingkat tinggi yang dipisahkan koma |
--dense-subtasks | Daftar nama subtask yang terperinci, dipisahkan oleh koma |
--dense-only | Hanya buat anotasi padat (otomatis membuat tahap “task” yang jarang) |
--video-key | Kunci kamera/video yang digunakan (misalnya, observation.images.top) |
--num-workers | Jumlah worker GPU paralel (default: 1) |
--episodes | Indeks episode spesifik untuk di anotasi (default: semua) |
--skip-existing | Lewati episode yang sudah memiliki anotasi |
--model | Model VLM (default: Qwen/Qwen3-VL-30B-A3B-Instruct) |
--num-visualizations | Jumlah episode untuk divisualisasikan setelah anotasi (default: 5, atur ke 0 untuk dilewati) |
Catatan: Setelah anotasi selesai, 5 episode secara otomatis divisualisasikan secara default. Gunakan
--num-visualizations 0untuk melewati langkah ini.
Langkah 2: Verifikasi Anotasi
Tidak perlu verifikasi! Lewati langkah ini.
Visualisasikan anotasi menggunakan flag --visualize-only:
python src/lerobot/data_processing/sarm_annotations/subtask_annotation.py \ --repo-id your-username/your-dataset \ --visualize-only \ --visualize-type dense \ --num-visualizations 5 \ --video-key observation.images.base \ --output-dir ./subtask_viz
Visualisasikan anotasi menggunakan flag --visualize-only:
python src/lerobot/data_processing/sarm_annotations/subtask_annotation.py \ --repo-id your-username/your-dataset \ --visualize-only \ --visualize-type both \ --num-visualizations 5 \ --video-key observation.images.base \ --output-dir ./subtask_viz
Ini menghasilkan visualisasi yang menampilkan bingkai video dengan batas subtask yang ditumpangkan serta linimasa subtask.
Argumen Visualisasi
| Argumen | Deskripsi |
|---|---|
--visualize-only | Hanya visualisasi anotasi yang sudah ada (tanpa generasi) |
--num-visualizations | Jumlah episode untuk divisualisasikan (default: 5) |
--visualize-type | Jenis anotasi yang akan divisualisasikan: sparse, dense, atau both |
Tips: Jika anotasi tidak akurat, sesuaikan deskripsi subtask Anda agar lebih spesifik dan jalankan ulang.
Langkah 3: Latih SARM
Latih dengan tanpa anotasi - menggunakan progres linear dari 0 ke 1:
lerobot-train \
--dataset.repo_id=your-username/your-dataset \
--reward_model.type=sarm \
--reward_model.annotation_mode=single_stage \
--reward_model.image_key=observation.images.base \
--output_dir=outputs/train/sarm_single \
--batch_size=32 \
--steps=5000 \
--trackio.enable=true \
--trackio.project=sarm \
--reward_model.repo_id=your-username/your-model-nameLatih dengan hanya anotasi padat (auto-generated yang jarang):
lerobot-train \
--dataset.repo_id=your-username/your-dataset \
--reward_model.type=sarm \
--reward_model.annotation_mode=dense_only \
--reward_model.image_key=observation.images.base \
--output_dir=outputs/train/sarm_dense \
--batch_size=32 \
--steps=5000 \
--trackio.enable=true \
--trackio.project=sarm \
--reward_model.repo_id=your-username/your-model-nameLatih dengan kedua anotasi sparse dan dense:
lerobot-train \
--dataset.repo_id=your-username/your-dataset \
--reward_model.type=sarm \
--reward_model.annotation_mode=dual \
--reward_model.image_key=observation.images.base \
--output_dir=outputs/train/sarm_dual \
--batch_size=32 \
--steps=5000 \
--trackio.enable=true \
--trackio.project=sarm \
--reward_model.repo_id=your-username/your-model-namePelatihan Multi-GPU
Tambahkan accelerate launch --multi_gpu --num_processes=4 untuk menggunakan beberapa GPU dalam pelatihan.
Argumen Pelatihan
| Argumen | Deskripsi | Default |
|---|---|---|
--reward_model.annotation_mode | single_stage, dense_only, atau dual | single_stage |
--reward_model.image_key | Kunci kamera untuk gambar | observation.images.top |
--reward_model.state_key | Kunci untuk keadaan bersama | observation.state |
--reward_model.n_obs_steps | Langkah riwayat observasi (total frame obs = n_obs_steps + 1) | 8 |
--reward_model.frame_gap | Gap (dalam frame) antara observasi yang disampelkan (pada 30 fps: 30 ≈ 1 detik) | 30 |
Langkah 4: Visualisasi Prediksi
Gunakan compute_rabc_weights.py dengan --visualize-only untuk memvisualisasikan prediksi model (dan, jika tersedia, target yang diturunkan dari anotasi) tanpa menulis file parquet.
python -m lerobot.rewards.sarm.compute_rabc_weights \ --dataset-repo-id your-username/your-dataset \ --reward-model-path your-username/sarm-model \ --visualize-only \ --num-visualizations 5 \ --head-mode sparse \ --output-dir ./sarm_viz
python -m lerobot.rewards.sarm.compute_rabc_weights \ --dataset-repo-id your-username/your-dataset \ --reward-model-path your-username/sarm-model \ --visualize-only \ --num-visualizations 5 \ --head-mode dense \ --output-dir ./sarm_viz
python -m lerobot.rewards.sarm.compute_rabc_weights \ --dataset-repo-id your-username/your-dataset \ --reward-model-path your-username/sarm-model \ --visualize-only \ --num-visualizations 5 \ --head-mode both \ --output-dir ./sarm_viz
Visualisasi menunjukkan:
- Plot progres: Progres yang diprediksi (dan “GT” opsional yang diturunkan dari anotasi jika tersedia dan
--stride 1) - Probabilitas tahap: Plot area bertumpuk dari probabilitas tahap yang diprediksi
- Frame sampel: Frame kunci dari episode dengan label progres/tahap
Argumen Visualisasi
| Argumen | Deskripsi |
|---|---|
--visualize-only | Hanya visualisasikan prediksi (tanpa komputasi RABC) |
--num-visualizations | Jumlah episode untuk divisualisasikan (default: 5) |
--head-mode | Kepala SARM yang akan digunakan: sparse, dense, atau both |
--stride | Hitung setiap N frame, sisanya diinterpolasi (default: 1) |
Langkah 5 (Opsional): Latih Policy dengan RA-BC
Reward-Aligned Behavior Cloning (RA-BC) menggunakan model SARM yang telah dilatih untuk memberikan bobot pada sampel pelatihan berdasarkan peningkatan progres yang diprediksi. Hal ini memerlukan dua langkah:
- Hitung nilai progres untuk semua frame menggunakan model SARM yang telah dilatih
- Latih kebijakan dengan pembobotan RA-BC menggunakan nilai yang telah dihitung sebelumnya
Cara Kerja RA-BC
Untuk setiap sampel pelatihan, RA-BC menghitung delta progres:
r_i = φ(o_{t+Δ}) - φ(o_t)Di mana φ adalah prediksi kemajuan SARM dan Δ adalah chunk_size dari kebijakan. Sampel dengan kemajuan positif (demonstrasi yang baik) mendapatkan bobot lebih tinggi, sedangkan sampel dengan kemajuan negatif atau nol mendapatkan bobot yang lebih rendah.
Penimbangan mengikuti Persamaan 8-9 dari makalah:
- Berat lunak:
w̃_i = clip((r_i − (μ − 2σ)) / (4σ + ε), 0, 1) - Bobot akhir:
w_i = 𝟙{r_i > κ} + 𝟙{0 ≤ r_i ≤ κ} × w̃_i
Langkah 5a: Hitung Nilai Progres SARM
Pertama, jalankan model SARM pada semua frame dalam dataset Anda untuk menghitung nilai progres:
python -m lerobot.rewards.sarm.compute_rabc_weights \ --dataset-repo-id your-username/your-dataset \ --reward-model-path your-username/sarm-model \ --head-mode sparse \ --num-visualizations 5 \ --push-to-hub
Skrip ini:
- Memproses semua frame dan menghitung nilai progres
- Menyimpan nilai progres ke file parquet di samping dataset di disk (default ke
<dataset_root>/sarm_progress.parquet) - Membuat visualisasi dari N episode pertama (default: 5)
Argumen:
| Argumen | Deskripsi | Default |
|---|---|---|
--reward-model-path | Path ke model SARM yang telah dilatih | (wajib) |
--head-mode | Kepala SARM yang akan digunakan: sparse, dense, atau both | sparse |
--device | Perangkat untuk inferensi | cuda |
--visualize-only | Hanya visualisasikan prediksi (tanpa komputasi RA-BC) | false |
--num-visualizations | Jumlah episode untuk divisualisasikan (default: 5, set ke 0 untuk dilewati) | 5 |
Format output (sarm_progress.parquet):
| Kolom | Deskripsi |
|---|---|
index | Indeks frame global dalam dataset |
episode_index | Nomor episode |
frame_index | Indeks frame lokal dalam episode |
progress_sparse | Nilai kemajuan kepala sparse [0, 1] |
progress_dense | Nilai progres head dense [0, 1] (jika dihitung) |
Langkah 5b: Latih Kebijakan dengan RA-BC
Setelah Anda memiliki file progres, latih kebijakan Anda dengan pembobotan RA-BC. File progres akan terdeteksi secara otomatis dari path dataset (sarm_progress.parquet) jika tidak diberikan secara eksplisit. Saat ini PI0, PI0.5 dan SmolVLA didukung dengan RA-BC:
lerobot-train \ --dataset.repo_id=your-username/your-dataset \ --policy.type=pi0 \ --sample_weighting.type=rabc \ --sample_weighting.head_mode=sparse \ --sample_weighting.kappa=0.01 \ --output_dir=outputs/train/policy_rabc \ --batch_size=32 \ --steps=40000
Skrip pelatihan secara otomatis:
- Memuat nilai progres yang telah dihitung sebelumnya dari file parquet
- Menggunakan
chunk_sizekebijakan untuk menghitung delta kemajuan (Δ) - Menghitung bobot sampel berdasarkan peningkatan progres
- Menerapkan kerugian berbobot selama pelatihan
Argumen RA-BC:
| Argumen | Deskripsi | Default |
|---|---|---|
--sample_weighting.type | Jenis strategi pembobotan (rabc atau uniform) | rabc |
--sample_weighting.progress_path | Path ke file parquet progres | sarm_progress.parquet |
--sample_weighting.head_mode | Kepala SARM mana yang progresnya akan digunakan: sparse atau dense | sparse |
--sample_weighting.kappa | Ambang batas κ untuk sampel berkualitas tinggi | 0.01 |
--sample_weighting.epsilon | Konstanta kecil untuk stabilitas numerik | 1e-6 |
Menyetel RA-BC Kappa
Parameter kappa adalah ambang batas yang menentukan sampel mana yang mendapatkan bobot penuh (w=1). Memahami cara menyetelnya sangat penting agar RA-BC dapat bekerja secara efektif.
Cara kerja pembobotan:
| Kondisi | Bobot |
|---|---|
delta > kappa | 1.0 (ambang keras) |
0 ≤ delta ≤ kappa | Bobot lunak dari Persamaan 8 |
delta < 0 | 0.0 (progres negatif) |
Mendiagnosis masalah kappa:
Pantau metrik Trackio ini selama pelatihan:
| Metrik | Rentang Sehat | Indikator Masalah |
|---|---|---|
sample_weight_mean_weight | 0.3 - 0.8 | ≈ 1.0 berarti kappa terlalu rendah |
sample_weighting/delta_mean | > 0 | Harus bernilai positif |
sample_weighting/delta_std | > 0 | Variasi dalam kualitas data |
Jika sample_weight_mean_weight ≈ 1.0: kappa Anda terlalu rendah. Sebagian besar sampel memiliki delta > kappa dan melewati soft-weighting sepenuhnya. RA-BC menjadi setara dengan vanilla BC.
Menetapkan kappa berdasarkan data Anda:
Nilai default kappa=0.01 telah disetel untuk tugas melipat kemeja T dalam makalah tersebut (episode ~90 detik pada 30fps). Untuk dataset Anda, periksa nilai sample_weighting/delta_mean dan sample_weighting/delta_std yang tercatat:
# If delta_mean ≈ 0.03 and delta_std ≈ 0.02:
# Most deltas fall in range [0.01, 0.05]
# Option 1: Set kappa = delta_mean (medium selectivity)
--sample_weighting.kappa=0.03
# Option 2: Set kappa = delta_mean + delta_std (high selectivity)
--sample_weighting.kappa=0.05
# Option 3: Set kappa = delta_mean + 2*delta_std (very selective)
--sample_weighting.kappa=0.07Kapan RA-BC mungkin tidak membantu:
Jika dataset Anda sudah berkualitas tinggi (kemajuan yang konsisten di seluruh demonstrasi), RA-BC tidak akan memberikan banyak manfaat karena tidak ada yang perlu difilter.
Pelatihan Multi-GPU dengan RA-BC
accelerate launch \ --multi_gpu \ --num_processes=4 \ src/lerobot/scripts/lerobot_train.py \ --dataset.repo_id=your-username/your-dataset \ --policy.type=pi0 \ --sample_weighting.type=rabc \ --sample_weighting.kappa=0.01 \ --output_dir=outputs/train/policy_rabc \ --batch_size=32 \ --steps=40000
Tips & Praktik Terbaik
Memilih Mode
- Mulai dengan
single_stageuntuk eksperimen cepat - tanpa beban anotasi - Gunakan
dense_onlyketika Anda ingin pelacakan progres yang detail tetapi tugas tidak memiliki tahap tingkat tinggi yang jelas - Gunakan
dualuntuk tugas kompleks di mana kemajuan kasar dan halus sama-sama bermakna
Kualitas Anotasi
- Jadilah spesifik dengan nama subtask: Alih-alih “fold”, gunakan “grab near side and fold toward center”
- Verifikasi dengan visualisasi: Selalu periksa beberapa episode sebelum pelatihan
- Penamaan yang konsisten: Gunakan nama subtask yang sama di semua episode
RA-BC
- Latih SARM terlebih dahulu: kualitas RA-BC sepenuhnya bergantung pada kualitas SARM
- Pantau
sample_weight_mean_weight: Jika nilainya ≈ 1.0, tingkatkan kappa (lihat Penyetelan Kappa RA-BC)
Sitasi
@article{chen2025sarm,
title={SARM: Stage-Aware Reward Modeling for Long Horizon Robot Manipulation},
author={Chen, Qianzhong and Yu, Justin and Schwager, Mac and Abbeel, Pieter and Shentu, Yide and Wu, Philipp},
journal={arXiv preprint arXiv:2509.25358},
year={2025}
}