LeRobot documentation

SARM: Modelagem de Recompensa Consciente de Etapas

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

SARM: Modelagem de Recompensa Consciente de Etapas

SARM (Stage-Aware Reward Modeling) é um framework de modelagem de recompensas baseado em vídeo para tarefas de manipulação robótica de longo horizonte. Este guia aborda como treinar modelos de recompensa SARM e, opcionalmente, como usá-los com Reward-Aligned Behavior Cloning (RA-BC).

Artigo: SARM: Stage-Aware Reward Modeling for Long Horizon Robot Manipulation

An overview of SARM

Por que Modelos de Recompensa?

O clonagem de comportamento padrão trata todos os quadros de demonstração de forma igual, mas os conjuntos de dados de robôs do mundo real são desorganizados. Eles contêm hesitações, correções e trajetórias de qualidade variável. Os modelos de recompensa resolvem isso aprendendo uma noção generalizável de progresso da tarefa a partir das demonstrações: dados os quadros de vídeo e uma descrição da tarefa, eles preveem o quão perto o robô está de concluir a tarefa (0→1). Esse “sinal de progresso” aprendido pode ser usado de várias maneiras, sendo duas aplicações promissoras: (1) aprendizado por imitação ponderado (RA-BC), em que os quadros com alto progresso recebem mais peso durante o treinamento da política, e (2) aprendizado por reforço, em que o modelo de recompensa fornece recompensas densas para o aprimoramento online ou offline da política.

Visão geral

O SARM possui os seguintes recursos:

  1. Arquitetura consciente de etapas: Prediz simultaneamente a etapa de alto nível da tarefa e o progresso detalhado dentro de cada etapa
  2. Anotações de subtarefas: Usa anotações de subtarefas em linguagem natural para derivar rótulos de progresso consistentes
  3. Proporções temporais: Calcula os priors no nível do conjunto de dados (α̅_k) para cada subtarefa, a fim de normalizar o progresso entre demonstrações de comprimento variável

O SARM treina em um alvo compacto stage+tau para cada quadro:

  • stage: índice do estágio inteiro k ∈ {0, ..., K-1}
  • τ (tau): progresso dentro do estágio τ ∈ [0, 1]
  • codificação de alvo: y = k + τ (é isso que o processador de conjunto de dados produz)

No momento da inferência (e no RA-BC de nível inferior), o SARM converte o valor bruto k + τ em um progresso normalizado em [0, 1] usando as proporções temporais de nível de conjunto de dados α̅_k (armazenadas em meta/temporal_proportions_*.json).

Isso corresponde à Fórmula (2) do artigo:

progress_t = P_{k-1} + α̅_k × τ_t

Onde:

  • τ_t = (t - s_k) / (e_k - s_k) é o tempo normalizado dentro da subtarefa
  • P_{k-1} é o anterior cumulativo (soma das proporções das subtarefas anteriores)
  • α̅_k é a proporção temporal para a subtarefa k

Isso garante que estados de tarefa idênticos sejam mapeados para valores de progresso consistentes, mesmo em demonstrações de diferentes comprimentos.

Entradas e Alvos (O que o novo código espera)

O SARM é treinado por meio de seu processador (src/lerobot/rewards/sarm/processor_sarm.py), que:

  • Codifica imagens e texto da tarefa com CLIP (ViT-B/32) em video_features e text_features
  • Preenche/trunca o estado do robô em state_features (até max_state_dim)
  • Constrói os alvos como sparse_targets (e dense_targets em dense_only/dual) usando a codificação stage+tau y = k + τ
  • Máscaras reprocessam quadros usando um tensor lengths por amostra (reprocessar é uma aumentação no momento do treinamento)

No mínimo, cada amostra de treinamento precisa de:

  • task (string): descrição da tarefa
  • imagens de reward_model.image_key e estados de reward_model.state_key do conjunto de dados

Modos de Anotação

Você pode escolher entre 3 modos de anotação que determinam como os rótulos de progresso são calculados:

ModoAnotações NecessáriasCabeçasCaso de Uso
single_stageNoneApenas esparsosTarefas simples, experimentos rápidos, sem necessidade de VLM
dense_onlyDense (VLM)Dual (auto-gerado esparsamente)Rastreamento detalhado de subtarefas sem definir estágios de alto nível
dualEsparsa + Densa (VLM)DualConfiguração completa do paper SARM com ambas as granularidades

Detalhes do Modo

single_stage
dense_only
dual

Sem anotações necessárias. O episódio inteiro é tratado como um único estágio chamado "task", e o progresso é linear de 0 a 1 ao longo da duração do episódio.

  • Cabeça esparsa: 1 estágio (“task”), progresso linear
  • Cabeça densa: Não utilizado
  • Melhor para: Tarefas simples, experimentos rápidos ou quando a anotação de VLM não está disponível

Configure seu ambiente

  1. Instale o LeRobot seguindo nosso Guia de Instalação.
  2. Instale as dependências do SARM executando:
pip install -e ".[sarm]"

Fluxo de trabalho:

