# Руководство по рабочему процессу обучения реального робота HIL-SERL

В этом руководстве вы пройдёте полный рабочий процесс обучения с подкреплением с участием человека в цикле и высокой эффективностью по образцам (Human-in-the-Loop Sample-Efficient Reinforcement Learning, HIL-SERL) с использованием LeRobot. Вы освоите обучение политики с помощью RL на реальном роботе всего за несколько часов.

HIL-SERL — это алгоритм обучения с подкреплением, эффективный по количеству примеров, который сочетает демонстрации человека с онлайн-обучением и вмешательствами человека. Подход начинается с небольшого набора демонстраций человека, использует их для обучения классификатора вознаграждения, а затем применяет архитектуру «исполнитель-обучающий», в которой человек может вмешиваться во время выполнения политики, направляя исследование и исправляя небезопасные действия. В этом учебном материале вы будете использовать геймпад для предоставления вмешательств и управления роботом в процессе обучения.

Оно объединяет три ключевых компонента:

1. **Офлайн-демонстрации и классификатор вознаграждения:** несколько эпизодов телеуправления человеком и детектор успеха на основе зрения задают политику сформированную стартовую точку.

2. **Цикл «исполнитель / обучатель» на роботе с вмешательством человека:** распределённый обучатель Soft Actor Critic (SAC) обновляет политику, пока исполнитель исследует среду на физическом роботе; человек может вмешаться в любой момент, чтобы скорректировать опасное или непродуктивное поведение.

3. **Инструменты безопасности и эффективности:** границы для шарниров/концевого эффектора (EE), предобработка области интереса (ROI) и мониторинг Trackio обеспечивают полезность данных и безопасность оборудования.

В совокупности эти элементы позволяют HIL-SERL достигать практически идеального уровня успешности выполнения задач и более коротких циклов по сравнению с базовыми методами, основанными исключительно на имитации.

  <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/hilserl-main-figure.png" alt="Рабочий процесс HIL-SERL" title="Рабочий процесс HIL-SERL" width="100%"
  >

  Рабочий процесс HIL-SERL, Luo et al. 2024

В этом руководстве приведены пошаговые инструкции по обучению политики робота с использованием реализации HilSerl в LeRobot для обучения на реальном роботе.

## Что мне нужно?

- Геймпад (рекомендуется) или клавиатура для управления роботом
- GPU от Nvidia
- Настоящий робот с ведущей и ведомой рукой (необязательно, если вы используете клавиатуру или геймпад)
- Файл URDF робота для пакета кинематики (см. `lerobot/model/kinematics.py`)

## Какие задачи можно обучать?

С помощью HIL-SERL можно обучать модели на разнообразных задачах манипуляции. Некоторые рекомендации:

- Начните с простой задачи, чтобы понять, как работает система.
  - Двигайте куб в целевую область
  - Выберите и поднимите кубик захватом
- Избегайте задач с очень длительным горизонтом. Фокусируйтесь на задачах, которые можно выполнить за 5–10 секунд.
- Когда вы хорошо поймёте, как работает система, можно попробовать более сложные задачи и более длинные горизонты.
  - Выбор и размещение куба
  - Двуручные задачи по захвату объектов двумя манипуляторами
  - Задачи передачи объектов с одной руки на другую
  - Давай без тормозов!

## Установка LeRobot с HIL-SERL

Для установки LeRobot с HIL-SERL необходимо установить дополнительный пакет `hilserl`.

```bash
pip install -e ".[hilserl]"
```

## Workflow обучения реального робота

### Понимание конфигурации

Процесс обучения начинается с правильной настройки для среды HILSERl. Основной класс конфигурации — `GymManipulatorConfig` в `lerobot/rl/gym_manipulator.py`, который содержит вложенные `HILSerlRobotEnvConfig` (определён в `lerobot/envs/configs.py`) и `DatasetConfig`. Конфигурация организована в сфокусированные вложенные подконфигурации:

```python
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
```

### Архитектура конвейера процессора

HIL-SERL использует модульную архитектуру конвейера процессоров, которая обрабатывает наблюдения и действия робота через серию составных шагов. Конвейер разделен на два основных компонента:

