LeRobot documentation

Guia do Fluxo de Trabalho de Treinamento em Robôs Reais do HIL-SERL

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.7.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Guia do Fluxo de Trabalho de Treinamento em Robôs Reais do HIL-SERL

Neste tutorial, você percorrerá o fluxo de trabalho completo de Aprendizado por Reforço Eficiente em Amostra com Humano no Loop (HIL-SERL) usando LeRobot. Você dominará o treinamento de uma política com RL em um robô real em apenas algumas horas.

HIL-SERL é um algoritmo de aprendizado por reforço eficiente em amostras que combina demonstrações humanas com aprendizado online e intervenções humanas. A abordagem parte de um pequeno conjunto de demonstrações humanas, usa-as para treinar um classificador de recompensa e, em seguida, emprega uma arquitetura ator-aprendiz em que humanos podem intervir durante a execução da política para orientar a exploração e corrigir comportamentos inseguros. Neste tutorial, você usará um controle de videogame para fornecer intervenções e controlar o robô durante o processo de aprendizado.

Ele combina três ingredientes-chave:

  1. Demonstrações offline e classificador de recompensa: alguns episódios de teleoperação humana, juntamente com um detector de sucesso baseado em visão, fornecem ao policy um ponto de partida estruturado.

  2. Laço ator/learner no robô com intervenções humanas: um learner distribuído de Soft Actor Critic (SAC) atualiza a política enquanto um ator explora no robô físico; o humano pode intervir a qualquer momento para corrigir comportamentos perigosos ou improdutivos.

  3. Ferramentas de segurança e eficiência: limites de junta/eficaz final (EE), pré-processamento da região de interesse (ROI) e monitoramento com Trackio mantêm os dados úteis e o hardware seguro.

Juntos, esses elementos permitem que o HIL-SERL alcance um sucesso de tarefa quase perfeito e tempos de ciclo mais rápidos do que as linhas de base baseadas apenas em imitação.

HIL-SERL workflow

Fluxo de trabalho do HIL-SERL, Luo et al. 2024

Este guia fornece instruções passo a passo para treinar uma política de robô usando a implementação HilSerl do LeRobot para treinar em um robô real.

Do que eu preciso?

  • Um gamepad (recomendado) ou teclado para controlar o robô
  • Uma GPU da Nvidia
  • Um robô real com um braço seguidor e um braço líder (opcional se você usar o teclado ou o controle)
  • Um arquivo URDF do robô para o pacote de cinemática (consulte lerobot/model/kinematics.py)

Que tipo de tarefas posso treinar?

É possível usar o HIL-SERL para treinar em uma variedade de tarefas de manipulação. Algumas recomendações:

  • Comece com uma tarefa simples para entender como o sistema funciona.
    • Empurre o cubo para uma região de destino
    • Pegue e levante o cubo com a pinça
  • Evite tarefas com horizonte extremamente longo. Foque em tarefas que podem ser concluídas em 5 a 10 segundos.
  • Depois que você tiver uma boa noção de como o sistema funciona, pode tentar tarefas mais complexas e horizontes mais longos.
    • Pegar e posicionar cubo
    • Tarefas bimanuais para pegar objetos com dois braços
    • Tarefas de passagem para transferir objetos de um braço para o outro
    • Vá à loucura!

Instale o LeRobot com HIL-SERL

Para instalar o LeRobot com HIL-SERL, você precisa instalar o extra hilserl.

pip install -e ".[hilserl]"

Fluxo de Trabalho de Treinamento de Robô Real

Compreendendo a Configuração

O processo de treinamento começa com a configuração adequada para o ambiente HILSERl. A classe de configuração principal é GymManipulatorConfig em lerobot/rl/gym_manipulator.py, que contém HILSerlRobotEnvConfig (definida em lerobot/envs/configs.py) e DatasetConfig aninhados. A configuração é organizada em subconfigurações aninhadas e focadas:

class GymManipulatorConfig:
    env: HILSerlRobotEnvConfig    # Environment configuration (nested)
    dataset: DatasetConfig    # Dataset recording/replay configuration (nested)
    mode: str | None = None    # "record", "replay", or None (for training)
    device: str = "cpu"    # Compute device

class HILSerlRobotEnvConfig(EnvConfig):
    robot: RobotConfig | None = None    # Main robot agent (defined in `lerobot/robots`)
    teleop: TeleoperatorConfig | None = None    # Teleoperator agent, e.g., gamepad or leader arm
    processor: HILSerlProcessorConfig    # Processing pipeline configuration (nested)
    name: str = "real_robot"    # Environment name
    task: str | None = None    # Task identifier
    fps: int = 30    # Control frequency