1. Train SARM → 2. Visualize predictions → 3. (Optional) Train policy with RA-BC

Etapa 1: Anotação de subtarefas

single_stage
dense_only
dual

Nenhuma anotação necessária! Pule esta etapa por completo. O modelo usará a descrição da tarefa do episódio e calculará o progresso linear automaticamente.

Argumentos de Anotação

ArgumentoDescrição
--repo-idID do repositório de dataset do HuggingFace
--sparse-subtasksLista de nomes de subtarefas de alto nível separadas por vírgulas
--dense-subtasksLista de nomes de subtarefas de alto nível separadas por vírgulas
--dense-onlyGerar apenas anotações densas (cria automaticamente o estágio esparsos “task”)
--video-keyChave da câmera/vídeo a ser usada (por exemplo, observation.images.top)
--num-workersNúmero de workers de GPU em paralelo (padrão: 1)
--episodesÍndices específicos de episódios para anotar (padrão: todos)
--skip-existingPular episódios que já possuem anotações
--modelModelo VLM (padrão: Qwen/Qwen3-VL-30B-A3B-Instruct)
--num-visualizationsNúmero de episódios a visualizar após a anotação (padrão: 5, defina como 0 para pular)

Observação: Após a conclusão da anotação, 5 episódios são visualizados automaticamente por padrão. Use --num-visualizations 0 para pular esta etapa.


Etapa 2: Verificar Anotações

single_stage
dense_only
dual

Nenhuma verificação necessária! Pule esta etapa.

Isso gera visualizações mostrando os quadros do vídeo com as fronteiras das subtarefas sobrepostas e a linha do tempo das subtarefas.

Argumentos de Visualização

ArgumentoDescrição
--visualize-onlyVisualizar apenas as anotações existentes (sem geração)
--num-visualizationsNúmero de episódios a visualizar (padrão: 5)
--visualize-typeTipo de anotações a visualizar: sparse, dense ou both

Dica: Se as anotações forem imprecisas, ajuste as descrições dos subtarefas para serem mais específicas e execute novamente.


Etapa 3: Treinar SARM

single_stage
dense_only
dual

Treine com sem anotações - usa progresso linear de 0 a 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-name

Treinamento Multi-GPU

Adicione accelerate launch --multi_gpu --num_processes=4 para usar múltiplas GPUs para treinamento.

Argumentos de Treinamento

ArgumentoDescriçãoPadrão
--reward_model.annotation_modesingle_stage, dense_only ou dualsingle_stage
--reward_model.image_keyChave da câmera para imagensobservation.images.top
--reward_model.state_keyChave para estados conjuntosobservation.state
--reward_model.n_obs_stepsEtapas do histórico de observação (total de quadros de obs = n_obs_steps + 1)8
--reward_model.frame_gapIntervalo (em quadros) entre as observações amostradas (a 30 fps: 30 ≈ 1s)30

Etapa 4: Visualizar Previsões

Use compute_rabc_weights.py com --visualize-only para visualizar as previsões do modelo (e, se disponíveis, os alvos derivados das anotações) sem gravar um arquivo parquet.

single_stage
dense_only
dual
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

A visualização mostra:

  • Gráfico de progresso: Progresso previsto (e anotação opcional derivada de “GT” quando disponível e --stride 1)
  • Probabilidades de estágio: Gráfico de área empilhado das probabilidades de estágio previstas
  • Quadros de amostra: Quadros-chave do episódio com rótulos de progresso/etapa

Argumentos de Visualização

ArgumentoDescrição
--visualize-onlyVisualizar apenas as previsões (sem o cálculo do RABC)
--num-visualizationsNúmero de episódios a visualizar (padrão: 5)
--head-modeCabeça SARM a ser usada: sparse, dense ou both
--strideCalcule a cada N quadros e interpole o restante (padrão: 1)

Etapa 5 (Opcional): Treinar a Política com RA-BC

O Behavior Cloning Alinhado a Recompensas (RA-BC) usa o modelo SARM treinado para ponderar as amostras de treinamento com base na melhoria de progresso prevista. Isso requer duas etapas:

  1. Pré-compute progress values para todos os frames usando o modelo SARM treinado
  2. Treinar a política com ponderação RA-BC usando os valores pré-computados

Como o RA-BC funciona

Para cada amostra de treinamento, o RA-BC calcula o delta de progresso:

r_i = φ(o_{t+Δ}) - φ(o_t)

Onde φ é a previsão de progresso do SARM e Δ é o chunk_size da política. Amostras com progresso positivo (boas demonstrações) recebem pesos maiores, enquanto amostras com progresso negativo ou zero têm seus pesos reduzidos.

A ponderação segue as Equações 8-9 do artigo:

  • Peso suave: w̃_i = clip((r_i − (μ − 2σ)) / (4σ + ε), 0, 1)
  • Peso final: w_i = 𝟙{r_i > κ} + 𝟙{0 ≤ r_i ≤ κ} × w̃_i

Etapa 5a: Calcule os valores de progresso do SARM