#### Конвейер процессора среды

Процессор среды (`env_processor`) обрабатывает входящие наблюдения и состояние среды:

1. **VanillaObservationProcessorStep**: преобразует необработанные наблюдения робота в стандартизированный формат
2. **JointVelocityProcessorStep** (необязательный): добавляет информацию о скорости суставов к наблюдениям
3. **MotorCurrentProcessorStep** (необязательный): добавляет показания тока двигателя к наблюдениям
4. **ForwardKinematicsJointsToEE** (необязательный): вычисляет позу исполнительного органа по позициям суставов
5. **ImageCropResizeProcessorStep** (необязательный): обрезает и изменяет размер изображений с камеры
6. **TimeLimitProcessorStep** (необязательный): устанавливает временные ограничения для эпизодов
7. **GripperPenaltyProcessorStep** (необязательный): применяет штрафы за некорректное использование захвата
8. **RewardClassifierProcessorStep** (необязательный): автоматическое обнаружение вознаграждений с использованием моделей зрения
9. **AddBatchDimensionProcessorStep**: преобразует данные в формат батча для обработки нейронной сетью
10. **DeviceProcessorStep**: перемещает данные на указанное вычислительное устройство (CPU/GPU)

#### Конвейер процессора действий

Процессор действий (`action_processor`) обрабатывает исходящие действия и вмешательства человека:

1. **AddTeleopActionAsComplimentaryDataStep**: Захват действий телеоператора для ведения журнала
2. **AddTeleopEventsAsInfoStep**: Записывает события вмешательства и сигналы управления эпизодом
3. **InterventionActionProcessorStep**: обрабатывает вмешательства человека и завершение эпизода
4. **Конвейер обратной кинематики** (при включении):
   - **MapDeltaActionToRobotActionStep**: преобразует действия в формате дельта в формат действий робота
   - **EEReferenceAndDelta**: вычисляет движения опорной точки и дельта
   - **EEBoundsAndSafety**: обеспечивает соблюдение границ безопасности рабочей области
   - **InverseKinematicsEEToJoints**: преобразует действия конечного эффектора в целевые значения для суставов
   - **GripperVelocityToJoint**: обрабатывает команды управления захватом

#### Примеры конфигурации

**Базовая обработка наблюдений**:

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

**Обработка изображений**:

```json
{
  "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]
      }
    }
  }
}
```

**Настройка обратной кинематики**:

```json
{
  "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
        }
      }
    }
  }
}
```

### Расширенная обработка наблюдений

Фреймворк HIL-SERL поддерживает дополнительные функции обработки наблюдений, которые могут улучшить обучение политики:

#### Обработка скорости соединения

Включите совместную оценку скорости, чтобы предоставить политике информацию о движении:

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

Этот процессор:

- Оценивает угловые скорости на основе конечных разностей между последовательными показаниями положений суставов
- Добавляет информацию о скорости к вектору состояния наблюдения
- Полезно для политик, которым необходимо распознавание движения для динамических задач

#### Обработка тока двигателя

Мониторинг токов двигателей для обнаружения контактных усилий и условий нагрузки:

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

Этот процессор:

- Читает значения тока двигателя из системы управления роботом
- Добавляет текущие измерения к вектору состояния наблюдений
- Помогает обнаруживать события контакта, вес объектов и механическое сопротивление
- Полезно для задач манипуляции с большим количеством контактов

#### Обработка объединённых наблюдений

Вы можете одновременно включить несколько функций обработки наблюдений:

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

**Примечание**: Включение дополнительных признаков наблюдений увеличивает размерность пространства состояний, что может потребовать корректировки архитектуры сети политики и, возможно, сбора дополнительных данных для обучения.

### Определение границ рабочего пространства робота

Перед сбором демонстраций необходимо определить соответствующие рабочие границы для вашего робота.