# Nested processor configuration
class HILSerlProcessorConfig:
    control_mode: str = "gamepad"    # Control mode
    observation: ObservationConfig | None = None    # Observation processing settings
    image_preprocessing: ImagePreprocessingConfig | None = None    # Image crop/resize settings
    gripper: GripperConfig | None = None    # Gripper control and penalty settings
    reset: ResetConfig | None = None    # Environment reset and timing settings
    inverse_kinematics: InverseKinematicsConfig | None = None    # IK processing settings
    reward_classifier: RewardClassifierConfig | None = None    # Reward classifier settings
    max_gripper_pos: float | None = 100.0    # Maximum gripper position

# Sub-configuration classes
class ObservationConfig:
    add_joint_velocity_to_observation: bool = False    # Add joint velocities to state
    add_current_to_observation: bool = False    # Add motor currents to state
    add_ee_pose_to_observation: bool = False    # Add end-effector pose to state
    display_cameras: bool = False    # Display camera feeds during execution

class ImagePreprocessingConfig:
    crop_params_dict: dict[str, tuple[int, int, int, int]] | None = None    # Image cropping parameters
    resize_size: tuple[int, int] | None = None    # Target image size

class GripperConfig:
    use_gripper: bool = True    # Enable gripper control
    gripper_penalty: float = 0.0    # Penalty for inappropriate gripper usage

class ResetConfig:
    fixed_reset_joint_positions: list[float] | None = None    # Joint positions for reset
    reset_time_s: float = 5.0    # Time to wait during reset
    control_time_s: float = 20.0    # Maximum episode duration
    terminate_on_success: bool = True    # Whether to terminate episodes on success detection

class InverseKinematicsConfig:
    urdf_path: str | None = None    # Path to robot URDF file
    target_frame_name: str | None = None    # End-effector frame name
    end_effector_bounds: dict[str, list[float]] | None = None    # EE workspace bounds
    end_effector_step_sizes: dict[str, float] | None = None    # EE step sizes per axis

class RewardClassifierConfig:
    pretrained_path: str | None = None    # Path to pretrained reward classifier
    success_threshold: float = 0.5    # Success detection threshold
    success_reward: float = 1.0    # Reward value for successful episodes

# Dataset configuration
class DatasetConfig:
    repo_id: str    # LeRobot dataset repository ID
    task: str    # Task identifier
    root: str | None = None    # Local dataset root directory
    num_episodes_to_record: int = 5    # Number of episodes for recording
    replay_episode: int | None = None    # Episode index for replay
    push_to_hub: bool = False    # Whether to push datasets to Hub

Arquitetura do Pipeline do Processor

O HIL-SERL usa uma arquitetura de pipeline de processadores modular que processa observações e ações do robô por meio de uma série de etapas componíveis. O pipeline é dividido em dois componentes principais:

Pipeline do Processador de Ambiente

O processador de ambiente (env_processor) trata as observações recebidas e o estado do ambiente:

  1. VanillaObservationProcessorStep: Converte observações brutas do robô para um formato padronizado
  2. JointVelocityProcessorStep (opcional): Adiciona informações de velocidade das juntas às observações
  3. MotorCurrentProcessorStep (opcional): Adiciona leituras de corrente do motor às observações
  4. ForwardKinematicsJointsToEE (opcional): Calcula a pose do efetuor final a partir das posições das juntas
  5. ImageCropResizeProcessorStep (opcional): Recorta e redimensiona imagens da câmera
  6. TimeLimitProcessorStep (opcional): Impõe limites de tempo por episódio
  7. GripperPenaltyProcessorStep (opcional): aplica penalidades por uso inadequado do garra
  8. RewardClassifierProcessorStep (opcional): detecção automática de recompensas usando modelos de visão
  9. AddBatchDimensionProcessorStep: Converte os dados para o formato de lote para processamento por redes neurais
  10. DeviceProcessorStep: Move os dados para o dispositivo de computação especificado (CPU/GPU)

Pipeline do Processador de Ações

O processador de ações (action_processor) trata as ações de saída e as intervenções humanas:

  1. AddTeleopActionAsComplimentaryDataStep: Captura as ações do teleoperador para registro
  2. AddTeleopEventsAsInfoStep: Registra eventos de intervenção e sinais de controle de episódio
  3. InterventionActionProcessorStep: Trata intervenções humanas e término de episódios
  4. Inverse Kinematics Pipeline (quando habilitado):
    • MapDeltaActionToRobotActionStep: Converte ações delta para o formato de ação do robô
    • EEReferenceAndDelta: Calcula os movimentos de referência e delta do efetuador final
    • EEBoundsAndSafety: Impõe limites de segurança do espaço de trabalho
    • InverseKinematicsEEToJoints: Converte ações do efetuador final em alvos de juntas
    • GripperVelocityToJoint: Trata os comandos de controle do garra

