
Перевірений покроковий посібник для доопрацювання NVIDIA GR00T N1.7 на наборі даних LeRobot SO-100: реальні прапорці, modality.json, вимога v2.1, скільки коштує запуск та підводні камені.
NVIDIA постачає приклад тонкого налаштування саме для тієї руки, яку ви, ймовірно, маєте. У репозиторії Isaac-GR00T є папка під назвою demo_data/cube_to_bowl_5: п'ять епізодів, 4148 кадрів зі швидкістю 30 кадрів/с, вже записані як 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 ГБ або більше VRAM. NVIDIA рекомендує вузли H100 або L40. RTX 4090 з 24 ГБ не впорається з цим завданням, хоча вона може тренувати 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 передбачає суглоби руки як ВІДНОСНІ дельти, а захват — як АБСОЛЮТНУ ціль. Зворотне поєднання є тихою відмовою, а не помилкою.
- •На AY-Robots та сама робота є формою: 20000 steps, batch 32, learning rate 1e-4, приблизно 4 to 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 |
| Візуально-мовна основа | nvidia/Cosmos-Reason2-2B (Qwen3-VL), gated on Hugging Face | README репозиторію |
| Голова дій | Flow-matching diffusion transformer, 16 layers (N1.6 had 32) | README репозиторію |
| Прогнозований горизонт дій | 40 steps for the base checkpoint (N1.6 had 16) | getting_started/policy.md та README репозиторію |
| Максимальна ширина стану та дії | 132 (N1.6 had 29) | README репозиторію |
| Ліцензія на код | Apache 2.0 | Репозиторій Isaac-GR00T |
| Ліцензія на ваги | NVIDIA Open Model License Agreement | картка моделі |
| Затримка, H100 80 ГБ, PyTorch eager, 4 кроки денойзингу, 1 камера | 85.8 ms end to end, 11.7 Hz | таблиця часу картки моделі |
| Те саме обладнання, повний конвеєр TensorRT | 27.9 ms end to end, 35.9 Hz | таблиця часу картки моделі |
| Затримка, яку AY-Robots вказує для свого розгорнутого GR00T N1.7 | 152 ms per action step | Каталог політик AY-Robots |
Ці останні три рядки пояснюють більшість розчарувань, про які повідомляють люди. Заявлені 27.9 мс — це рушій TensorRT на H100 з однією камерою та чотирма кроками денойзингу. Звичайний PyTorch на тій самій карті становить 85.8 мс, і картка моделі вказує на розрив у 3.08x. Жодне з цих чисел не включає шар обслуговування, другу камеру або мережевий стрибок. 152 мс на крок дії, які 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 and CUDA 12.8 | 3.12 and CUDA 12.8 |
| Відео бекенд | torchcodec 0.8.0, FFmpeg 4 to 7 only | те саме |
| Формат набору даних | LeRobot v2 plus meta/modality.json | не застосовується |
| Доступ до Hugging Face | approved for nvidia/Cosmos-Reason2-2B | те саме |
| Інші інструменти | git-lfs and uv | uv |
| Рівень GPU AY-Robots для тренера groot1.7 | A100 80 GB or H100 80 GB | под надається автоматично |
Кожен чекпоінт 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 у гілці main — це 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 передбачає п'ять суглобів руки як ВІДНОСНІ дельти від поточного стану, а захоплювач як АБСОЛЮТНУ цільову позицію, оскільки бінарний сигнал відкрито/закрито поводиться краще як ціль, ніж як дельта.
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 перемістив репозиторій до та 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, згенерований з dataclass, і цей dataclass не має поля 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 з dataclass 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 to 6 hours | 4 to 12 USD | 50 |
| GR00T N1.5 | A100 80 GB or H100 80 GB | 3 to 6 hours | 4 to 12 USD | 50 |
| Pi0.5 | A100 80 GB or H100 80 GB | 3 to 6 hours | 4 to 12 USD | 50 |
| SmolVLA | RTX 4090 or any 24 GB card | 2 to 5 hours | 1 to 3 USD | 30 |
| ACT | RTX 4090 or any 24 GB card | 2 to 5 hours | 1 to 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 та переконайтеся, що діапазони дій є фізично правдоподібними. |
| Добре на traj 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 | --seed, LeRobot за замовчуванням 1000 |
| Відносні дії | ActionConfig для кожного ключа в конфігурації даних | --policy.use_relative_actions плюс --policy.relative_exclude_joints |
| Опубліковані еталонні результати | Тенденція SO-100 open-loop MSE на демонстраційних даних | Набори 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, автентифікуйтесь у 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 | Value |
|---|---|
| Розмір пакету | 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, з вашої власної машини або з сесії, яку ви записали за допомогою десктопного клієнта. Висновок є окремим кроком: платформа надає под, який обслуговує політику, а ваш локальний клієнт робота спілкується з цією кінцевою точкою. Поди мають сторожовий таймер бездіяльності та знищуються після періоду бездіяльності, тому забута вкладка браузера не буде виставляти рахунок за ніч. Якщо ви не хочете натискати, ті ж операції доступні на 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 V. Подача на них 12 V знищує їх, і це легка помилка, якщо у вас також є LeKiwi, чия база працює на 12 V, тоді як його рука – ні. Перевірте живлення перед першим увімкненням, а не після диму. Дивіться сторінку обладнання SO-100 та SO-100 проти LeKiwi. Якщо рука вмикається, але нічого не рухається, сервопривід не відповідає – це місце, з якого варто почати.
Тепер чесна частина про те, де виконується політика, тому що навчання та обслуговування мають різні історії з обладнанням. Доналаштування вимагає 40 GB або більше. Висновок – ні: README вказує 16 GB або більше і прямо називає RTX 4090, тому карта, яку ви вже маєте, може обслуговувати контрольну точку, яку вона ніколи не могла б створити. Що вирішує, чи буде політика чутливою, це не VRAM, а те, де знаходиться сервер. На AY-Robots GR00T N1.7 є лише хмарним, тому цикл керування оплачує зворотний шлях через публічний інтернет на додаток до 152 ms за крок дії, і лише SmolVLA та ACT також працюють локально. Для повільного вибору та розміщення віддалений под є прийнятним. Для чогось реактивного – ні: політика стає нерішучою таким чином, що виглядає точно як збій навчання, але таким не є. ACT з 20 ms за крок дії є моделлю, яка толерує найщільніший цикл, SmolVLA знаходиться на 245 ms, і жодна кількість налаштування затримки не поверне зворотний шлях, який вже був витрачений. Запустіть свою першу політику детально розглядає сторону обслуговування.
Що насправді йде не так
- 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, згенерований з dataclass, який не містить поля seed, тому ніщо не фіксує RNG. Репозиторій окремо зазначає 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 to 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