Это упрощает задачу обучения на реальном роботе двумя способами: 1) ограничивая рабочее пространство робота конкретной областью, которая решает задачу и исключает ненужное или небезопасное исследование, и 2) позволяя обучение в пространстве конечного эффектора, а не в пространстве суставов. Эмпирически, обучение в пространстве суставов для reinforcement learning в манипуляции часто является более сложной задачей — некоторые задачи практически невозможно решить в пространстве суставов, но они становятся обучаемыми, когда пространство действий преобразуется в координаты конечного эффектора.

**Использование lerobot-find-joint-limits**

Этот скрипт помогает определить безопасные рабочие границы для исполнительного органа вашего робота. Если у вас есть ведущая и ведомая руки, вы можете использовать скрипт для поиска границ для ведомой руки, которые будут применяться во время обучения. Ограничение пространства действий сокращает избыточное исследование со стороны агента и гарантирует безопасность.

```bash
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` является обязательным: он указывает на файл URDF вашего робота, который скрипт использует для вычисления позиции конечного эффектора. Для SO-100/SO-101 клонируйте репозиторий [SO-ARM100](https://github.com/TheRobotStudio/SO-ARM100) с помощью `git clone https://github.com/TheRobotStudio/SO-ARM100.git`; файл URDF будет находиться по пути `SO-ARM100/Simulation/SO101/so101_new_calib.urdf`.

**Рабочий процесс**

1. Запустите скрипт и перемещайте робота по пространству, решая задачу
2. Скрипт записывает минимальные и максимальные позиции конечного эффектора и углы суставов и выводит их в консоль, например:

   ```
   # 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. Используйте эти значения в конфигурации вашего окружения под `env.processor.inverse_kinematics.end_effector_bounds` (см. `InverseKinematicsConfig` в `lerobot/envs/configs.py`)

**Пример конфигурации**

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

### Сбор демонстраций

После определения границ можно безопасно собирать демонстрации для обучения. Обучение с подкреплением с использованием off-policy-алгоритма позволяет использовать офлайн-наборы данных, собранные для повышения эффективности процесса обучения.

**Настройка режима записи**

Файлы конфигурации, используемые в качестве примеров в этом руководстве, находятся в датасете [lerobot/config_examples](https://huggingface.co/datasets/lerobot/config_examples) на Hub. Скачайте конфигурации окружения и обучения в рабочую директорию:

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

Это сохраняет их в `rl/env_config.json` и `rl/train_config.json`, пути, используемые в командах ниже. Отредактируйте `rl/env_config.json` для записи демонстраций:

1. Установите `mode` в `"record"` на верхнем уровне
2. Укажите уникальный `repo_id` для вашего набора данных в разделе `dataset` (например, "username/task_name")
3. Укажите в разделе `dataset` значение параметра `num_episodes_to_record`, равное количеству демонстраций, которые вы хотите собрать
4. Изначально установите `env.processor.image_preprocessing.crop_params_dict` в `{}` (области обрезки мы определим позже)
5. Настройте `env.robot`, `env.teleop` и другие параметры оборудования в разделе `env`

Пример раздела конфигурации:

```json
{
  "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"
}
```

### Использование устройства телеуправления

Вместе с роботом вам понадобится устройство телеуправления для управления им, чтобы собирать наборы данных для вашей задачи и выполнять вмешательства во время онлайн-обучения. Мы поддерживаем использование геймпада, клавиатуры или ведущего манипулятора робота.

HIL-Serl обучает действия в пространстве конечного эффектора робота. Следовательно, телеуправление будет контролировать смещения конечного эффектора по осям x, y, z.

Преобразование конечного эффектора применяется конвейером процессора (`InverseKinematicsRLStep`, `EEBoundsAndSafety`, `EEReferenceAndDelta`, `GripperVelocityToJoint`), настроенным в `env.processor.inverse_kinematics` (`InverseKinematicsConfig`) и `env.processor.gripper` / `env.processor.max_gripper_pos`. Значения по умолчанию, связанные с пространством конечного эффектора:

```python
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
```

`Teleoperator` определяет устройство телеуправления. Список доступных телеоператоров можно найти в `lerobot/teleoperators`.

**Настройка геймпада**

Геймпад предоставляет очень удобный способ управления роботом и состоянием эпизода.

Для настройки геймпада необходимо установить `control_mode` в значение `"gamepad"` и определить секцию `teleop` в файле конфигурации.

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

  <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/gamepad_guide.jpg?raw=true" alt="На рисунке показано управление на геймпаде Logitech." title="Управление с помощью геймпада" width="100%"
  >

  Назначение кнопок геймпада для управления роботом и управления эпизодами

**Настройка SO101 leader**

Рука-лидер SO101 оснащена редукторами, что позволяет ей перемещаться и отслеживать руку-последователя в процессе исследования. Поэтому передача управления происходит значительно плавнее, чем у SO100 без редукторов.

Для настройки SO101 leader необходимо установить `control_mode` в значение `"leader"` и определить секцию `teleop` в файле конфигурации.

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

Чтобы отметить успех или неудачу эпизода, **вам потребуется** использовать клавиатуру: нажмите `s` для успеха и `esc` для неудачи. Во время онлайн-обучения нажмите `space`, чтобы взять управление на себя, и снова `space`, чтобы вернуть управление политике.

Видео: телеуправление лидером SO101

  
    <source
      src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/so101_leader_tutorial.mp4"
      type="video/mp4"
    />
  

Пример телеуправления лидером SO101: лидер отслеживает ведомого, нажмите `space` для вмешательства

**Запись демонстраций**

Запустите процесс записи с конфигурацией окружения, которую вы отредактировали выше:

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

Во время записи:

1. Робот будет сброшен в начальное положение, заданное в файле конфигурации `env.processor.reset.fixed_reset_joint_positions`
2. Успешно выполните задачу
3. Эпизод завершается наградой 1, когда вы нажимаете кнопку «success»
4. Если время истекло или была нажата кнопка сбоя, эпизод завершается с наградой 0
5. Вы можете переснять эпизод, нажав кнопку «переснять»
6. Процесс автоматически продолжается со следующего эпизода
7. После записи всех эпизодов датасет отправляется на Hugging Face Hub (по желанию) и сохраняется локально

### Обработка набора данных

После сбора демонстраций обработайте их, чтобы определить оптимальные кадрирования камеры. Обучение с подкреплением чувствительно к отвлекающим факторам на фоне, поэтому важно кадрировать изображения так, чтобы выделить релевантную область рабочего пространства.

Алгоритмы визуального RL обучаются непосредственно на пиксельных входных данных, что делает их уязвимыми к нерелевантной визуальной информации. Фоновые элементы, такие как изменяющееся освещение, тени, движущиеся люди или объекты вне рабочей области, могут нарушать процесс обучения. Правильный выбор ROI должен:

- Включайте только то рабочее пространство, где выполняется задача
- Зафиксируйте конечный исполнительный орган робота и все объекты, участвующие в задаче
- Исключите ненужные фоновые элементы и отвлекающие факторы

Примечание: если вы уже знаете параметры кадрирования, вы можете пропустить этот шаг и просто задать `crop_params_dict` в файле конфигурации во время записи.

**Определение параметров кадрирования**

Используйте скрипт `crop_dataset_roi.py`, чтобы интерактивно выбрать области интереса на снимках с камеры:

```bash
python -m lerobot.rl.crop_dataset_roi --repo-id username/pick_lift_cube
```

1. Для каждого вида камеры скрипт отобразит первый кадр
2. Обведите прямоугольником соответствующую область рабочего пространства
3. Нажмите «c», чтобы подтвердить выбор
4. Повторите для всех видов камеры
5. Скрипт выводит параметры обрезки и создаёт новый обрезанный набор данных

Пример вывода:

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

  <img
    src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/crop_dataset.gif"
    width="600"
  />

  Интерактивный инструмент обрезки для выбора областей интереса

**Обновление конфигурации**

Добавьте эти параметры обрезки в конфигурацию обучения:

```json
{
  "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]
      }
    }
  }
}
```

**Рекомендуемое разрешение изображения**

Большинство политик на основе компьютерного зрения были проверены на квадратных входах размером **128×128** (по умолчанию) или **64×64** пикселей. Поэтому мы рекомендуем устанавливать параметр resize_size в значение [128, 128] – или [64, 64], если необходимо сэкономить память и пропускную способность GPU. Другие разрешения также возможны, но не были достаточно протестированы.

### Обучение классификатора вознаграждения

Классификатор вознаграждения играет важную роль в рабочем процессе HIL-SERL, автоматизируя присвоение вознаграждений и автоматическое определение успешности эпизода. Вместо ручного определения функций вознаграждения или опора на обратную связь человека для каждого шага времени, классификатор вознаграждения обучается предсказывать успех или неудачу на основе визуальных наблюдений. Это позволяет алгоритму обучения с подкреплением эффективно обучаться, предоставляя согласованные и автоматизированные сигналы вознаграждения на основе входных данных с камер робота.

В этом руководстве объясняется, как обучить классификатор вознаграждения для реализации обучения с подкреплением с участием человека в LeRobot. Классификаторы вознаграждения обучаются предсказывать значение вознаграждения по заданному состоянию, что можно использовать в настройке RL для обучения политики.

**Примечание**: Обучение классификатора вознаграждения является необязательным. Вы можете начать первый раунд экспериментов с RL, вручную размечая успех с помощью геймпада или клавиатуры.

Реализация классификатора вознаграждений в `lerobot/rewards/classifier/modeling_classifier.py` использует предобученную модель зрения для обработки изображений. Она может выводить одно значение для бинарных вознаграждений, чтобы предсказывать случаи успеха/неудачи, или несколько значений для многоклассовых сценариев.

**Сбор набора данных для классификатора вознаграждения**

Перед обучением необходимо собрать датасет с размеченными примерами. Установка `mode: "record"` в конфигурации и запуск `gym_manipulator.py` запускает процесс сбора датасета наблюдений, действий и вознаграждений.

Для сбора набора данных необходимо изменить некоторые параметры в конфигурации среды на основе HILSerlRobotEnvConfig.

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

**Ключевые параметры для сбора данных**

- **mode**: установите значение `"record"`, чтобы собрать набор данных (на корневом уровне)
- **dataset.repo_id**: `"hf_username/dataset_name"`, название набора данных и репозитория на хабе
- **dataset.num_episodes_to_record**: количество эпизодов для записи
- **env.processor.reset.terminate_on_success**: следует ли автоматически завершать эпизоды при обнаружении успеха (по умолчанию: `true`)
- **env.fps**: количество кадров в секунду для записи
- **dataset.push_to_hub**: нужно ли отправить датасет в хаб

Параметр `env.processor.reset.terminate_on_success` позволяет управлять поведением завершения эпизода. Если установить его в `false`, эпизоды будут продолжаться даже после обнаружения успеха, что позволяет собирать больше положительных примеров с меткой reward=1. Это критически важно для обучения классификаторов вознаграждения, так как в наборе данных появляется больше примеров состояний успеха. Если установить значение `true` (по умолчанию), эпизоды завершаются сразу после обнаружения успеха.

**Важно**: для обучения классификатора вознаграждения установите `terminate_on_success: false`, чтобы собрать достаточное количество положительных примеров. Для обычного обучения HIL-SERL оставьте значение `true`, чтобы обеспечить автоматическое завершение эпизода при успешном выполнении задачи.

Пример раздела конфигурации для сбора данных:

```json
{
  "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"
}
```

**Конфигурация классификатора вознаграждения**

Классификатор вознаграждения настраивается с помощью `lerobot/rewards/classifier/configuration_classifier.py`. Вот ключевые параметры:

- **model_name**: Базовая архитектура модели (например, мы в основном используем `"helper2424/resnet10"`)
- **model_type**: `"cnn"` или `"transformer"`
- **num_cameras**: количество входов камеры
- **num_classes**: количество выходных классов (обычно 2 для бинарного успеха/неудачи)
- **hidden_dim**: размер скрытого представления
- **dropout_rate**: параметр регуляризации
- **learning_rate**: Скорость обучения для оптимизатора

Пример конфигурации для обучения классификатора вознаграждения. Сохраните её как `reward_classifier_train_config.json`:

```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"
}
```

**Обучение классификатора**

Для обучения классификатора используйте скрипт `train.py` с вашей конфигурацией:

```bash
lerobot-train --config_path reward_classifier_train_config.json
```

**Развёртывание и тестирование модели**

Чтобы использовать обученный вами классификатор вознаграждения, настройте `HILSerlRobotEnvConfig` так, чтобы он использовал вашу модель:

```python
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
)
```

или задайте аргумент в файле конфигурации json.

```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
      }
    }
  }
}
```

Запустите `gym_manipulator.py`, чтобы протестировать модель.

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

Классификатор вознаграждений будет автоматически предоставлять вознаграждения на основе визуального ввода с камер робота.

**Пример рабочего процесса для обучения классификатора вознаграждения**

1. **Создайте файлы конфигурации**: Создайте необходимые json-файлы конфигурации для классификатора вознаграждения и среды: `reward_classifier_train_config.json` из примера выше и загруженный `rl/env_config.json`.

2. **Соберите набор данных**:

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

3. **Обучение классификатора**:

   ```bash
   lerobot-train --config_path reward_classifier_train_config.json
   ```

4. **Проверьте классификатор**:
   ```bash
   python -m lerobot.rl.gym_manipulator --config_path rl/env_config.json
   ```

### Обучение с Actor-Learner

Система LeRobot использует распределённую архитектуру «актёр-обучающий» для обучения. Эта архитектура разделяет взаимодействие с роботом и процесс обучения, позволяя выполнять их параллельно без взаимной блокировки. Сервер актёра обрабатывает наблюдения и действия робота, отправляя данные взаимодействия на сервер обучающего. Сервер обучающего выполняет градиентный спуск и периодически обновляет веса политики актёра. Вам необходимо запустить два процесса: обучающий и актёр.

**Настройка конфигурации**

Отредактируйте файл конфигурации обучения, который вы скачали ранее, `rl/train_config.json` (пример доступен [здесь](https://huggingface.co/datasets/lerobot/config_examples/resolve/main/rl/train_config.json)). Конфигурация обучения основана на основном классе `TrainRLServerPipelineConfig` в `lerobot/rl/train_rl.py`.

1. Настройте параметры политики (`type="gaussian_actor"`, `device` и т. д.)
2. Настройте параметры алгоритма в верхнеуровневом блоке `algorithm` (`type="sac"`, коэффициенты обучения, дисконтирование и т. д., определённые в `lerobot/rl/algorithms/sac/configuration_sac.py`).
3. Укажите `dataset` как ваш обрезанный набор данных
4. Настройте параметры окружения с параметрами обрезки
5. Проверьте другие параметры, связанные с Gaussian Actor, в [configuration_gaussian_actor.py](https://github.com/huggingface/lerobot/blob/main/src/lerobot/policies/gaussian_actor/configuration_gaussian_actor.py#L79).
6. Проверьте, что конфигурация `policy` корректна и содержит правильные `input_features` и `output_features` для вашей задачи.

**Запуск Learner**

Сначала запустите процесс сервера обучающего агента:

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

Ученик:

- Инициализирует сеть политики
- Готовит буферы воспроизведения
- Запускает `gRPC`-сервер для взаимодействия с акторами
- Обрабатывает переходы и обновляет политику

**Запуск Actor**

В отдельном терминале запустите процесс actor с той же конфигурацией:

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

Актор:

- Подключается к обучающему модулю через `gRPC`
- Инициализирует окружение
- Выполните проигрывания (rollouts) политики для сбора опыта
- Отправляет переходы обучающему
- Получает обновленные параметры политики

**Поток обучения**

Обучение выполняется автоматически:

1. Агент выполняет политику в среде
2. Переходы собираются и отправляются обучающему
3. Ученик обновляет политику на основе этих переходов
4. Обновленные параметры политики отправляются обратно в актор
5. Процесс продолжается до достижения указанного лимита шагов

**Человек в цикле**

- Ключ к эффективному обучению заключается в том, чтобы вмешательство человека обеспечивало корректирующую обратную связь и завершение задачи, что помогает обучению и исследованию политики.
- Чтобы выполнить действия человека, нажмите верхнюю правую кнопку-триггер на геймпаде (или клавишу `space` на клавиатуре). Это приостановит действия политики и позволит вам взять управление на себя.
- Успешный эксперимент — это тот, в котором человек должен вмешиваться в начале, но по мере улучшения политики частота вмешательств снижается. Вы можете отслеживать частоту вмешательств в панели Trackio (`trackio show --project <project>`).

  <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/hil_effect.png?raw=true" alt="Рисунок показывает управление на геймпаде Logitech." title="Управление с помощью геймпада" width="100%"
  >

  
    Пример, демонстрирующий, как вмешательства человека помогают направлять обучение политики со временем
  

- На рисунке показан график эпизодического вознаграждения в зависимости от шага взаимодействия. На рисунке показано влияние вмешательств человека на обучение политики.
- Оранжевая кривая представляет собой эксперимент без какого-либо вмешательства человека. Розовая и синяя кривые — это эксперименты с вмешательством человека.
- Мы можем наблюдать, что количество шагов, на которых политика начинает достигать максимального вознаграждения, сокращается на четверть при наличии вмешательств со стороны человека.

**Мониторинг и отладка**

Если в вашей конфигурации параметр `trackio.enable` установлен в значение `true`, вы можете отслеживать ход обучения в реальном времени через панель [Trackio](https://huggingface.co/docs/trackio) (`trackio show --project <project>`).

### Руководство по вмешательствам человека

Процесс обучения очень чувствителен к стратегии вмешательства. Потребуется несколько запусков, чтобы понять, как эффективно вмешиваться. Несколько советов и подсказок:

- Позвольте политике исследовать пространство действий в течение нескольких эпизодов в начале обучения.
- Старайтесь не вмешиваться в течение длительного времени. Вмешивайтесь в ситуацию, чтобы скорректировать поведение робота, когда он отклоняется от заданного курса.
- Когда политика начинает выполнять задачу, даже если результат не идеален, вы можете ограничить свои вмешательства простыми быстрыми действиями, такими как простые команды захвата.

Идеальное поведение заключается в том, что частота вашего вмешательства должна постепенно снижаться в ходе обучения, как показано на рисунке ниже.

  <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/intervention_rate_tutorial_rl.png?raw=true" alt="Частота вмешательства" title="Частота вмешательства во время обучения" width="100%"
  >

  
    График частоты вмешательства во время обучения на задаче подбора и подъёма куба
  

### Ключевые гиперпараметры для настройки

Некоторые значения конфигурации оказывают непропорционально большое влияние на стабильность и скорость обучения:

- **`temperature_init`** (`algorithm.temperature_init`) – начальная температура энтропии в SAC. Более высокие значения поощряют большее исследование; более низкие значения делают политику более детерминированной на ранних этапах. Хорошей отправной точкой является `1e-2`. Мы наблюдали, что установка слишком высокого значения может сделать человеческие вмешательства неэффективными и замедлить обучение.
- **`policy_parameters_push_frequency`** (`policy.actor_learner_config.policy_parameters_push_frequency`) – интервал в _секундах_ между двумя передачами весов от learner к actor. По умолчанию установлено значение `4 s`. Уменьшите до **1-2 s**, чтобы получать более актуальные веса (за счёт увеличения сетевого трафика); увеличивайте только при медленном соединении, так как это снизит эффективность использования данных.
- **`storage_device`** (`policy.storage_device`) – устройство, на котором learner хранит параметры политики. Если у вас есть свободная память GPU, установите это значение в `"cuda"` (вместо значения по умолчанию `"cpu"`). Хранение весов на GPU устраняет накладные расходы на передачу CPU→GPU и может значительно увеличить количество обновлений learner в секунду.

Поздравляем 🎉, вы завершили этот учебник!

> [!TIP]
> Если у вас есть вопросы или нужна помощь, напишите нам в [Discord](https://discord.com/invite/s3KuuzsPFb).

Цитирование статьи:

```
@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}
}
```