Exemplos de Configuração

Processamento básico de observações:

{
  "env": {
    "processor": {
      "observation": {
        "add_joint_velocity_to_observation": true,
        "add_current_to_observation": false,
        "display_cameras": false
      }
    }
  }
}

Processamento de Imagens:

{
  "env": {
    "processor": {
      "image_preprocessing": {
        "crop_params_dict": {
          "observation.images.front": [180, 250, 120, 150],
          "observation.images.side": [180, 207, 180, 200]
        },
        "resize_size": [128, 128]
      }
    }
  }
}

Configuração da Cinemática Inversa:

{
  "env": {
    "processor": {
      "inverse_kinematics": {
        "urdf_path": "path/to/robot.urdf",
        "target_frame_name": "end_effector",
        "end_effector_bounds": {
          "min": [0.16, -0.08, 0.03],
          "max": [0.24, 0.2, 0.1]
        },
        "end_effector_step_sizes": {
          "x": 0.02,
          "y": 0.02,
          "z": 0.02
        }
      }
    }
  }
}

Processamento Avançado de Observações

O framework HIL-SERL suporta recursos adicionais de processamento de observações que podem melhorar o aprendizado da política:

Processamento de Velocidade Conjunta

Ative a estimativa conjunta de velocidade para fornecer informações de movimento à política:

{
  "env": {
    "processor": {
      "observation": {
        "add_joint_velocity_to_observation": true
      }
    }
  }
}

Este processador:

  • Estima as velocidades articulares usando diferenças finitas entre leituras consecutivas de posição das articulações
  • Adiciona informações de velocidade ao vetor de estado da observação
  • Útil para políticas que precisam de consciência de movimento para tarefas dinâmicas

Processamento da Corrente do Motor

Monitore as correntes do motor para detectar forças de contato e condições de carga:

{
  "env": {
    "processor": {
      "observation": {
        "add_current_to_observation": true
      }
    }
  }
}

Este processador:

  • Lê os valores de corrente do motor do sistema de controle do robô
  • Adiciona as medições atuais ao vetor de estado da observação
  • Ajuda a detectar eventos de contato, pesos de objetos e resistência mecânica
  • Útil para tarefas de manipulação com muitos contatos

Processamento de Observações Combinadas

Você pode habilitar vários recursos de processamento de observações simultaneamente:

{
  "env": {
    "processor": {
      "observation": {
        "add_joint_velocity_to_observation": true,
        "add_current_to_observation": true,
        "display_cameras": false
      }
    }
  }
}

Nota: Habilitar recursos de observação adicionais aumenta a dimensionalidade do espaço de estados, o que pode exigir ajustes na arquitetura da sua rede de política e, potencialmente, a coleta de mais dados de treinamento.

Encontrando os limites do espaço de trabalho do robô

Antes de coletar demonstrações, você precisa determinar os limites operacionais adequados para o seu robô.

Isso ajuda a simplificar o problema de aprendizado no robô real de duas formas: 1) limitando o espaço operacional do robô a uma região específica que resolve a tarefa e evita exploração desnecessária ou insegura, e 2) permitindo o treinamento no espaço do efetuor final em vez do espaço das juntas. Empiricamente, o aprendizado no espaço das juntas para aprendizado por reforço em manipulação é frequentemente um problema mais difícil - algumas tarefas são quase impossíveis de aprender no espaço das juntas, mas se tornam aprendíveis quando o espaço de ações é transformado para coordenadas do efetuor final.

Usando o lerobot-find-joint-limits

Este script ajuda você a encontrar os limites operacionais seguros para o efetuador final do seu robô. Dado que você possui um braço seguidor e um braço líder, pode usar o script para encontrar os limites para o braço seguidor que serão aplicados durante o treinamento. Limitar o espaço de ações reduzirá a exploração redundante do agente e garante a segurança.

lerobot-find-joint-limits \
  --robot.type=so100_follower \
  --robot.port=/dev/tty.usbmodem58760431541 \
  --robot.id=black \
  --teleop.type=so100_leader \
  --teleop.port=/dev/tty.usbmodem58760431551 \
  --teleop.id=blue \
  --urdf_path=SO-ARM100/Simulation/SO101/so101_new_calib.urdf \
  --target_frame_name=gripper

--urdf_path é obrigatório: ele aponta para o arquivo URDF do seu robô, que o script usa para calcular a posição do efetuor final. Para o SO-100/SO-101, clone o repositório SO-ARM100 com git clone https://github.com/TheRobotStudio/SO-ARM100.git; o URDF estará então em SO-ARM100/Simulation/SO101/so101_new_calib.urdf.