Primeiro, execute o modelo SARM em todos os frames do seu conjunto de dados para calcular os valores de progresso:

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

Este script:

  • Processa todos os quadros e calcula os valores de progresso
  • Salva os valores de progresso em um arquivo parquet ao lado do conjunto de dados no disco (padrão: <dataset_root>/sarm_progress.parquet)
  • Gera visualizações dos primeiros N episódios (padrão: 5)

Argumentos:

ArgumentoDescriçãoPadrão
--reward-model-pathCaminho para o modelo SARM treinado(obrigatório)
--head-modeCabeça SARM a ser usada: sparse, dense ou bothsparse
--deviceDispositivo para inferênciacuda
--visualize-onlyVisualizar apenas as previsões (sem o cálculo de RA-BC)false
--num-visualizationsNúmero de episódios para visualizar (padrão: 5, defina como 0 para pular)5

Formato de saída (sarm_progress.parquet):

ColunaDescrição
indexÍndice global do quadro no conjunto de dados
episode_indexNúmero do episódio
frame_indexÍndice do quadro local dentro do episódio
progress_sparseValor de progresso da cabeça esparsa [0, 1]
progress_denseValor de progresso da cabeça densa [0, 1] (se calculado)

Etapa 5b: Treinar a Política com RA-BC

Depois de obter o arquivo de progresso, treine sua política com ponderação RA-BC. O arquivo de progresso é detectado automaticamente a partir do caminho do dataset (sarm_progress.parquet) se não for fornecido explicitamente. Atualmente, PI0, PI0.5, SmolVLA e FastWAM são suportados com 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

O script de treinamento faz automaticamente:

  • Carrega os valores de progresso pré-computados do arquivo parquet
  • Usa o chunk_size da política para calcular os deltas de progresso (Δ)
  • Calcula pesos de amostras com base na melhoria do progresso
  • Aplica perda ponderada durante o treinamento

Argumentos do RA-BC:

ArgumentoDescriçãoPadrão
--sample_weighting.typeTipo de estratégia de ponderação (rabc ou uniform)rabc
--sample_weighting.progress_pathCaminho para o arquivo parquet de progressosarm_progress.parquet
--sample_weighting.head_modeQual progresso da cabeça SARM usar: sparse ou densesparse
--sample_weighting.kappaLimiar κ para amostras de alta qualidade0.01
--sample_weighting.epsilonConstante pequena para estabilidade numérica1e-6

Ajuste do Kappa RA-BC

O parâmetro kappa é o limiar que determina quais amostras recebem peso total (w=1). Compreender como ajustá-lo é fundamental para que o RA-BC funcione de forma eficaz.

Como a ponderação funciona:

CondiçãoPeso
delta > kappa1.0 (limiar rígido)
0 ≤ delta ≤ kappaPeso suave da Eq. 8
delta < 00.0 (progresso negativo)

Diagnóstico de problemas de kappa:

Monitore estas métricas do Trackio durante o treinamento:

MétricaFaixa SaudávelIndicador de Problema
sample_weight_mean_weight0.3 - 0.8≈ 1.0 significa que o kappa é baixo demais
sample_weighting/delta_mean> 0Deve ser positivo
sample_weighting/delta_std> 0Variação na qualidade dos dados

Se sample_weight_mean_weight ≈ 1.0: seu kappa está muito baixo. A maioria das amostras tem delta > kappa e ignora completamente o ponderamento suave. O RA-BC se torna equivalente ao BC vanilla.

Definindo kappa com base nos seus dados:

O valor padrão kappa=0.01 foi ajustado para a tarefa de dobrar camisetas do artigo (episódios de ~90s a 30fps). Para o seu conjunto de dados, verifique os valores registrados em sample_weighting/delta_mean e sample_weighting/delta_std:

# 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.07

Quando o RA-BC pode não ajudar:

Se o seu conjunto de dados já for de alta qualidade (progresso consistente em todas as demonstrações), o RA-BC não trará muitos benefícios, pois não há nada para filtrar.

Treinamento Multi-GPU com 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

Dicas e Boas Práticas

Escolhendo um Modo

  • Comece com single_stage para experimentos rápidos - sem sobrecarga de anotação
  • Use dense_only quando você deseja um acompanhamento detalhado do progresso, mas as tarefas não possuem etapas de alto nível bem definidas
  • Use dual para tarefas complexas em que o progresso em nível grosseiro e fino é significativo

Qualidade da Anotação

  1. Seja específico com os nomes das subtarefas: em vez de “dobrar”, use “pegue o lado próximo e dobre em direção ao centro”
  2. Verifique com visualização: Sempre verifique alguns episódios antes do treinamento
  3. Nomenclatura consistente: Use os mesmos nomes de subtarefas em todos os episódios

RA-BC

  1. Treine o SARM primeiro: a qualidade do RA-BC depende inteiramente da qualidade do SARM
  2. Monitore sample_weight_mean_weight: se for ≈ 1.0, aumente kappa (veja Ajuste do Kappa do RA-BC)

Citação

@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}
}
Update on GitHub