
Проверенное пошаговое руководство по тонкой настройке NVIDIA GR00T N1.7 на наборе данных LeRobot SO-100: реальные флаги, modality.json, требование v2.1, стоимость запуска и подводные камни.
NVIDIA поставляет пример тонкой настройки именно для того манипулятора, который у вас, вероятно, есть. Внутри репозитория Isaac-GR00T находится папка под названием demo_data/cube_to_bowl_5: пять эпизодов, 4148 кадров при 30 fps, уже записанных в формате LeRobot v2.1, с соответствующей конфигурацией модальности в examples/SO100/. Его meta/info.json сообщает robot_type: so101_follower, что в LeRobot является тем же классом конфигурации, что и so100_follower. Это действительно полезно, потому что это означает, что эталонный путь для GR00T N1.7 для шести-степеней свободы любительского манипулятора поддерживается людьми, которые написали модель. Это не уменьшенная демонстрация гуманоида, это тот же манипулятор.
Плохая новость заключается в расстоянии между I recorded 60 episodes и the arm does the task. Существует около шести мест, где этот конвейер завершается сбоем тихо, а не громко, и четыре из них находятся в файлах, которые большинство людей никогда не открывают: meta/modality.json, конфигурация данных Python, meta/relative_stats.json, и собственная строка версии набора данных. Это руководство описывает ручной маршрут от начала до конца с реальными командами, а затем показывает ту же задачу в виде формы на AY-Robots. Все нижеизложенное было проверено на соответствие основной ветке Isaac-GR00T по состоянию на 20 августа 2026 года (линия n1.7-release) и lerobot 0.6.1, опубликованному в PyPI 3 августа 2026 года. Разработка идет быстро, и если какой-либо флаг был переименован, об этом говорится в данной статье.
Что нужно знать перед началом работы
- •Для тонкой настройки GR00T N1.7 требуется 40 GB или более видеопамяти. NVIDIA рекомендует узлы H100 или L40. RTX 4090 с 24 GB не справится с этой задачей, хотя она может обучать SmolVLA и ACT.
- •Набор данных должен быть LeRobot v2 (v2.0 или v2.1) плюс GR00T-специфичный meta/modality.json. Набор данных LeRobot v3.0 не загружается и должен быть преобразован в более раннюю версию.
- •Точкой входа является gr00t/experiment/launch_finetune.py, CLI tyro. У него нет флага --seed, поэтому запуски не являются побитово воспроизводимыми.
- •Для пользовательского манипулятора тег воплощения — NEW_EMBODIMENT, и этот тег делает --modality-config-path обязательным.
- •Поставляемый рецепт SO-100 предсказывает суставы манипулятора как RELATIVE дельты, а захват — как ABSOLUTE цель. Обратное сопоставление является тихим сбоем, а не ошибкой.
- •На AY-Robots та же задача представляет собой форму: 20000 steps, batch 32, learning rate 1e-4, примерно от 4 до 12 USD на уровне A100 80 GB или H100.
Что на самом деле представляет собой GR00T N1.7
GR00T N1.7 — это визуально-языковая модель действий с двухсистемной архитектурой, описанной в оригинальной статье GR00T N1: визуально-языковой модуль, который считывает данные с камер и инструкцию, и диффузионный трансформер, который преобразует это в блок непрерывных моторных команд. N1.7 заменил первую половину. Бэкенд Eagle из N1.6 был удален, заменен на nvidia/Cosmos-Reason2-2B на архитектуре Qwen3-VL, и модель была предварительно обучена на примерно 20 000 часах эгоцентрического человеческого видео в дополнение к данным робота. В собственном отчете NVIDIA эта цифра составляет 20 854 часа и сообщается, что переход от 1 тыс. до 20 тыс. часов более чем удваивает среднее выполнение задач.
Вторая половина также изменилась, и эти изменения важны для вашего запуска. Голова действий уменьшилась с 32 диффузионных слоев до 16, предсказанный блок действий увеличился с 16 шагов до 40, а максимальная ширина состояния и действия увеличилась с 29 до 132. Эти три числа взяты из журнала изменений в README репозитория; собственный пост NVIDIA о запуске по-прежнему описывает Систему 1 как 32-слойный DiT, поэтому в случае расхождений доверяйте репозиторию, который вы собираетесь клонировать. Действия по умолчанию выражаются в относительном пространстве конечного эффектора, дельтах от текущей позы, а не абсолютных целях, что позволяет вообще переносить априорные знания о манипуляциях, полученные из человеческого видео, в управление роботом. Сама голова представляет собой сопоставление потоков диффузионный трансформер, того же семейства, что и Pi0.5, но с другим бэкендом перед ним. Если вы все еще используете предыдущее поколение, N1.7 против N1.5 описывает, оправдывает ли обновление переделку вашего конвейера.
| Свойство | Значение | Источник |
|---|---|---|
| Параметры | 3,000,000,000 | Hugging Face model card |
| Визуально-языковой бэкенд | nvidia/Cosmos-Reason2-2B (Qwen3-VL), gated on Hugging Face | repo README |
| Голова действий | Flow-matching diffusion transformer, 16 layers (N1.6 had 32) | repo README |
| Горизонт предсказанных действий | 40 steps for the base checkpoint (N1.6 had 16) | getting_started/policy.md and repo README |
| Максимальная ширина состояния и действия | 132 (N1.6 had 29) | repo README |
| Лицензия на код | Apache 2.0 | Isaac-GR00T repository |
| Лицензия на веса | NVIDIA Open Model License Agreement | model card |
| Задержка, H100 80 ГБ, PyTorch eager, 4 шага денойзинга, 1 камера | 85.8 ms end to end, 11.7 Hz | model card timing table |
| То же оборудование, полный конвейер TensorRT | 27.9 ms end to end, 35.9 Hz | model card timing table |
| Задержка, которую AY-Robots указывает для своего обслуживаемого GR00T N1.7 | 152 ms per action step | AY-Robots policy catalog |
Эти последние три строки объясняют большую часть разочарования, о котором сообщают люди. Заявленные 27.9 ms — это движок TensorRT на H100 с одной камерой и четырьмя шагами денойзинга. Обычный PyTorch на той же карте дает 85.8 ms, и карточка модели указывает на разрыв в 3.08x. Ни одно из этих чисел не включает слой обслуживания, вторую камеру или сетевой переход. 152 ms на шаг действия, которые AY-Robots указывает для своего обслуживаемого GR00T N1.7, — это показатель с обслуживанием в цикле, и к этому добавляется время кругового обхода по публичному интернету. Подробнее об этом в конце. Что касается чисел рядом с другими моделями, GR00T N1.7 против Pi0.5 и GR00T N1.7 против SmolVLA представляют их рядом.