Fluxo de trabalho

  1. Execute o script e mova o robô pelo espaço que resolve a tarefa

  2. O script registrará as posições mínimas e máximas do efetuador final e os ângulos das juntas e os exibirá no console, por exemplo:

    # End Effector Bounds (x, y, z):
    max_ee = [0.2417, 0.2012, 0.1027]
    min_ee = [0.1663, -0.0823, 0.0336]
    
    # Joint Position Limits (radians):
    max_pos = [...]
    min_pos = [...]
  3. Use esses valores na configuração do seu ambiente sob env.processor.inverse_kinematics.end_effector_bounds (veja InverseKinematicsConfig em lerobot/envs/configs.py)

Configuração de exemplo

{
  "env": {
    "processor": {
      "inverse_kinematics": {
        "end_effector_bounds": {
          "max": [0.24, 0.2, 0.1],
          "min": [0.16, -0.08, 0.03]
        }
      }
    }
  }
}

Coletando Demonstrações

Com os limites definidos, você pode coletar com segurança demonstrações para o treinamento. Treinar RL com um algoritmo off-policy nos permite usar conjuntos de dados offline coletados para melhorar a eficiência do processo de aprendizado.

Configurando o modo de gravação

Os arquivos de configuração de exemplo para este guia estão no dataset lerobot/config_examples no Hub. Baixe as configurações de ambiente e de treinamento para o seu diretório de trabalho:

hf download lerobot/config_examples rl/env_config.json rl/train_config.json --repo-type dataset --local-dir .

Isso os salva em rl/env_config.json e rl/train_config.json, os caminhos usados nos comandos abaixo. Edite rl/env_config.json para gravar demonstrações:

  1. Defina mode como "record" no nível raiz
  2. Especifique um repo_id único para o seu conjunto de dados na seção dataset (por exemplo, “username/task_name”)
  3. Defina num_episodes_to_record na seção dataset para o número de demonstrações que você deseja coletar
  4. Defina env.processor.image_preprocessing.crop_params_dict como {} inicialmente (determinaremos os recortes mais tarde)
  5. Configure env.robot, env.teleop e outras configurações de hardware na seção env

Seção de configuração de exemplo:

{
  "env": {
    "type": "gym_manipulator",
    "name": "real_robot",
    "fps": 10,
    "processor": {
      "control_mode": "gamepad",
      "observation": {
        "display_cameras": false
      },
      "image_preprocessing": {
        "crop_params_dict": {},
        "resize_size": [128, 128]
      },
      "gripper": {
        "use_gripper": true,
        "gripper_penalty": 0.0
      },
      "reset": {
        "reset_time_s": 5.0,
        "control_time_s": 20.0
      }
    },
    "robot": {
      // ... robot configuration ...
    },
    "teleop": {
      // ... teleoperator configuration ...
    }
  },
  "dataset": {
    "repo_id": "username/pick_lift_cube",
    "root": null,
    "task": "pick_and_lift",
    "num_episodes_to_record": 15,
    "replay_episode": 0,
    "push_to_hub": true
  },
  "mode": "record",
  "device": "cpu"
}

Usando um dispositivo de teleoperação

Junto com seu robô, você precisará de um dispositivo de teleoperação para controlá-lo, a fim de coletar conjuntos de dados da sua tarefa e realizar intervenções durante o treinamento online. Suportamos o uso de um controle de videogame, um teclado ou o braço líder do robô.

HIL-Serl aprende ações no espaço do efetuor final do robô. Portanto, a teleoperação controlará os deslocamentos x, y, z do efetuor final.

A transformação do efetuor final é aplicada pelo pipeline do processador (InverseKinematicsRLStep, EEBoundsAndSafety, EEReferenceAndDelta, GripperVelocityToJoint) configurado sob env.processor.inverse_kinematics (InverseKinematicsConfig) e env.processor.gripper / env.processor.max_gripper_pos. Os padrões relacionados ao espaço do efetuor final são:

class InverseKinematicsConfig:
    """Configuration for inverse kinematics processing."""

    urdf_path: str | None = None
    target_frame_name: str | None = None
    # bounds for the end-effector in x,y,z direction
    end_effector_bounds: dict[str, list[float]] | None = None
    # maximum step size for the end-effector in x,y,z direction
    end_effector_step_sizes: dict[str, float] | None = None

class HILSerlProcessorConfig:
    ...
    # maximum gripper position that the gripper will be open at
    max_gripper_pos: float | None = 100.0

O Teleoperator define o dispositivo de teleoperação. Você pode verificar a lista de teleoperadores disponíveis em lerobot/teleoperators.

Configurando o Gamepad

O gamepad oferece uma maneira muito conveniente de controlar o robô e o estado do episódio.

Para configurar o gamepad, você precisa definir o control_mode como "gamepad" e definir a seção teleop no arquivo de configuração.

