# OpenGalaxea G0.5

G0.5 — это модель зрения, языка и действий Qwen3.5-2B, способная генерировать воплощенное рассуждение и действия в одном потоке. LeRobot представляет фазу действий как System 1, а необязательную фазу нативного цепочного рассуждения (chain-of-thought) — как System 2. Это не отдельные модели: среда выполнения получает обе фазы из одного вызова инференса, при этом действия остаются обусловленными рассуждениями.

## Обзор модели

Transformers включает в себя нативный мультимодальный бэкбон Qwen3.5, визуальную башню и процессор. Однако G0.5 — это не стандартный чекпоинт `Qwen3_5ForConditionalGeneration`: он добавляет путь проприоцепции/действия, эксперта действий, head flow-matching, ActionCodec и унифицированную декодирование CoT/действия. LeRobot реализует эти компоненты G0.5 нативно и загружает сконвертированные чекпоинты без пакетов OpenGalaxea Python, Hydra или OmegaConf.

### Что охватывает интеграция LeRobot

- Стандартная конфигурация `policy.type=g05` и загрузка контрольной точки с Hub.
- Нативная генерация непрерывного потока и дискретных действий ActionCodec.
- Необязательное рассуждение и генерация действий в режиме System 2 в рамках одного прохода.
- Сериализуемые процессоры камеры, состояния, действия, нормализации и промптов.
- Допобучение через `lerobot-train` и инференс через `lerobot-rollout`.
- LIBERO, RoboTwin, SO-101 и опубликованные контракты контрольных точек R1 Lite/Pro.