Что требуется для запуска, прежде чем вы что-либо напечатаете
| Требование | Дообучение | Вывод |
|---|---|---|
| VRAM, рекомендации NVIDIA | 40 ГБ или более, рекомендуется H100 или L40 | 16 ГБ или более, работает RTX 4090 |
| Python и CUDA на dGPU | 3.12 и CUDA 12.8 | 3.12 и CUDA 12.8 |
| Видео бэкенд | torchcodec 0.8.0, только FFmpeg от 4 до 7 | то же |
| Формат набора данных | LeRobot v2 плюс meta/modality.json | неприменимо |
| Доступ к Hugging Face | одобрено для nvidia/Cosmos-Reason2-2B | то же |
| Другие инструменты | git-lfs и uv | uv |
| Уровень GPU AY-Robots для тренера groot1.7 | A100 80 ГБ или H100 80 ГБ | под автоматически выделяется |
Каждый чекпоинт GR00T, включая базовый nvidia/GR00T-N1.7-3B, при первом использовании загружает nvidia/Cosmos-Reason2-2B, и этот репозиторий является закрытым. В README точно указана причина сбоя: загрузка модели завершается ошибкой GatedRepoError / 401 Client Error. Что не упоминается, так это когда это происходит, а именно после того, как вы арендовали карту и запуск начался. Запросите доступ на странице модели, затем выполните uv run huggingface-cli login или экспортируйте HF_TOKEN, прежде чем что-либо арендовать.
Шаг 0: сами эпизоды
Все нижеизложенное предполагает, что у вас уже есть записанные эпизоды. Если нет, то это настоящий первый шаг, и именно он определяет, насколько хорошим может быть результат, потому что обучение с имитацией не может восстановить информацию, которой нет в данных. Сначала откалибруйте обе руки, затем управляйте ведомой рукой с помощью ведущей руки пока lerobot-record записывает файлы parquet и потоки с камер. Если калибровка неточна, значения суставов в вашем наборе данных описывают немного другого робота, чем тот, который позже будет выполнять политику, и никакое количество обучения это не исправит.
lerobot-record \
--robot.type=so100_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=my_follower_arm \
--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30}}" \
--teleop.type=so100_leader \
--teleop.port=/dev/ttyACM1 \
--teleop.id=my_leader_arm \
--dataset.repo_id=${HF_USER}/cube-into-bowl \
--dataset.num_episodes=60 \
--dataset.single_task="put the cube in the yellow bowl" \
--display_data=trueСобственный совет LeRobot — записывать не менее 50 эпизодов, примерно по 10 на каждое местоположение объекта, держать камеры неподвижными и сохранять постоянное поведение захвата. Добавляйте вариации позже, а не в начале. Стоит запомнить эмпирическое правило: если вы не смогли выполнить задачу самостоятельно, используя только изображения с камеры, то политика тоже не сможет. Для настройки, специфичной для манипулятора, начало работы с SO-100 и страница LeRobot для SO-100 охватывают порты, калибровку и индексы камер. На AY-Robots вы также можете сделать это через интернет из браузера, используя телеуправление и записывать прямо из сессии.
Шаг 1: набор данных должен быть LeRobot v2.1
Это самое распространенное препятствие. Текущая CODEBASE_VERSION LeRobot в основной ветке — это v3.0, поэтому все, что вы записываете сегодня с помощью текущего набора инструментов, выходит как v3.0. Загрузчик GR00T ожидает v2. Репозиторий явно объясняет причину: многие вышестоящие наборы данных, такие как DROID, LIBERO и Bridge, опубликованы в v2, и нативная поддержка обоих планируется, но еще не реализована. Таким образом, преобразование лежит на вас, и оно выполняется в собственном виртуальном окружении по конкретной причине: scripts/lerobot_conversion имеет свой собственный pyproject, который требует Python 3.10 или 3.11 и привязывает lerobot к одному коммиту git, в то время как сам Isaac-GR00T требует Python 3.12. Установите конвертер из корня репозитория, и вы получите пакет gr00t вместо того, что является ошибкой, о которой предупреждает его README. Если вы новичок в формате, набор данных LeRobot запись в глоссарии объясняет, что на самом деле находится внутри.
# from the Isaac-GR00T repo root
cd scripts/lerobot_conversion
uv venv
source .venv/bin/activate
uv pip install -e . --verbose
# pulls the dataset from the Hub and writes a v2.1 copy into the default cache
python convert_v3_to_v2.py --repo-id <your-hf-user>/<your-dataset>
# or, back in the repo root, keep it next to the SO-100 example
uv run --project scripts/lerobot_conversion \
python scripts/lerobot_conversion/convert_v3_to_v2.py \
--repo-id <your-hf-user>/<your-dataset> \
--root examples/SO100/my_dataset_lerobotЕсли набор данных v3.0 уже существует локально, скрипт создает макет v2.1 рядом с ним, а затем меняет их местами: оригинал перемещается в соседнюю папку с добавленной версией, <name>_v3.0, а преобразованная копия занимает исходный путь. (Собственный docstring скрипта называет эту папку _v30; код добавляет строку версии, поэтому вы фактически получаете _v3.0.) Второй сюрприз: вывод всегда попадает в <root>/<repo-id>, поэтому --root examples/SO100/my_dataset_lerobot дает вам examples/SO100/my_dataset_lerobot/<your-hf-user>/<your-dataset>, и этот более длинный путь является тем, что позже требуется для --dataset-path. Когда задание обучения отклоняет ваш набор данных по причинам версии, страница «набор данных отклонен как v3» перечисляет точные симптомы.
Структура, которую GR00T ожидает после преобразования, — это классический макет v2: meta/info.json, meta/episodes.jsonl, meta/tasks.jsonl, файлы parquet в data/chunk-000/, файлы MP4 в videos/chunk-000/observation.images.
Шаг 2: modality.json, шесть чисел, которые решают всё
В наборе данных LeRobot состояние робота и действие хранятся в виде плоских массивов float32. Для SO-100 оба имеют форму [6]: пять суставов руки и захват. Демонстрационный набор данных называет их shoulder_pan.pos, shoulder_lift.pos, elbow_flex.pos, wrist_flex.pos, wrist_roll.pos, gripper.pos, но эти имена находятся в info.json, и ничто в файле parquet не указывает, какой индекс соответствует чему. meta/modality.json предоставляет это сопоставление, и GR00T не будет обучаться без него. Вот тот, который поставляется в репозитории для SO-100, дословно.
{
"state": {
"single_arm": {
"start": 0,
"end": 5
},
"gripper": {
"start": 5,
"end": 6
}
},
"action": {
"single_arm": {
"start": 0,
"end": 5
},
"gripper": {
"start": 5,
"end": 6
}
},
"video": {
"front": {
"original_key": "observation.images.front"
},
"wrist": {
"original_key": "observation.images.wrist"
}
},
"annotation": {
"human.task_description": {
"original_key": "task_index"
}
}
}Скопируйте его в ваш преобразованный набор данных по адресу meta/modality.json и переименуйте ключи видео в соответствии с фактическими названиями ваших камер. Если вы записывали с помощью одной верхней камеры под названием top, тогда original_key это observation.images.top а понятное имя — это то, на что будет ссылаться ваша конфигурация данных. Эти два значения должны совпадать, и ни одно из них не проверяет другое за вас. Языковая аннотация хуже, потому что один и тот же ключ должен появляться в трех местах.
| Уровень | Файл | Форма SO-100, используемая в репозитории |
|---|---|---|
| Столбец Parquet | data/chunk-*/episode_*.parquet | annotation.human.task_description |
| Ключ modality.json | meta/modality.json, под "annotation", без префикса annotation. | human.task_description |
| modality_keys в конфигурации данных | your so100_config.py | annotation.human.task_description |
Сегменты после annotation. выбираются автором набора данных. Демонстрационные данные SO-100 используют annotation.human.task_description; LIBERO и SimplerEnv используют annotation.human.action.task_description. Оба варианта действительны. Если вы скопировали конфигурацию из примера LIBERO и указали ее на свою собственную запись SO-100, языковой канал не разрешится ни во что, и модель будет обучаться на пустой инструкции. Потери все равно уменьшаются. Политика все равно что-то делает. Она просто игнорирует то, что вы ей сказали сделать.
Шаг 3: конфигурация данных, относительная рука и абсолютный захват
Конфигурация модальности — это файл Python, а не JSON, потому что она также определяет, как представляется каждая группа действий. Это та часть рабочего процесса N1.7, которая не существовала в той же форме в N1.5, и та часть, которую стоит прочитать дважды. Поставляемая конфигурация SO-100 предсказывает пять суставов манипулятора как RELATIVE дельты от текущего состояния, а захват как ABSOLUTE целевую позицию, потому что бинарный сигнал открытия/закрытия лучше работает как цель, чем как дельта.
from gr00t.configs.data.embodiment_configs import register_modality_config
from gr00t.data.embodiment_tags import EmbodimentTag
from gr00t.data.types import (
ActionConfig, ActionFormat, ActionRepresentation, ActionType, ModalityConfig,
)
so100_config = {
"video": ModalityConfig(
delta_indices=[0], # current frame only
modality_keys=["front", "wrist"], # must match modality.json
),
"state": ModalityConfig(
delta_indices=[0],
modality_keys=["single_arm", "gripper"],
),
"action": ModalityConfig(
delta_indices=list(range(0, 16)), # predict 16 future steps
modality_keys=["single_arm", "gripper"],
action_configs=[
ActionConfig(rep=ActionRepresentation.RELATIVE, # arm joints
type=ActionType.NON_EEF,
format=ActionFormat.DEFAULT),
ActionConfig(rep=ActionRepresentation.ABSOLUTE, # gripper
type=ActionType.NON_EEF,
format=ActionFormat.DEFAULT),
],
),
"language": ModalityConfig(
delta_indices=[0],
modality_keys=["annotation.human.task_description"],
),
}
register_modality_config(so100_config, embodiment_tag=EmbodimentTag.NEW_EMBODIMENT)Две детали здесь обойдутся вам в день, если вы их не знаете. Во-первых, action_configs является позиционным: документация требует той же длины и того же порядка, что и modality_keys, и они прямо говорят о последствиях ошибки: неправильное представление применяется без уведомления. Ваш захват обучается как дельта, а ваш манипулятор — как абсолютная цель, и при этом нет сообщения об ошибке. Во-вторых, register_modality_config утверждает, что тег еще не зарегистрирован, поэтому вторая конфигурация NEW_EMBODIMENT в том же процессе Python завершается с ошибкой Embodiment tag ... already registered. Вы не можете импортировать две такие конфигурации в один скрипт. Третье правило применяется позже, при развертывании: delta_indices должны быть непрерывным диапазоном, начинающимся с нуля. Разреженное окно, такое как [0, 4, 8], отклоняется, потому что все последующие компоненты индексируют предсказанный фрагмент линейно и в противном случае выполняли бы неправильные строки.
Статистика нормализации, в частности meta/relative_stats.json, вычисляется для той длины горизонта, которая была у вас при их генерации. Сократите горизонт действий с 16 до 8 без перегенерации, и обучение завершится с ошибкой IndexError: boolean index did not match indexed array ... dimension is 8 but corresponding boolean dimension is 16. Решение — одна команда: python gr00t/data/stats.py --dataset-path <path> --embodiment-tag NEW_EMBODIMENT --modality-config-path examples/SO100/so100_config.py. Запускайте ее после любого изменения delta_indices.
Шаг 4: окружение
N1.7 переместил репозиторий в uv и Python 3.12. Старый путь через conda плюс pip install -e . все еще существует в свернутом разделе README, но предупреждает, что зависимости GPU, включая flash-attn и TensorRT, могут потребовать ручной установки. Используйте uv, если у вас нет особой причины не делать этого. Что касается flash-attn, одна деталь поможет избежать путаницы: вы увидите Installing flash-attn выводимым при каждом uv run. Это не пересборка. uv повторно проверяет закрепленный по URL wheel, который уже кэширован, и это занимает две-три секунды.
- 1Установите git-lfs, затем клонируйте с подмодулями
git-lfs является обязательным, а не опциональным. Без него файлы parquet в demo_data/ загружаются как заглушки-указатели, и демонстрационный запуск завершается ошибкой на наборе данных, который выглядит присутствующим в списке файлов.
bashsudo apt install git-lfs && git lfs install git clone --recurse-submodules https://github.com/NVIDIA/Isaac-GR00T cd Isaac-GR00T - 2Установите uv и синхронизируйте окружение
Установка по умолчанию подтягивает зависимости GPU, включая flash-attn и TensorRT. На чистом образе A100 или H100 это самый долгий отдельный шаг, поэтому выполните его, прежде чем обращать внимание на что-либо еще.
bashcurl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get update && sudo apt-get install -y ffmpeg uv sync --python 3.12 uv run python -c "import gr00t; print('GR00T installed successfully')" - 3Аутентификация в Hugging Face
Сделайте это до первого запуска обучения, а не после того, как оно завершится ошибкой через восемь минут.
bashuv run huggingface-cli login # or: export HF_TOKEN=<your_token> - 4Проверка работоспособности на поставляемых демонстрационных данных SO-100
Прежде чем использовать собственную запись, выполните 2000 шагов на demo_data/cube_to_bowl_5. Это пять эпизодов, они быстро завершаются и подтверждают работоспособность окружения, а не ваших данных. Если этот запуск завершится ошибкой, ничто, что вы сделаете с вашим набором данных, не поможет.
bashCUDA_VISIBLE_DEVICES=0 uv run python \ gr00t/experiment/launch_finetune.py \ --base-model-path nvidia/GR00T-N1.7-3B \ --dataset-path demo_data/cube_to_bowl_5 \ --embodiment-tag NEW_EMBODIMENT \ --modality-config-path examples/SO100/so100_config.py \ --num-gpus 1 \ --output-dir /tmp/test_finetune \ --max-steps 2000 \ --global-batch-size 32 \ --dataloader-num-workers 4
FFmpeg 8. torchcodec 0.8.0 поддерживает только FFmpeg от 4 до 7, а Ubuntu 25.10 и более поздние версии поставляются с версией 8. Ошибка Could not load libtorchcodec выглядит как сломанная установка, а не конфликт версий. Установите более старую среду выполнения, например conda install -c conda-forge 'ffmpeg<8', и добавьте ее библиотеки в LD_LIBRARY_PATH. CUDA_HOME не установлен. Тонкая настройка полностью завершается ошибкой. Запустите bash scripts/deployment/dgpu/install_deps.sh один раз, или просто export CUDA_HOME=/usr/local/cuda.
Шаг 5: команда тонкой настройки и реальные значения по умолчанию для ее флагов
Замените демонстрационный набор данных на свой и добавьте нужные вам параметры. Ниже приведена полная форма, которую репозиторий использует в своем собственном руководстве по новой реализации, включая флаги аугментации и контрольных точек, которые отсутствуют в кратком примере README. Это в узком смысле: языковая основа и визуальный кодировщик остаются замороженными, а обучаются проектор и диффузионная головка действий.
export NUM_GPUS=1
CUDA_VISIBLE_DEVICES=0 uv run python \
gr00t/experiment/launch_finetune.py \
--base-model-path nvidia/GR00T-N1.7-3B \
--dataset-path ./my_dataset_lerobot \
--embodiment-tag NEW_EMBODIMENT \
--modality-config-path examples/SO100/so100_config.py \
--num-gpus $NUM_GPUS \
--output-dir /tmp/so100 \
--save-total-limit 5 \
--save-steps 2000 \
--max-steps 20000 \
--use-wandb \
--global-batch-size 32 \
--color-jitter-params brightness 0.3 contrast 0.4 saturation 0.5 hue 0.08 \
--dataloader-num-workers 4| Флаг | Значение по умолчанию в FinetuneConfig | Что он делает |
|---|---|---|
| --global-batch-size | 64 | Общий размер пакета данных для всех GPU до накопления градиента. В поставляемых примерах используется 32. |
| --learning-rate | 1e-4 | То же значение, которое AY-Robots использует для своего тренера groot1.7. |
| --max-steps | 10000 | Общее количество шагов оптимизатора. Оболочка examples/finetune.sh также по умолчанию использует 10000. |
| --gradient-accumulation-steps | 1 | Умножает эффективный размер пакета. Значения выше 1 выдают предупреждение о накопленном размере. |
| --save-steps and --save-total-limit | 1000 and 5 | Частота сохранения контрольных точек и их количество. Старые удаляются. |
| --weight-decay and --warmup-ratio | 1e-5 and 0.05 | Также явно устанавливается в examples/finetune.sh. |
| --state-dropout-prob | 0.2 in the CLI, 0.8 in the model config | Случайным образом отбрасывает проприоцептивное состояние во время обучения. Уменьшите его, если ваша задача сильно зависит от состояния. |
| --tune-llm and --tune-visual | False and False | Ядро по умолчанию остается замороженным. |
| --tune-projector and --tune-diffusion-model | True and True | Проектор и диффузионная головка действий — это то, что фактически обучается. |
| --use-percentiles | True | Нормализовать с помощью q01 и q99 вместо необработанных минимума и максимума. |
| --dataloader-num-workers | 2 | Загрузчик по умолчанию основан на CPU. В примерах это значение увеличивается до 4. |
| --seed | does not exist | В этом CLI нет флага seed. |
Эта последняя строка — не опечатка. launch_finetune.py — это CLI tyro, сгенерированный из класса данных, и этот класс данных не имеет поля seed. В файле README отдельно отмечается 5–6-процентная дисперсия между запусками, вызванная недетерминированной аугментацией изображений. Два запуска с идентичными флагами не дадут идентичных контрольных точек, что очень важно, когда вы пытаетесь решить, помогло ли изменение гиперпараметра или вам просто повезло. Для сравнения, собственный тренажер lerobot по умолчанию использует seed 1000, а рецепт LeRobot GR00T явно передает --seed=42 явно.
Тонкая настройка выполняется с eval_strategy="no", поэтому кривой потерь валидации вообще нет. Вы получаете только потери обучения и ничего больше. Руководство по новому воплощению предписывает включить его с помощью --eval-strategy steps --eval-steps 500, но этот флаг отсутствует в launch_finetune.py: CLI генерируется tyro из класса данных FinetuneConfig, а eval_strategy, eval_steps и eval_batch_size являются полями TrainingConfig. Их значения по умолчанию там: "no", 500 и 2. Чтобы получить к ним доступ, используйте более полную точку входа gr00t/experiment/launch_train.py, где вложенный флаг — --training.eval-strategy. В любом случае, падение потерь обучения само по себе очень мало говорит о генерализации, что в точности соответствует ситуации, описанной в потери падают, но политика ничего не делает.
Сколько стоит запуск на 20000 шагов
GR00T N1.7 требуется карта на 80 ГБ, поэтому вопрос стоимости имеет узкий ответ. На AY-Robots тренажер groot1.7 работает на уровне A100 80 ГБ или H100 80 ГБ, где запуск занимает от 3 до 6 часов по цене от 1.20 до 2.00 USD в час на спотовом рынке. Это примерно от 4 до 12 USD за стандартную задачу на 20000 шагов. Та же задача на SmolVLA или ACT выполняется на карте 24 ГБ по цене от 0.30 до 0.60 USD в час и от 1 до 3 USD за запуск. В этом и заключается реальный компромисс: GR00T стоит примерно в четыре раза дороже за попытку, и вы не сможете запустить его на 4090 под своим столом.
| Модель | Уровень GPU | Типичное время выполнения | Типичная стоимость | Минимум эпизодов |
|---|---|---|---|---|
| GR00T N1.7 | A100 80 GB or H100 80 GB | от 3 до 6 часов | от 4 до 12 USD | 50 |
| GR00T N1.5 | A100 80 GB or H100 80 GB | от 3 до 6 часов | от 4 до 12 USD | 50 |
| Pi0.5 | A100 80 GB or H100 80 GB | от 3 до 6 часов | от 4 до 12 USD | 50 |
| SmolVLA | RTX 4090 or any 24 GB card | от 2 до 5 часов | от 1 до 3 USD | 30 |
| ACT | RTX 4090 or any 24 GB card | от 2 до 5 часов | от 1 до 3 USD | 50 |
Минимум в 50 эпизодов — это нижний предел, а не цель. Собственный FAQ NVIDIA более требователен: примерно 100 траекторий для простого захвата и размещения в фиксированном месте, 500 или более для сложных или многошаговых сцен, и от 100 до 500 для точной манипуляции. Если у вас всего 20 эпизодов, потратьте день на запись, а не вечер на настройку. Руководство по сбору данных описывает, что отличает полезный эпизод от бесполезного, запишите свой первый набор данных — это краткая версия, а сбор данных SO-100 — это версия для конкретной руки.
Шаг 6: оценка в разомкнутом контуре, прежде чем вы прикоснетесь к руке
Не устанавливайте свежий контрольную точку на физическую руку, чтобы узнать, сработало ли обучение. Сначала запустите оценку в разомкнутом цикле. Она воспроизводит записанный эпизод, запрашивает у модели действия на каждом шаге и строит график предсказаний в сравнении с истинными значениями с использованием MSE и MAE. Это ничего не стоит и позволяет выявить ошибки сопоставления из шагов 2 и 3.
uv run python gr00t/eval/open_loop_eval.py \
--dataset-path ./my_dataset_lerobot \
--embodiment-tag NEW_EMBODIMENT \
--model-path /tmp/so100/checkpoint-20000 \
--traj-ids 0 \
--execution-horizon 16 \
--steps 400 \
--modality-keys single_arm gripperРепозиторий намеренно отказывается публиковать целевое значение MSE для пользовательских данных, и это правильное решение: число зависит от ваших единиц действия, вашей задачи и размера вашего набора данных, поэтому порог, скопированный с чужой руки, ничего не значит. Что имеет значение, так это тенденция. Вот эталонный запуск, который репозиторий документирует на одном H100 с демонстрационным набором данных из пяти эпизодов и 2000 шагов.
| Контрольная точка | Средний MSE на траектории 0 | Средний MAE на траектории 0 |
|---|---|---|
| 500 | 87.5 | 5.63 |
| 1000 | 25.4 | 3.30 |
| 1500 | 13.2 | 2.18 |
| 2000 | 10.0 | 1.76 |
Форма является сигналом, а не абсолютными значениями. Ошибка должна неуклонно снижаться по мере накопления шагов обучения. Усредненный по всем пяти эпизодам обучения, а не только по траектории 0, итоговый контрольный пункт репозитория показал примерно 7.5 MSE и 1.5 MAE, поэтому даже эталонный запуск интерпретируется по-разному в зависимости от того, какие эпизоды вы усредняете. Запишите свой собственный базовый показатель на неизмененной демонстрационной команде, прежде чем что-либо менять в своих данных: если вы не можете воспроизвести заведомо рабочий запуск, вы не сможете отличить ошибку настройки от проблемы с данными. Репозиторий также сопоставляет общие симптомы с причинами, и каждая из них является операционной, а не ошибкой модели.
| Симптом | Вероятная причина |
|---|---|
| MSE остается неизменным или растет на контрольных точках | Скорость обучения слишком низка, или данные вообще не загружаются. Проверьте --dataset-path и рабочие процессы загрузчика данных. |
| Кривая предсказания плоская или постоянная | Ключи modality.json или --modality-config-path не совпадают. Ключи действий не сопоставлены. |
| MSE огромен, или потеря NaN во время обучения | Нормализация действий и состояний. Проверьте meta/stats и убедитесь, что диапазоны действий физически правдоподобны. |
| Хорошо на траектории 0, плохо на отложенных эпизодах | Недостаток данных, а не ошибка. Пять демонстрационных эпизодов не могут обеспечить обобщение. |
Другой путь: lerobot-train вместо Isaac-GR00T
Текущий релиз LeRobot, 0.6.1 на PyPI с 3 августа 2026 года, предлагает второй и совершенно иной способ тонкой настройки тех же базовых весов. LeRobot предоставляет GR00T N1.7 как тип политики и обучает его через свою собственную точку входа lerobot-train. Здесь важны две вещи. CLI LeRobot — это набор консольных скриптов, поэтому все, что вы читаете, где говорится python lerobot/scripts/train.py, устарело и не будет работать. И LeRobot полностью удалил поддержку GR00T N1.5, отклоняя контрольные точки и конфигурации N1.5 с примечанием о миграции, поэтому, если вам нужен N1.5 через LeRobot, вам придется закрепить версию lerobot==0.5.1, последний релиз, который его поддерживает, опубликованный 7 апреля 2026 года.
pip install "lerobot[groot]" "lerobot[training]"
hf auth login
lerobot-train \
--dataset.repo_id=$HF_USER/$DATASET_NAME \
--dataset.image_transforms.enable=true \
--policy.type=groot \
--policy.device=cuda \
--policy.base_model_path=nvidia/GR00T-N1.7-3B \
--policy.embodiment_tag=new_embodiment \
--policy.chunk_size=16 \
--policy.n_action_steps=16 \
--policy.use_relative_actions=true \
--policy.relative_exclude_joints='["gripper"]' \
--policy.use_bf16=true \
--seed=42 \
--batch_size=64 \
--steps=20000 \
--save_freq=5000 \
--output_dir=$OUTPUT_DIR| Аспект | Isaac-GR00T launch_finetune.py | lerobot-train --policy.type=groot |
|---|---|---|
| Версия набора данных | Только LeRobot v2, требуется конвертация | Нативный набор данных LeRobot, без понижения версии |
| Сопоставление модальностей | meta/modality.json плюс конфигурация данных Python | без modality.json; поведение задается флагами --policy.* в командной строке |
| Зерно | флаг зерна отсутствует | --seed, по умолчанию LeRobot 1000 |
| Относительные действия | ActionConfig для каждого ключа в конфигурации данных | --policy.use_relative_actions плюс --policy.relative_exclude_joints |
| Опубликованные эталонные результаты | Тенденция MSE SO-100 в разомкнутом контуре на демонстрационных данных | Наборы LIBERO, в среднем 96,5 процента по четырем наборам |
| Путь развертывания | run_gr00t_server.py плюс eval_so100.py через ZMQ | lerobot-rollout, с чанкингом в реальном времени (queue_threshold должен оставаться на уровне 5 или ниже) |
- Каждый флаг виден и изменяем. Вы можете разморозить визуальный кодировщик, изменить state_dropout_prob или сократить горизонт действий.
- Графики разомкнутого контура — это локальные файлы. Сравнение checkpoint-5000 с checkpoint-20000 — это команда оболочки.
- Вы не зависите от того, что какая-либо платформа остается онлайн, и контрольная точка хранится на вашем диске в стандартном формате.
- Примеры бенчмарков репозитория для LIBERO, SimplerEnv и DROID дают вам заведомо хорошие запуски для воспроизведения, прежде чем вы доверитесь своим собственным данным.
- Окружение — это большая часть работы. Версия FFmpeg, CUDA_HOME, git-lfs, gated backbone, torchcodec: ни одна из этих проблем не связана с моделью, и каждая из них останавливает выполнение.
- Преобразование из v3.0 в v2.1 требует отдельного виртуального окружения со своим шагом установки, и оно перезаписывает ваш каталог набора данных на месте.
- Аренда GPU начинает тарифицироваться, когда вы начинаете отладку, а не когда начинается обучение, и ничто не останавливает экземпляр после завершения выполнения.
- Отсутствие зерна означает отсутствие побитовой воспроизводимости, вдобавок к 5-6-процентной вариативности между запусками только из-за аугментации.
Два способа получить одну и ту же контрольную точку
Вы арендуете GPU и контролируете каждый шаг. Реалистично, в первый раз это займет полдня, а затем — двадцать минут каждый раз.
- Записывайте эпизоды с помощью lerobot-record на SO-100. Вы получите набор данных LeRobot v3.0.
- Преобразуйте его до версии v2.1 с помощью scripts/lerobot_conversion/convert_v3_to_v2.py в отдельном виртуальном окружении.
- Напишите meta/modality.json и конфигурацию модальности на Python, зарегистрированную под EmbodimentTag.NEW_EMBODIMENT.
- Арендуйте карту на 80 ГБ, клонируйте с подмодулями, выполните uv sync, пройдите аутентификацию в Hugging Face.
- Запустите launch_finetune.py, затем open_loop_eval.py на нескольких контрольных точках и сравните тенденцию MSE, прежде чем приступать к работе с оборудованием.
- Скопируйте контрольную точку с машины, прежде чем уничтожить экземпляр, затем постройте путь обслуживания к манипулятору.
Скопируйте контрольную точку с арендованного экземпляра, прежде чем выключить его. --save-total-limit 5 также означает, что старые контрольные точки удаляются по мере обучения, поэтому контрольная точка, которую вы хотели на шаге 5000, может больше не существовать на шаге 20000.
Та же задача в виде формы. Вы выбираете модель и набор данных, бэкенд арендует GPU на спотовом рынке по требуемому объему VRAM, запускает обучение и записывает контрольные точки в объектное хранилище. руководство по GR00T N1.7 на SO-100 — это именно такая комбинация; матрица обучения содержит все остальные пары моделей и манипуляторов, включая GR00T N1.7 на SO-101.
| Что отправляет обучитель groot1.7 | Значение |
|---|---|
| Размер батча | 32 |
| Скорость обучения | 1e-4 |
| Макс. шаги | 20000 |
| Накопление градиента | 1, and it does take effect for this trainer |
| Дополнительная настройка, доступная в форме | saveSteps |
| Базовая контрольная точка | nvidia/GR00T-N1.7-3B |
| Принимаемый формат набора данных | LeRobot v2.0 or v2.1 |
Набор данных может быть получен из Hugging Face repo id, с вашей собственной машины или из сессии, записанной с помощью десктопного клиента. Вывод — это отдельный шаг: платформа выделяет под, который обслуживает политику, и ваш локальный клиент робота взаимодействует с этой конечной точкой. Поды имеют сторожевой таймер простоя и уничтожают себя после периода бездействия, поэтому забытая вкладка браузера не будет выставлять счета за ночь. Если вы предпочитаете не нажимать, те же операции доступны на CLI и сервере MCP.
GR00T N1.7 и Pi0.5 здесь доступны только в облаке; только SmolVLA и ACT также работают локально. Требование v2.1 также никуда не девается, потому что набор данных v3.0 все равно должен быть преобразован, прежде чем загрузчик GR00T его примет. И никто не напишет за вас семантику вашего modality.json: если ключи вашей камеры или языковой ключ неверны, они неверны на обоих маршрутах. См. документацию по обучению, чтобы узнать, что бэкенд делает и не делает от вашего имени.