{
  "env": {
    "teleop": {
      "type": "gamepad",
      "use_gripper": true
    },
    "processor": {
      "control_mode": "gamepad",
      "gripper": {
        "use_gripper": true
      }
    }
  }
}

Figure shows the control mappings on a Logitech gamepad.

Mapeamento de botões do gamepad para controle do robô e gerenciamento de episódios

Configurando o líder SO101

O braço líder do SO101 possui engrenagens reduzidas que permitem que ele se mova e acompanhe o braço seguidor durante a exploração. Portanto, a transição de controle é muito mais suave do que no SO100, que não possui engrenagens.

Para configurar o líder SO101, você precisa definir o control_mode como "leader" e definir a seção teleop no arquivo de configuração.

{
  "env": {
    "teleop": {
      "type": "so101_leader",
      "port": "/dev/tty.usbmodem585A0077921",
      "use_degrees": true
    },
    "processor": {
      "control_mode": "leader",
      "gripper": {
        "use_gripper": true
      }
    }
  }
}

Para anotar o sucesso/falha do episódio, você precisará usar um teclado para pressionar s para sucesso e esc para falha. Durante o treinamento online, pressione space para assumir o controle da política e space novamente para devolver o controle à política.

Video: SO101 leader teleoperation

Exemplo de teleoperação do líder SO101, o líder acompanha o seguidor, pressione `space` para intervir

Gravação de Demonstrações

Inicie o processo de gravação com a configuração de ambiente que você editou acima:

python -m lerobot.rl.gym_manipulator --config_path rl/env_config.json

Durante a gravação:

  1. O robô será redefinido para a posição inicial definida no arquivo de configuração env.processor.reset.fixed_reset_joint_positions
  2. Conclua a tarefa com sucesso
  3. O episódio termina com uma recompensa de 1 quando você pressiona o botão “success”
  4. Se o limite de tempo for atingido ou o botão de falha for pressionado, o episódio termina com uma recompensa de 0
  5. Você pode gravar novamente um episódio pressionando o botão “rerecord”
  6. O processo continua automaticamente para o próximo episódio
  7. Após gravar todos os episódios, o conjunto de dados é enviado para o Hugging Face Hub (opcional) e salvo localmente

Processando o Conjunto de Dados

Após coletar as demonstrações, processe-as para determinar os recortes de câmera ideais. O aprendizado por reforço é sensível a distrações do fundo, portanto, é importante recortar as imagens para a área de trabalho relevante.

Algoritmos de RL visual aprendem diretamente a partir de entradas de pixels, tornando-os vulneráveis a informações visuais irrelevantes. Elementos de fundo, como mudanças de iluminação, sombras, pessoas em movimento ou objetos fora da área de trabalho, podem confundir o processo de aprendizado. Uma boa seleção de ROI deve:

  • Inclua apenas o workspace essencial onde a tarefa é executada
  • Capture o efector final do robô e todos os objetos envolvidos na tarefa
  • Exclua elementos de fundo e distrações desnecessários

Nota: Se você já conhece os parâmetros de recorte, pode pular esta etapa e simplesmente definir o crop_params_dict no arquivo de configuração durante a gravação.

Determinando os Parâmetros de Corte

Use o script crop_dataset_roi.py para selecionar interativamente regiões de interesse nas imagens da sua câmera:

python -m lerobot.rl.crop_dataset_roi --repo-id username/pick_lift_cube
  1. Para cada visão da câmera, o script exibirá o primeiro quadro
  2. Desenhe um retângulo ao redor da área relevante do espaço de trabalho
  3. Pressione ‘c’ para confirmar a seleção
  4. Repita para todas as visões da câmera
  5. O script exibe os parâmetros de recorte e cria um novo conjunto de dados recortado

Exemplo de saída:

Selected Rectangular Regions of Interest (top, left, height, width):
observation.images.side: [180, 207, 180, 200]
observation.images.front: [180, 250, 120, 150]

Ferramenta interativa de recorte para selecionar regiões de interesse

Atualizando a Configuração

Adicione estes parâmetros de recorte à sua configuração de treinamento:

{
  "env": {
    "processor": {
      "image_preprocessing": {
        "crop_params_dict": {
          "observation.images.side": [180, 207, 180, 200],
          "observation.images.front": [180, 250, 120, 150]
        },
        "resize_size": [128, 128]
      }
    }
  }
}

Resolução de imagem recomendada

A maioria das políticas baseadas em visão foi validada em entradas quadradas de 128×128 (padrão) ou 64×64 pixels. Portanto, recomendamos definir o parâmetro resize_size como [128, 128] – ou [64, 64] se você precisar economizar memória e largura de banda da GPU. Outras resoluções são possíveis, mas não foram amplamente testadas.