> [!WARNING]
> Код интеграции G0.5 (`src/lerobot/policies/g05`) и контрольные точки используют [G0.5 Community License](https://huggingface.co/OpenGalaxea/G05/blob/main/licenses/LICENSE-G0.5), включая ограничения на некоммерческое использование; лицензия Apache-2.0 на эти материалы не распространяется. Преобразованные контрольные точки поставляются с этой лицензией в виде файла `LICENSE` вместе с файлом `NOTICE` и не являются одобренными Galaxea.

## Чекпоинты

### Контракты ввода и вывода

| Чекпоинт       | Путь действия, который был выпущен                       | Сырой → макет политики                          | Камеры                               | Предсказано | Выполнено | Нормализация    |
| ---------------- | ------------------------------------------ | -------------------------------------------- | ------------------------------------- | --------: | -------: | ---------------- |
| `g05_base`       | Явно выбранный AR ActionCodec или flow | Совместы R1 Lite/Pro → 27D-раскладка всего тела   | голова и оба запястья, история из 6 шагов    |        32 |       16 | пошаговый z-оцен |
| `g05_libero`     | Непрерывный поток                            | правый EEF 6 + захват 1 → сгруппированная раскладка 20D | внешняя сторона, правый запястный сустав                 |        32 |       10 | постепенный q01/q99 |
| `g05_robotwin20` | Непрерывный поток                            | две руки 6+захват → сгруппированная раскладка 20D      | высокий, левый запястье, правое запястье         |        32 |        8 | постепенный q01/q99 |
| `g05_so101`      | Flow или AR ActionCodec + нативный CoT        | суставы правой руки 6 → 20D сгруппированная раскладка      | внешний, опционально левый + правый запястный |        32 |       16 | постепенный q01/q99 |

Каждый преобразованный контрольный пункт хранит конфигурацию модели и процессора, метаданные ActionCodec, статистику, точный шаблон промпта и лицензию.

### Конвертированные контрольные точки

| Репозиторий               | Договор                     |
| ------------------------ | ---------------------------- |
| `lerobot/g05_base`       | 27D base, процессор R1 Lite  |
| `lerobot/g05_libero`     | 20D LIBERO                   |
| `lerobot/g05_robotwin20` | 20D RoboTwin                 |
| `lerobot/g05_so101`      | 20D SO-101 (профиль `so100`) |

Эти контрольные точки распространяются по некоммерческой [G0.5 Community License](https://huggingface.co/OpenGalaxea/G05/blob/main/licenses/LICENSE-G0.5); см. [License](#license).

`lerobot/g05_base` предоставляет эти веса модели 27D, оба action heads, токенизатор ActionCodec и опубликованный контракт процессора/статистики R1 Lite на шесть шагов.

## Требования к установке

Установите LeRobot с зависимостью G0.5 Transformers:

```bash
uv sync --extra g05 --extra test
```

> [!TIP]
> Install [`flash-linear-attention`](https://github.com/fla-org/flash-linear-attention) for training and inference on GPU. Most Qwen3.5 decoder layers are Gated DeltaNet linear attention, and without it Transformers falls back to a much slower PyTorch kernel, logging "The fast path is not available". It is pure Triton, so it installs without a build:
>
> ```bash
> uv pip install flash-linear-attention
> ```
>
> Обучение с ним примерно в 1,5 раза быстрее и требует меньше памяти, при этом потери идентичны. Первый шаг занимает примерно на 20 с дольше, пока Triton компилирует свои ядра.

SO-100 и SO-101 используют общий выпущенный токен воплощения `so100` и контракт для правого шести-суставного манипулятора. Отсутствие камеры на левом запястье компенсируется нулевым дополнением.

## Использование

Загрузите контрольную точку, соответствующую целевой эмподиментации, с помощью стандартного параметра `--policy.path`. Встроенная конфигурация выбирает правильный action head, порядок камер, размерности, нормализацию и горизонт выполнения.

### Интерактивная среда выполнения System 1 и System 2

G0.5 генерирует рассуждения и действия из одного потока вывода: цепочка рассуждений формируется в том же проходе, что и фрагмент, а действие зависит от неё.

`policy.runtime_system` в контрольной точке выбирает путь. Система 1 выполняет выбранный ActionCodec или фрагмент потока напрямую и не генерирует CoT:

```bash
lerobot-rollout \
  --policy.path=lerobot/g05_so101 \
  --policy.runtime_system=system1 \
  --task="pick up the cup" \
  --fps=30
```

System 2 доступен только при наличии в метаданных упакованного чекпоинта `predict_cot=true`. Его цепочка рассуждений возвращается как предсказание политики: `predict_action_chunk` возвращает батч `PolicyOutput`, содержащий чанк под ключом `"action"` и, под ключом `"prediction"`, подзадачу CoT каждого окружения (`language["subtask"]`, одна строка на окружение) и боксы в виде дробей xyxy в диапазоне [0, 1] на `policy.config.bbox_camera` (`boxes[camera]`, один ответ на окружение), а `select_action` возвращает его вместе с первым действием каждого чанка. Модель не указывает камеру: её целевые BBox рисуются на этой камере во время обучения. System 1 не генерирует CoT и возвращает только действия.

```python
output = policy.predict_action_chunk(batch)
print(output["prediction"])
# {"language": {"subtask": ["grasp the cup"]},
#  "boxes": {"observation.images.top": [{"detections": [{"label": "cup", "bbox": [...]}]}]}}
```

С флагом `--display_data=true` команда `lerobot-rollout` отображает подзадачу и рисует рамки поверх изображения с камеры bbox в Rerun или Foxglove.

#### Управление сессией из stdin

`--interactive=true` управляет rollout с помощью команд в чат-формате, пока аппаратная часть и политика остаются подключёнными и «тёплыми». Робот не начинает двигаться, пока вы не введёте `/start`, что делает этот способ безопасным для запуска физического SO-101: сначала подтвердите индексы камер и порт руки, затем запустите.

```bash
lerobot-rollout \
  --interactive=true \
  --policy.path=lerobot/g05_so101 \
  --policy.device=cuda \
  --robot.type=so101_follower \
  --robot.port=/dev/ttyACM0 \
  --robot.id=my_follower \
  --robot.cameras='{exterior: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist_right: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30}}' \
  --task="pick up the cube" \
  --fps=30
```

| Команда                  | Эффект                                                         |
| ------------------------ | -------------------------------------------------------------- |
| `/start`                 | запустить (или перезапустить) цикл управления политикой                     |
| `/subtask <text>`        | установите инструкцию, которой следует политика                         |
| `/vqa <text>`            | не поддерживается на G0.5 (см. [ниже](#why-vqa-is-not-supported)) |
| `/autosteer <goal>\|off` | позволить политике самостоятельно выбирать подзадачи для достижения высокоуровневой цели  |
| `/reset`                 | остановить движение, вернуться в исходное положение, восстановить задачу    |
| `/stop`                  | завершить сеанс и остановить                                  |
| `/help`                  | показать список команд                                          |

`/autosteer` требует контрольную точку с `predict_cot=true` и ответы из живого наблюдения, поэтому он отклоняется, пока не запущен `/start`. Он выводит выбранный подзадачу как `Autosteer subtask:`, а `--autosteer_interval_s` задаёт, сколько секунд движения проходит между двумя запросами повторного планирования.

Выберите среду выполнения в соответствии с тем, как была поставлена задача при обучении G0.5:

- **Высокоуровневая задача, без управления:** сохраняйте System 2. Каждый фрагмент предсказывает текущий подзадачу из задачи, а затем действует на её основе.
- **`/subtask` или `/autosteer`:** используйте `--policy.runtime_system=system1`. Подзадача становится задачей, и политика действует на неё напрямую; `/autosteer` по-прежнему планирует каждую подзадачу из цели с помощью запроса System 2. System 2 для подзадачи-как-задачи спланировал бы подзадачу подзадачи, промпт, на котором он не обучался.

#### Выбор цепочки рассуждений

`--policy.runtime_cot_fields` определяет, какой из обученных форматов цепочки рассуждений (chain-of-thought) G0.5 генерирует System 2 перед каждым чанком. Действие обращает внимание на всю цепочку рассуждений, поэтому всё, что в ней содержится, влияет на выбор действия.

| `runtime_cot_fields`    | Обученная инструкция                | Сгенерированная цепочка рассуждений |
| ----------------------- | ---------------------------------- | -------------------------- |
| `["subtask"]` (по умолчанию) | `predict subtask`                  | подзадача                |
| `["bbox", "subtask"]`   | `predict bbox, subtask and action` | boxes, затем подзадача    |

Например, `["bbox", "subtask"]` генерирует:

```text
BBox: cube <loc0397><loc0717><loc0625><loc0895>|Subtask: pick up the blue cube
```

- **`["subtask"]`** генерирует наименьшее количество токенов на чанк, поэтому это более быстрый вариант.
- **`["bbox", "subtask"]`** сначала находит соответствующие объекты, что привязывает подзадачу и действие к сцене. Каждая рамка — это метка, за которой следуют четыре токена координат в порядке `y1, x1, y2, x2`; токен `<locNNNN>` представляет собой координату как долю размера изображения, умноженную на 1024. Рамки относятся к камере BBox (`--policy.cot_bbox_camera`, по умолчанию — первый непустой слот камеры).

`lerobot/g05_base` и `lerobot/g05_so101` обучены на обоих форматах; чекпоинты LIBERO и RoboTwin имеют `predict_cot=false` и не содержат System 2. Дообучение даёт полезные рамки только если его датасет содержал привязанные `vqa` аннотации на камере BBox (см. [Требования к данным](#data-requirements)).

#### Почему `/vqa` не поддерживается

Текстовая голова G0.5 не является универсальным ассистентом для задач зрения и языка. Она обучалась выдавать только перечисленные выше форматы цепочки рассуждений после одной из их фиксированных инструкций, а в её промпте нет места для свободного вопроса. Вопрос `/vqa` может занять только место задачи, поэтому модель ответит подзадачей (и рамками) для этой «задачи», а не ответом. `/autosteer` работает, потому что его цель — это задача, что и ожидается в этом слоте.

В интерактивном режиме `--duration` ограничивает каждый сегмент `/start`, а не всю сессию.

## Требования к данным

Набор данных должен предоставлять признаки состояния, действия, камеры и задачи, соответствующие контракту выбранной контрольной точки. Названия камер задаются свободно: `--policy.camera_order` перечисляет камеру из набора данных, которая заполняет каждый из слотов изображений контрольной точки, а `null` оставляет слот пустым (заполненным нулями). Для SO-101 слотами являются exterior, left wrist и right wrist; слот left wrist является необязательным.

Обучение System 2 language targets дополнительно требует аннотированных полей CoT в контрольной точке. Обычная запись LeRobot обеспечивает надзор за действиями, но не синтезирует метки CoT. Сгенерируйте столбцы `subtask` и `vqa` с привязкой к контексту с помощью `lerobot-annotate`, как описано в [конвейере аннотирования](./annotation_pipeline).

## Обучение

G0.5 нативно реализует поверхность обучения LeRobot: `forward` вычисляет кросс-энтропию для assistant-токенов и потерю flow-matching, политика предоставляет группы оптимизаторов для VLM/зрения/действий, а чекпоинт можно сохранить, возобновить и загрузить с помощью стандартных скриптов LeRobot. Целевая функция сохраняет упакованные `ar.ce_weight`, необязательный `ar.ce_z_loss_scale` и `fm.fm_weight`; авто-регрессивная потеря совместно покрывает цели CoT-текста и ActionCodec. Например, дообучите чекпоинт SO-101 на датасете LeRobot:

### Пример команды обучения

```bash
export HF_USER=your_hf_username

lerobot-train \
  --dataset.repo_id=${HF_USER}/my_so101_dataset_annotated \
  --policy.path=lerobot/g05_so101 \
  --policy.device=cuda \
  --policy.use_language_recipe=true \
  --policy.cot_bbox_camera=observation.images.exterior \
  --policy.repo_id=${HF_USER}/g05_so101_finetuned \
  --policy.private=true \
  --output_dir=outputs/train/g05_so101 \
  --job_name=g05_so101 \
  --batch_size=16 \
  --steps=10000 \
  --save_freq=1000
```

Встроенный рецепт смешивает три типа образцов, как и исходный тренировочный микс:

- 4/6 цепочка рассуждений: сначала задача, затем цель BBox и/или Subtask для аннотаций `subtask` и `vqa` с привязкой к объектам, активных на данный момент времени, и, наконец, действия.
- 1/6 подзадача как задача: активная подзадача является инструкцией, сразу к действиям. Это то, что видит политика, когда `/subtask` или `/autosteer` задаёт подзадачу.
- 1/6 plain: задача сразу переходит к действиям, промпт Системы 1.

Образец цепочки рассуждений без аннотации на момент времени обучает обычный промпт.

Сгенерируйте необходимые столбцы `subtask` и `vqa` с привязкой к контексту с помощью `lerobot-annotate`, как описано в [конвейере аннотирования](./annotation_pipeline). Встроенный рецепт читает рамки, размеченные на камере BBox: `--policy.cot_bbox_camera`, по умолчанию используется первый непустой слот камеры. Координаты рамок должны быть дробями от ширины и высоты изображения в диапазоне `[0, 1]`, именно так их сохраняет `lerobot-annotate`; пиксельные рамки отклоняются. Чтобы обучить другой рецепт, передайте внешний YAML-файл явно через `--policy.recipe_path=/path/to/recipe.yaml`: он загружается один раз в `policy.recipe` при построении конфигурации, поэтому сохранённый чекпоинт сохраняет рецепт, с которым он обучался, даже если файл изменится позже.

### Доработка базовой контрольной точки на другом роботе

`lerobot/g05_base` можно дообучить на роботе, с которым модель ранее не сталкивалась. Укажите имя робота с помощью `--policy.embodiment`, например, значение `robot_type` из набора данных; это имя используется как текст `Embodiment:` в промпте. Флаг обязателен: без него чекпоинт сохраняет собственное воплощение и таблицу слотов. Суставы размещаются в базовой раскладке на основе имён суставов из набора данных: суставы с префиксом `left_` назначаются левому манипулятору, остальные — правому; сустав, в имени которого есть `gripper`, занимает слот захвата соответствующего манипулятора, а остальные заполняют его девять управляющих слотов по порядку. Таким образом, манипулятор с 5 суставами и захватом заполняет слоты 10–14 правого манипулятора и слот правого захвата, а манипулятор с 7 степенями свободы — слоты 10–16 и слот захвата. Используйте `--policy.state_slots` и `--policy.action_slots`, чтобы явно указать расположение суставов. Разрешённые слоты сохраняются вместе с дообученным чекпоинтом.

Пример ниже выполняет дообучение на одном-ручном роботе, записанном с помощью камеры `front` и камеры `wrist`. Слоты изображений в базовой контрольной точке — это вид с головы, левый запястный и правый запястный; одна рука находится справа, поэтому её запястная камера занимает слот правого запястья, а слот левого запястья остаётся пустым. Флаги со списком значений принимают JSON в кавычках.

```bash
lerobot-train \
  --dataset.repo_id=${HF_USER}/my_robot_dataset_annotated \
  --policy.path=lerobot/g05_base \
  --policy.embodiment=my_robot \
  --policy.camera_order='["observation.images.front", null, "observation.images.wrist"]' \
  --policy.n_obs_steps=1 \
  --policy.use_language_recipe=true \
  --policy.device=cuda \
  --policy.repo_id=${HF_USER}/g05_my_robot_finetuned \
  --output_dir=outputs/train/g05_my_robot \
  --job_name=g05_my_robot \
  --batch_size=16 \
  --steps=10000
```

`--policy.n_obs_steps=1` передаёт один кадр с каждой камеры, как и в исходных процессах дообучения; шестиступенчатая история базовой контрольной точки увеличивает количество изображений на образец в шесть раз.

Нормализация использует собственные статистические данные набора данных (z-score для базовой контрольной точки; для q01/q99 передайте `--policy.normalization_mapping='{"VISUAL": "IDENTITY", "STATE": "QUANTILES", "ACTION": "QUANTILES"}'`). Захватчик остаётся абсолютным (`relative_exclude_joints=["gripper"]` в базовой контрольной точке), тогда как суставы руки обучаются как дельты. Целевые значения BBox берутся из привязанных к объектам ответов `vqa`, размеченных на `observation.images.front`, первом непустом слоте камеры.

Рецепт SO-101 использует AdamW с `8e-5` и 1000 шагами разгона. Встроенные конфигурации LIBERO и RoboTwin используют опубликованный рецепт `1e-5` с 1000 и 500 шагами разгона соответственно. Все профили сохраняют группы параметров и множители скорости обучения G0.5. Переопределите их, чтобы обучать с другим рецептом оптимизации:

```bash
--policy.optimizer_lr=2e-5 \
--policy.optimizer_backbone_lr_multiplier=0.5 \
--policy.optimizer_vision_lr_multiplier=0.1
```

Возобновите сохранённый прогон с помощью стандартного контрольного пункта LeRobot:

```bash
lerobot-train \
  --config_path=outputs/train/g05_so101/checkpoints/last/pretrained_model/train_config.json \
  --resume=true
```

## Ключевые параметры конфигурации

| Параметр                                   | Описание                                                       |
| ------------------------------------------- | ----------------------------------------------------------------- |
| `policy.embodiment`                         | Имя робота, указанное в промпте; выбирает опубликованную таблицу слотов   |
| `policy.state_slots`, `policy.action_slots` | Явный слот policy-layout для каждого необработанного значения состояния/действия        |
| `policy.camera_order`                       | Слот изображения камеры датасета для контрольной точки; `null` оставляет его пустым  |
| `policy.action_head`                        | Использует путь действия `flow` или `actioncodec` из контрольной точки         |
| `policy.runtime_system`                     | Выбирает прямое рассуждение и действие в режиме System 1 или объединённое рассуждение и действие в режиме System 2  |
| `policy.runtime_cot_fields`                 | Цепочка рассуждений System 2: `["subtask"]` или `["bbox", "subtask"]` |
| `policy.dtype`                              | `bfloat16` (смешанная точность на CUDA) или `float32`        |
| `policy.chunk_size`                         | Количество предсказанных действий в каждом чанке                         |
| `policy.n_action_steps`                     | Количество действий, выполненных перед повторным планированием                      |
| `policy.use_language_recipe`                | Включить встроенный рецепт языкового надзора G0.5                |
| `policy.recipe_path`                        | Файл рецепта YAML загружается один раз в `policy.recipe` (не сохраняется)            |
| `policy.optimizer_backbone_lr_multiplier`   | Множитель скорости обучения для языковой основы                |
| `policy.optimizer_vision_lr_multiplier`     | Множитель скорости обучения для визуальной башни                     |

Голова действий, размерности, горизонт, режимы процессора и нормализация берутся из контрольной точки; несовместимые переопределения отклоняются при загрузке.

## Оценка

После установки симулятора LIBERO оцените контрольную точку LIBERO с использованием его имён камер и относительного управления:

```bash
lerobot-eval \
  --policy.path=lerobot/g05_libero \
  --policy.device=cuda \
  --env.type=libero \
  --env.task=libero_10 \
  --env.control_mode=relative \
  --env.observation_height=512 \
  --env.observation_width=512 \
  '--env.camera_name_mapping={"agentview_image": "image", "robot0_eye_in_hand_image": "wrist_image"}' \
  --eval.batch_size=1 \
  --eval.n_episodes=5 \
  --seed=0 \
  --output_dir=outputs/g05-libero-lerobot-eval
```

## Ссылки

- [Модель OpenGalaxea G0.5](https://huggingface.co/OpenGalaxea/G05)
- [Репозиторий OpenGalaxea G0.5](https://github.com/OpenGalaxea/GalaxeaVLA)
- [Конвейер аннотирования языка в LeRobot](./annotation_pipeline)

## Лицензия

Код интеграции G0.5 в `src/lerobot/policies/g05` адаптирован из реализации Galaxea и, как и веса контрольных точек, распространяется по лицензии [G0.5 Community License](https://huggingface.co/OpenGalaxea/G05/blob/main/licenses/LICENSE-G0.5), а не по Apache-2.0 LeRobot. Перед загрузкой или использованием контрольной точки ознакомьтесь с условиями этой лицензии и примите их.

Fine-tune является производной работой от G0.5. При его распространении включайте файлы `LICENSE` и `NOTICE` из чекпоинта, от которого он был получен: LeRobot не копирует их за вас, но в сгенерированной карточке модели указана лицензия.