Возвращение контрольной точки на манипулятор
Isaac-GR00T использует разделение клиент-сервер по ZMQ. Политика выполняется на GPU, а тонкий клиент на машине робота отправляет наблюдения и получает фрагменты действий. Пример SO-100 достаточно полон для копирования: запустите run_gr00t_server.py с вашей контрольной точкой и --embodiment-tag NEW_EMBODIMENT, затем запустите eval_so100.py на стороне робота с использованием последовательного порта, идентификатора робота, индексов камеры и языковой инструкции. Имена камер в этой команде должны соответствовать дружественным именам из вашего modality.json, а не номерам устройств ОС.
# GPU side
uv run python gr00t/eval/run_gr00t_server.py \
--model-path /tmp/so100/checkpoint-20000 \
--embodiment-tag NEW_EMBODIMENT \
--device cuda:0 \
--host 0.0.0.0 --port 5555
# robot side, from gr00t/eval/real_robot/SO100
uv run --no-sync python eval_so100.py \
--robot.type=so101_follower \
--robot.port=/dev/ttyACM2 \
--robot.id=orange_follower \
--robot.cameras="{ front: {type: opencv, index_or_path: 6, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30}}" \
--policy_host=localhost --policy_port=5555 \
--lang_instruction="put the cube in the yellow bowl"Пока вы снова подключаете манипулятор: SO-100 использует шинные сервоприводы Feetech STS3215 на шине 7.4 В. Подача на них 12 В выводит их из строя, и это легко допустить, если у вас также есть LeKiwi, чья база работает от 12 В, а манипулятор — нет. Проверьте питание перед первым включением, а не после появления дыма. См. страницу оборудования SO-100 и SO-100 против LeKiwi. Если манипулятор включается, но ничего не движется, сервопривод не отвечает — это то, с чего стоит начать.
Теперь честная часть о том, где выполняется политика, потому что обучение и обслуживание имеют разные требования к оборудованию. Для тонкой настройки требуется 40 ГБ или более. Для инференса — нет: README указывает 16 ГБ или более и явно называет RTX 4090, так что карта, которая у вас уже есть, может обслуживать контрольную точку, которую она никогда не смогла бы произвести. Что определяет, насколько отзывчивой кажется политика, это не VRAM, а то, где находится сервер. На AY-Robots GR00T N1.7 доступен только в облаке, поэтому цикл управления оплачивает круговой путь через публичный интернет в дополнение к 152 мс на каждый шаг действия, и только SmolVLA и ACT также работают локально. Для медленного захвата и перемещения удаленный под является приемлемым. Для чего-либо реактивного — нет: политика становится нерешительной таким образом, что это выглядит в точности как сбой обучения, но таковым не является. ACT со скоростью 20 мс на шаг действия — это модель, которая допускает самый короткий цикл, SmolVLA работает со скоростью 245 мс, и никакое количество настройка задержки не компенсирует уже потраченный круговой путь. Запустите свою первую политику подробно описывает сторону обслуживания от начала до конца.
Что на самом деле идет не так
- GatedRepoError при первом запуске. Вам не был предоставлен доступ к nvidia/Cosmos-Reason2-2B, или вы не прошли аутентификацию. Это происходит после того, как тактовая частота GPU уже запущена.
- Набор данных отклонен при загрузке. Почти всегда это набор данных v3.0. Преобразуйте его в более раннюю версию. См. отклонение набора данных как v3.
- IndexError о несоответствии булевых размерностей. Вы изменили delta_indices и не перегенерировали статистику.
- Недостаточно памяти при пакете 32. Уменьшите --global-batch-size и увеличьте --gradient-accumulation-steps, или уменьшите --num-shards-per-epoch, что явно предлагается в конфигурации при ограниченной VRAM. См. недостаток памяти во время обучения.
- Потери падают, политика ничего не делает. По умолчанию нет разделения на валидацию, поэтому чистая кривая обучения мало что доказывает. Эта страница описывает диагностику.
- Работает в вашей настройке и нигде больше. Ожидаемо для небольшого набора данных, снятого при одном условии освещения. NVIDIA рекомендует аугментацию с цветовым дрожанием плюс от 20 до 50 эпизодов при различном освещении. Подробнее здесь.
- Захват никогда не закрывается должным образом. Убедитесь, что действие захвата является ABSOLUTE, а суставы манипулятора — RELATIVE, именно в таком порядке в action_configs. Захват не закрывается перечисляет другие причины.
- Камера незаметно отключается в середине записи. Эпизод все равно сохраняется, и ключ видео все еще существует, поэтому это неприятно. Камера не обнаружена описывает это.
Полный индекс режимов отказа находится на . Если вы выбираете между моделями, а не отлаживаете одну, и содержат эталонные показатели с прикрепленными источниками, а — это сравнение, которое на самом деле нужно большинству людей, потому что это выбор между моделью, которую можно обучить на карте под вашим столом, и моделью, для тонкой настройки которой нужно арендовать узел с 80 ГБ. Для получения информации о том, почему эти модели ведут себя так, как они ведут, и стоит прочитать в первую очередь. И если у вас еще нет манипулятора, транслирует физический SO-100 без регистрации.
Сколько эпизодов мне нужно, прежде чем тонкая настройка GR00T N1.7 станет целесообразной?▾
AY-Robots устанавливает жесткий минимум в 50 эпизодов для тренера groot1.7. Собственный FAQ NVIDIA более требователен: примерно 100 траекторий для простого захвата и размещения в фиксированном месте, 500 или более для сложных или многошаговых сцен, и от 100 до 500 для тонкой манипуляции. При количестве менее 50 почти всегда лучше записать больше данных, чем настраивать гиперпараметры. Если после этого успех стабилизируется, NVIDIA рекомендует HG-DAgger: запустить политику, вмешаться при ее сбое и добавить эти исправления в набор данных.
Почему мой набор данных не загружается, и как определить его версию?▾
Откройте meta/info.json и прочитайте codebase_version. Текущая CODEBASE_VERSION LeRobot в main — v3.0, поэтому все, что записано с помощью недавнего набора инструментов, является v3.0, а загрузчик GR00T ожидает v2. Преобразуйте с помощью scripts/lerobot_conversion/convert_v3_to_v2.py из репозитория Isaac-GR00T, который записывает codebase_version: v2.1 в преобразованный набор данных. Скрипт запускается в собственном виртуальном окружении, потому что ему нужна другая версия lerobot, чем та, которую использует GR00T.
Могу ли я тонко настроить GR00T N1.7 на RTX 4090?▾
Нет. NVIDIA рекомендует 40 ГБ или более VRAM для тонкой настройки и называет узлы H100 или L40; другие карты работают, но занимают гораздо больше времени. У 4090 есть 24 ГБ. AY-Robots предлагает GR00T N1.7 только на уровне A100 80 ГБ и H100 80 ГБ по той же причине. Инференс — это другая история: 16 ГБ достаточно для обслуживания модели, поэтому 4090 может запускать политику, которую она не может обучить. Если вы хотите VLA, который можно обучить на 24 ГБ, это SmolVLA с примерно 450 млн параметров или ACT с примерно 80 млн.
Почему два запуска с идентичными флагами дают разные контрольные точки?▾
Потому что launch_finetune.py не имеет seed. Это CLI tyro, сгенерированный из класса данных, который не содержит поля seed, поэтому ничто не фиксирует ГСЧ. Репозиторий отдельно отмечает 5-6-процентную дисперсию между запусками, вызванную недетерминированной аугментацией изображений. Если воспроизводимость важна, используйте вместо этого путь LeRobot: lerobot-train принимает --seed, а опубликованный рецепт GR00T передает --seed=42.
Стоит ли использовать Isaac-GR00T или lerobot-train?▾
Используйте Isaac-GR00T, если вам нужна эталонная реализация, поключевой контроль над представлением действий, экспорт TensorRT или примеры бенчмарков для воспроизведения, прежде чем доверять своим собственным данным. Используйте lerobot-train, если ваш набор данных уже LeRobot v3.0 и вы не хотите его конвертировать, если вам нужен seed, или если остальная часть вашего стека уже LeRobot. Оба тонко настраивают одни и те же веса nvidia/GR00T-N1.7-3B. Обратите внимание, что LeRobot полностью прекратил поддержку GR00T N1.5: контрольные точки N1.5 отклоняются с примечанием о миграции, и вам придется зафиксировать lerobot==0.5.1, чтобы продолжать их использовать.
Действительно ли мне нужна наручная камера, а также фронтальная камера?▾
Поставляемая конфигурация SO-100 использует обе, и modality.json сопоставляет переднюю и наручную камеры как отдельные видеоключи. Вы можете обучать с одной камерой, и таблица задержек карты модели измеряется с одной камерой, но вид с запястья дает политике полезную информацию о захвате в момент контакта. Если захват закрывается не в то время в ваших прогонах, отсутствующая или плохо нацеленная наручная камера — одна из первых вещей, которые нужно проверить.
Тонкая настройка GR00T N1.7 на вашем SO-100 без предварительной сборки окружения
Выберите модель, набор данных и гиперпараметры в форме. Бэкенд арендует A100 80 ГБ или H100 на спотовом рынке, запускает тренажер с пакетом 32, скоростью обучения 1e-4 и 20000 шагами, и записывает контрольные точки в объектное хранилище. Примерно от 4 до 12 USD за запуск.
Открыть руководство по обучению GR00T N1.7Sources
- NVIDIA Isaac-GR00T repository README, N1.7 main branch
- Isaac-GR00T: Fine-tune on Custom Embodiments (NEW_EMBODIMENT)
- Isaac-GR00T: Finetuning Models for the SO100/SO101 Robot
- Isaac-GR00T: Robot Data Preparation Guide, the GR00T LeRobot format
- Isaac-GR00T: modality config and ActionConfig reference
- Isaac-GR00T: Policy API Guide and the embodiment tag list
- Isaac-GR00T: FinetuneConfig dataclass with every CLI default
- Isaac-GR00T: the shared finetune launcher wrapper
- GR00T N1.7 FAQ: data volume, augmentation and deployment
- nvidia/GR00T-N1.7-3B model card, including the inference timing table
- nvidia/Cosmos-Reason2-2B, the gated VLM backbone used by N1.7
- GR00T N1: An Open Foundation Model for Generalist Humanoid Robots
- NVIDIA Isaac GR00T N1.7: Open Reasoning VLA Model for Humanoid Robots
- LeRobot: GR00T Policy, the lerobot-train recipe
- LeRobot: Imitation Learning on Real-World Robots (lerobot-record, lerobot-train)
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started