Treinando um Classificador de Recompensa

O classificador de recompensa desempenha um papel importante no fluxo de trabalho do HIL-SERL ao automatizar a atribuição de recompensas e detectar automaticamente o sucesso dos episódios. Em vez de definir manualmente funções de recompensa ou depender de feedback humano para cada passo de tempo, o classificador de recompensa aprende a prever sucesso/falha a partir de observações visuais. Isso permite que o algoritmo de RL aprenda de forma eficiente, fornecendo sinais de recompensa consistentes e automatizados com base nas entradas da câmera do robô.

Este guia explica como treinar um classificador de recompensa para a implementação de aprendizado por reforço com intervenção humana (human-in-the-loop) do LeRobot. Os classificadores de recompensa aprendem a prever o valor da recompensa dado um estado, o que pode ser usado em uma configuração de RL para treinar uma política.

Nota: Treinar um classificador de recompensa é opcional. Você pode iniciar a primeira rodada de experimentos de RL anotando o sucesso manualmente com seu controle ou dispositivo de teclado.

A implementação do classificador de recompensas em lerobot/rewards/classifier/modeling_classifier.py usa um modelo de visão pré-treinado para processar as imagens. Ele pode gerar um único valor para recompensas binárias, a fim de prever casos de sucesso/falha, ou múltiplos valores para configurações de múltiplas classes.

Coletando um Conjunto de Dados para o classificador de recompensa

Antes do treinamento, você precisa coletar um conjunto de dados com exemplos rotulados. Definir mode: "record" na sua configuração e executar gym_manipulator.py habilita o processo de coleta de um conjunto de dados de observações, ações e recompensas.

Para coletar um conjunto de dados, você precisa modificar alguns parâmetros na configuração do ambiente com base em HILSerlRobotEnvConfig.

python -m lerobot.rl.gym_manipulator --config_path rl/env_config.json

Parâmetros-chave para a coleta de dados

  • mode: defina como "record" para coletar um conjunto de dados (no nível raiz)
  • dataset.repo_id: "hf_username/dataset_name", nome do dataset e do repositório no hub
  • dataset.num_episodes_to_record: Número de episódios a serem gravados
  • env.processor.reset.terminate_on_success: Se os episódios devem ser encerrados automaticamente quando o sucesso é detectado (padrão: true)
  • env.fps: Número de quadros por segundo a serem gravados
  • dataset.push_to_hub: Se deve enviar o dataset para o hub

O parâmetro env.processor.reset.terminate_on_success permite controlar o comportamento de término dos episódios. Quando definido como false, os episódios continuam mesmo após a detecção de sucesso, permitindo coletar mais exemplos positivos com o rótulo reward=1. Isso é crucial para o treinamento de classificadores de recompensa, pois fornece mais exemplos de estados de sucesso no seu conjunto de dados. Quando definido como true (padrão), os episódios terminam imediatamente ao detectar o sucesso.

Importante: Para o treinamento do classificador de recompensa, defina terminate_on_success: false para coletar exemplos positivos suficientes. Para o treinamento regular do HIL-SERL, mantenha como true para permitir o término automático do episódio quando a tarefa for concluída com sucesso.

Exemplo de seção de configuração para coleta de dados:

{
  "env": {
    "type": "gym_manipulator",
    "name": "real_robot",
    "fps": 10,
    "processor": {
      "reset": {
        "reset_time_s": 5.0,
        "control_time_s": 20.0,
        "terminate_on_success": false
      },
      "gripper": {
        "use_gripper": true
      }
    },
    "robot": {
      // ... robot configuration ...
    },
    "teleop": {
      // ... teleoperator configuration ...
    }
  },
  "dataset": {
    "repo_id": "hf_username/dataset_name",
    "root": "data/your_dataset",
    "task": "reward_classifier_task",
    "num_episodes_to_record": 20,
    "replay_episode": null,
    "push_to_hub": true
  },
  "mode": "record",
  "device": "cpu"
}

Configuração do Classificador de Recompensa

O classificador de recompensa é configurado usando lerobot/rewards/classifier/configuration_classifier.py. Aqui estão os principais parâmetros:

  • model_name: Arquitetura do modelo base (por exemplo, usamos principalmente "helper2424/resnet10")
  • model_type: "cnn" ou "transformer"
  • num_cameras: Número de entradas de câmera
  • num_classes: Número de classes de saída (geralmente 2 para sucesso/falha binário)
  • hidden_dim: Tamanho da representação oculta
  • dropout_rate: Parâmetro de regularização
  • learning_rate: Taxa de aprendizado para o otimizador

Exemplo de configuração para treinar o classificador de recompensa. Salve-o como reward_classifier_train_config.json:

{
  "dataset": {
    "repo_id": "hf_username/dataset_name",
    "root": null
  },
  "reward_model": {
    "type": "reward_classifier",
    "model_name": "helper2424/resnet10",
    "model_type": "cnn",
    "num_cameras": 2,
    "num_classes": 2,
    "hidden_dim": 256,
    "dropout_rate": 0.1,
    "learning_rate": 1e-4,
    "device": "cuda",
    "input_features": {
      "observation.images.front": {
        "type": "VISUAL",
        "shape": [3, 128, 128]
      },
      "observation.images.side": {
        "type": "VISUAL",
        "shape": [3, 128, 128]
      }
    },
    "push_to_hub": true,
    "repo_id": "hf_username/model_repo"
  },
  "batch_size": 16,
  "num_workers": 4,
  "steps": 5000,
  "log_freq": 10,
  "env_eval_freq": 1000,
  "save_freq": 1000,
  "save_checkpoint": true,
  "seed": 2,
  "resume": false,
  "optimizer": {
    "grad_clip_norm": 10.0
  },
  "trackio": {
    "enable": true,
    "project": "reward-classifier"
  },
  "job_name": "reward-classifier"
}

Treinando o Classificador

Para treinar o classificador, use o script train.py com sua configuração:

lerobot-train --config_path reward_classifier_train_config.json

Implantação e Teste do Modelo

Para usar seu classificador de recompensa treinado, configure o HILSerlRobotEnvConfig para usar seu modelo:

config = GymManipulatorConfig(
    env=HILSerlRobotEnvConfig(
        processor=HILSerlProcessorConfig(
            reward_classifier=RewardClassifierConfig(
                pretrained_path="path_to_your_pretrained_trained_model"
            )
        ),
        # Other environment parameters
    ),
    dataset=DatasetConfig(...),
    mode=None  # For training
)

ou defina o argumento no arquivo de configuração json.

{
  "env": {
    "processor": {
      "reward_classifier": {
        "pretrained_path": "path_to_your_pretrained_model",
        "success_threshold": 0.7,
        "success_reward": 1.0
      },
      "reset": {
        "terminate_on_success": true
      }
    }
  }
}

Execute gym_manipulator.py para testar o modelo.

python -m lerobot.rl.gym_manipulator --config_path rl/env_config.json

O classificador de recompensas fornecerá automaticamente recompensas com base na entrada visual das câmeras do robô.

Exemplo de fluxo de trabalho para treinar o classificador de recompensa

  1. Crie os arquivos de configuração: Crie os arquivos de configuração json necessários para o classificador de recompensa e o ambiente: reward_classifier_train_config.json do exemplo acima e o rl/env_config.json baixado.

  2. Coletar um conjunto de dados:

    python -m lerobot.rl.gym_manipulator --config_path rl/env_config.json
  3. Treinar o classificador:

    lerobot-train --config_path reward_classifier_train_config.json
  4. Teste o classificador:

    python -m lerobot.rl.gym_manipulator --config_path rl/env_config.json

Treinamento com Actor-Learner

O sistema LeRobot usa uma arquitetura distribuída de ator-aprendiz para treinamento. Essa arquitetura desacopla as interações do robô do processo de aprendizado, permitindo que eles sejam executados simultaneamente sem bloquear um ao outro. O servidor de ator lida com as observações e ações do robô, enviando dados de interação para o servidor de aprendizado. O servidor de aprendizado executa a descida do gradiente e atualiza periodicamente os pesos da política do ator. Você precisará iniciar dois processos: um de aprendizado e um de ator.

Configuração do Setup

Edite o arquivo de configuração de treinamento que você baixou anteriormente, rl/train_config.json (exemplo disponível aqui). A configuração de treinamento é baseada na classe principal TrainRLServerPipelineConfig em lerobot/rl/train_rl.py.

  1. Configure as configurações da política (type="gaussian_actor", device, etc.)
  2. Configure as configurações do algoritmo no bloco de nível superior algorithm (type="sac", taxas de aprendizado, desconto, etc., definidas em lerobot/rl/algorithms/sac/configuration_sac.py).
  3. Defina dataset como seu dataset recortado
  4. Configure as configurações do ambiente com parâmetros de recorte
  5. Verifique os outros parâmetros relacionados ao Ator Gaussiano em configuration_gaussian_actor.py.
  6. Verifique se a configuração policy está correta, com os input_features e output_features adequados para a sua tarefa.

Iniciando o Learner

Primeiro, inicie o processo do servidor de aprendizado:

python -m lerobot.rl.learner --config_path rl/train_config.json

O aprendiz:

  • Inicializa a rede de política
  • Prepara buffers de replay
  • Abre um servidor gRPC para se comunicar com atores
  • Processa transições e atualiza a política

Iniciando o Actor

Em um terminal separado, inicie o processo do ator com a mesma configuração:

python -m lerobot.rl.actor --config_path rl/train_config.json

O ator:

  • Conecta-se ao learner via gRPC
  • Inicializa o ambiente
  • Execute rollouts da política para coletar experiência
  • Envia transições para o aprendiz
  • Recebe os parâmetros de política atualizados

Fluxo de Treinamento

O treinamento prossegue automaticamente:

  1. O ator executa a política no ambiente
  2. As transições são coletadas e enviadas ao aprendiz
  3. O learner atualiza a política com base nessas transições
  4. Os parâmetros de política atualizados são enviados de volta para o ator
  5. O processo continua até que o limite de etapas especificado seja atingido

Humano no Loop

  • A chave para aprender de forma eficiente é contar com intervenções humanas que forneçam feedback corretivo e completem a tarefa, auxiliando o aprendizado e a exploração da política.
  • Para realizar intervenções humanas, você pode pressionar o gatilho superior direito no controle (ou a tecla space no teclado). Isso pausará as ações da política e permitirá que você assuma o controle.
  • Um experimento bem-sucedido é aquele em que o humano precisa intervir no início, mas reduz a quantidade de intervenções à medida que a política melhora. Você pode monitorar a taxa de intervenção no dashboard do Trackio (trackio show --project <project>).

Figure shows the control mappings on a Logitech gamepad.

Exemplo mostrando como intervenções humanas ajudam a orientar o aprendizado de política ao longo do tempo

  • A figura mostra o gráfico da recompensa episódica em função do passo de interação. A figura mostra o efeito das intervenções humanas no aprendizado da política.
  • A curva laranja é um experimento sem nenhuma intervenção humana. Enquanto as curvas rosa e azul são experimentos com intervenções humanas.
  • Podemos observar que o número de etapas em que a política começa a alcançar a recompensa máxima é reduzido em um quarto quando há intervenções humanas.

Monitoramento e Depuração

Se você tiver trackio.enable definido como true na sua configuração, pode monitorar o progresso do treinamento em tempo real por meio do painel Trackio (trackio show --project <project>).

Guia de Intervenções Humanas

O processo de aprendizado é muito sensível à estratégia de intervenção. Serão necessários alguns testes para entender como intervir de forma eficaz. Algumas dicas e sugestões:

  • Permita que a política explore por alguns episódios no início do treinamento.
  • Evite intervenções por longos períodos. Tente intervir na situação para corrigir o comportamento do robô quando ele sair do rumo.
  • Quando a política começa a realizar a tarefa, mesmo que não perfeitamente, você pode limitar suas intervenções a ações simples e rápidas, como comandos simples de preensão.

O comportamento ideal é que sua taxa de intervenção diminua gradualmente durante o treinamento, conforme mostrado na figura abaixo.

Intervention rate

Gráfico da taxa de intervenção durante uma execução de treinamento em uma tarefa de pegar e levantar um cubo

Principais hiperparâmetros para ajustar

Alguns valores de configuração têm um impacto desproporcional na estabilidade e na velocidade do treinamento:

  • temperature_init (algorithm.temperature_init) – temperatura inicial de entropia no SAC. Valores mais altos incentivam mais exploração; valores mais baixos tornam a política mais determinística no início. Um bom ponto de partida é 1e-2. Observamos que configurá-la muito alta pode tornar as intervenções humanas ineficazes e desacelerar o aprendizado.
  • policy_parameters_push_frequency (policy.actor_learner_config.policy_parameters_push_frequency) – intervalo em segundos entre duas transferências de pesos do learner para o actor. O padrão é 4 s. Diminua para 1-2 s para fornecer pesos mais atualizados (ao custo de mais tráfego de rede); aumente apenas se sua conexão for lenta, pois isso reduzirá a eficiência da amostragem.
  • storage_device (policy.storage_device) – dispositivo no qual o learner mantém os parâmetros da policy. Se você tiver memória GPU disponível, defina isso como "cuda" (em vez do padrão "cpu"). Manter os pesos na GPU elimina o overhead de transferência CPU→GPU e pode aumentar significativamente o número de atualizações do learner por segundo.

Parabéns 🎉, você concluiu este tutorial!

Se você tiver alguma dúvida ou precisar de ajuda, entre em contato no Discord.

Citação do artigo:

@article{luo2024precise,
  title={Precise and Dexterous Robotic Manipulation via Human-in-the-Loop Reinforcement Learning},
  author={Luo, Jianlan and Xu, Charles and Wu, Jeffrey and Levine, Sergey},
  journal={arXiv preprint arXiv:2410.21845},
  year={2024}
}
Update on GitHub