Страницата с ръководство на AY-Robots за обучение на GR00T N1.7 на SO-100 ръка, показваща необходимия GPU клас, формат на набора от данни и настройките по подразбиране на обучителя
GR00T N1.7SO-100Фино настройванеLeRobotVLA

Как да обучите GR00T N1.7 на собствен SO-100 набор от данни

AY-Robots ResearchAugust 23, 202628 мин четене

Изпробвано ръководство за фино настройване на NVIDIA GR00T N1.7 върху SO-100 LeRobot набор от данни: реални флагове, 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 GB или повече VRAM. NVIDIA препоръчва H100 или L40 възли. 24 GB RTX 4090 няма да свърши тази работа, въпреки че ще обучи 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 стъпки, пакет 32, скорост на обучение 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 часа и съобщава, че преминаването от 1k на 20k часа повече от удвоява средното изпълнение на задачи.

Втората половина също се промени, по начини, които са важни за вашето изпълнение. Главата за действие намаля от 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), достъпен в Hugging FaceREADME на хранилището
Глава за действиеДифузионен трансформатор със съвпадение на потока, 16 слоя (N1.6 имаше 32)README на хранилището
Предвиден хоризонт на действие40 стъпки за базовата контролна точка (N1.6 имаше 16)getting_started/policy.md и README на хранилището
Максимална ширина на състоянието и действието132 (N1.6 имаше 29)README на хранилището
Лиценз на кодаApache 2.0Хранилище Isaac-GR00T
Лиценз на теглатаNVIDIA Open Model License AgreementКарта на модела
Латентност, H100 80 GB, PyTorch eager, 4 стъпки за премахване на шума, 1 камера85.8 ms от край до край, 11.7 HzТаблица за времената в картата на модела
Същият хардуер, пълна конвейерна линия TensorRT27.9 ms от край до край, 35.9 HzТаблица за времената в картата на модела
Латентност, цитирана от AY-Robots за обслужвания GR00T N1.7152 ms на стъпка на действиеКаталог с политики на AY-Robots

Последните три реда обясняват по-голямата част от разочарованието, което хората съобщават. Заглавните 27.9 ms са за TensorRT енджин на H100 с една камера и четири стъпки за премахване на шума. Обикновеният PyTorch на същата карта е 85.8 ms, а картата на модела посочва разлика от 3.08x. Нито едно от числата не включва обслужващ слой, втора камера или мрежов скок. Цитираните от AY-Robots 152 ms на стъпка на действие за обслужвания GR00T N1.7 са стойността с обслужване в цикъла, а пътуване до публичен интернет се добавя отгоре. Повече за това в края. За числата до други модели, GR00T N1.7 срещу Pi0.5 и GR00T N1.7 срещу SmolVLA ги представят един до друг.

Страницата на модела AY-Robots за GR00T N1.7, показваща броя на параметрите, нивото на GPU, латентността на извода и заявените силни страни и ограничения на модела
Страницата /policies/groot-n1-7 съдържа същата лента със спецификации, която иначе бихте сглобили ръчно от картата на модела и README файла на хранилището.

Какво е необходимо за изпълнението, преди да въведете каквото и да било

ИзискванеФина настройкаИзвод
VRAM, насоки от NVIDIA40 GB или повече, препоръчително H100 или L4016 GB или повече, работи RTX 4090
Python и CUDA на dGPU3.12 и CUDA 12.83.12 и CUDA 12.8
Видео бекендtorchcodec 0.8.0, само FFmpeg 4 до 7същото
Формат на набора от данниLeRobot v2 плюс meta/modality.jsonнеприложимо
Достъп до Hugging Faceодобрен за nvidia/Cosmos-Reason2-2Bсъщото
Други инструментиgit-lfs и uvuv
Ниво на GPU на AY-Robots за обучителя groot1.7A100 80 GB или 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 файловете и потоците от камери. Ако калибрирането е неточно, стойностите на ставите във вашия набор от данни описват малко по-различен робот от този, който по-късно ще изпълни политиката, и никакво обучение не може да поправи това.

bash
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-record на текущ LeRobot. Дължината на епизода по подразбиране е 60 s, а времето за нулиране е 60 s. so100_follower и so101_follower са регистрирани към един и същ LeRobot конфигурационен клас, поради което примерът Isaac-GR00T SO100 използва имената so101; и двете работят на SO-100. Имената на камерите, които избирате тук (front, wrist), са имената, които трябва да се появят отново в modality.json.

Собственият съвет на LeRobot е да запишете поне 50 епизода с около 10 за всяко местоположение на обекта, да държите камерите фиксирани и да поддържате последователно поведението на захващане. Добавете вариации по-късно, не в началото. Правилото, което си струва да запомните: ако не можете да изпълните задачата сами само от изображенията на камерата, политиката също не може. За специфичната за рамото настройка, начало с SO-100 и страницата на SO-100 LeRobot обхващат портове, калибриране и индекси на камери. На AY-Robots можете да направите това и през интернет от браузъра, използвайки телеоперация и да записвате директно от сесията.

Стъпка 1: наборът от данни трябва да е LeRobot v2.1

Това е най-често срещаната пречка. Текущата CODEBASE_VERSION във `main` е v3.0, така че всичко, което запишете днес с текущия набор от инструменти, излиза като v3.0. Зареждащият модул на GR00T очаква v2. Хранилището е изрично защо: много набори от данни нагоре по веригата, като DROID, LIBERO и Bridge, са публикувани във v2, а нативната поддръжка за двете е планирана, но не е доставена. Така че конверсията е ваша отговорност и тя работи в собствен виртуален енвайрънмънт по конкретна причина: scripts/lerobot_conversion носи свой собствен `pyproject`, който изисква Python 3.10 или 3.11 и фиксира `lerobot` към един `git commit`, докато самият Isaac-GR00T изисква Python 3.12. Инсталирайте конвертора от корена на хранилището и вместо това ще получите пакета gr00t , което е грешката, за която предупреждава неговият README. Ако сте нов във формата, набор от данни LeRobot в речника обяснява какво всъщност има вътре.

bash
# 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
Конверторът приема --repo-id, незадължителен --root и --force-conversion, което изтрива всяко съществуващо локално копие и го изтегля отново. Той записва codebase_version: v2.1 в meta/info.json.
Конверсията презаписва на място

Ако наборът от данни 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./, и един допълнителен файл, който стандартният LeRobot не притежава. Този допълнителен файл е мястото, където се намират повечето от останалите грешки.

Стъпка 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, дословно.

json
{
  "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"
    }
  }
}
examples/SO100/modality.json. Индексите са базирани на нула и следват нарязването на Python, така че single_arm е [0:5], а gripper е [5:6].

Копирайте го във вашия конвертиран набор от данни на meta/modality.json и преименувайте видео ключовете на това, както всъщност се наричат вашите камери. Ако сте записали с една горна камера, наречена top, тогава original_key е observation.images.top и приятелското име е това, което ще реферира вашата конфигурация на данни. Двете трябва да съвпадат и нито едно от тях не проверява другото вместо вас. Анотацията на езика е по-лоша, защото един и същ ключ трябва да се появи на три места.

СлойФайлSO-100 форма, използвана в хранилището
Parquet колонаdata/chunk-*/episode_*.parquetannotation.human.task_description
Ключ в modality.jsonmeta/modality.json, under "annotation", without the annotation. prefixhuman.task_description
modality_keys в конфигурацията на даннитеyour so100_config.pyannotation.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 целева позиция, тъй като двоичен сигнал отворено-или-затворено се държи по-добре като цел, отколкото като делта.

python
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)
examples/SO100/so100_config.py, съкратен до най-същественото. NON_EEF означава пространство на ставите; EEF би очаквало девет-измерен вектор от x, y, z плюс 6D ротация.

Два детайла тук ще ви струват един ден, ако не ги знаете. Първо, action_configs е позиционен: документацията изисква същата дължина и същия ред като modality_keys, и те са директни относно последствията от грешка, а именно, че грешното представяне се прилага мълчаливо. Вашият захват се обучава като делта, а ръката ви като абсолютна цел, и няма съобщение за грешка. Второ, register_modality_config твърди, че тагът не е вече регистриран, така че втора NEW_EMBODIMENT конфигурация в същия Python процес умира с Embodiment tag ... already registered. Не можете да импортирате две от тези в един скрипт. Трето правило се прилага по-късно, при разгръщане: delta_indices на действието трябва да бъде непрекъснат диапазон, започващ от нула. Разреден прозорец като [0, 4, 8] се отхвърля, защото всичко надолу по веригата индексира предсказания блок линейно и иначе би изпълнило грешни редове.

Променете delta_indices и трябва да генерирате отново статистиките

Статистиките за нормализация, по-специално 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. 1
    Инсталирайте git-lfs, след това клонирайте със субмодули

    git-lfs е задължителен, не по избор. Без него parquet файловете в demo_data/ се изтеглят като указателни пънове и демонстрационното изпълнение се проваля на набор от данни, който изглежда присъства в списъка с файлове.

    bash
    sudo apt install git-lfs && git lfs install
    git clone --recurse-submodules https://github.com/NVIDIA/Isaac-GR00T
    cd Isaac-GR00T
  2. 2
    Инсталирайте uv и синхронизирайте средата

    Инсталацията по подразбиране изтегля GPU зависимостите, включително flash-attn и TensorRT. На чисто A100 или H100 изображение това е най-дългата единична стъпка, така че я направете, преди да обърнете внимание на нещо друго.

    bash
    curl -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. 3
    Автентикирайте се срещу Hugging Face

    Направете това преди първото стартиране на обучението, а не след като се провали осем минути по-късно.

    bash
    uv run huggingface-cli login   # or: export HF_TOKEN=<your_token>
  4. 4
    Проверка за изправност на предоставените SO-100 демонстрационни данни

    Преди да докоснете собствения си запис, изпълнете 2000 стъпки на demo_data/cube_to_bowl_5. Това са пет епизода, завършва бързо и доказва средата, а не вашите данни. Ако това изпълнение се провали, нищо, което направите с вашия набор от данни, няма да помогне.

    bash
    CUDA_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 пропуска. Това е в тесен смисъл: езиковата основа и визуалният енкодер остават замразени, а това, което се обучава, е проекторът и дифузионната глава за действие.

bash
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
Един GPU. За осем карти заменете стартера с uv run torchrun --nproc_per_node=8 --master_port=29500 и задайте --num-gpus 8. Използвайте uv run torchrun, а не само torchrun, иначе ще получите грешна среда.
ФлагПо подразбиране във FinetuneConfigКакво прави
--global-batch-size64Общ пакет данни за всички GPU преди натрупване на градиенти. Доставените примери използват 32.
--learning-rate1e-4Същата стойност, която AY-Robots изпраща за своя groot1.7 обучител.
--max-steps10000Общ брой стъпки на оптимизатора. Обвивката examples/finetune.sh също е по подразбиране 10000.
--gradient-accumulation-steps1Умножава ефективния пакет данни. Стойности над 1 издават предупреждение, което ви информира за натрупания размер.
--save-steps and --save-total-limit1000 and 5Честота на контролните точки и колко от тях се запазват. По-старите се изтриват.
--weight-decay and --warmup-ratio1e-5 and 0.05Зададени изрично и от examples/finetune.sh.
--state-dropout-prob0.2 in the CLI, 0.8 in the model configСлучайно изпуска проприоцептивно състояние по време на обучение. Намалете го, ако задачата ви разчита на състоянието.
--tune-llm and --tune-visualFalse and FalseОсновата остава замразена по подразбиране.
--tune-projector and --tune-diffusion-modelTrue and TrueПроекторът и дифузионната глава за действие са това, което всъщност се обучава.
--use-percentilesTrueНормализирайте с q01 и q99 вместо със сурови минимални и максимални стойности.
--dataloader-num-workers2Зареждащото устройство е базирано на CPU по дизайн. Примерите го увеличават до 4.
--seeddoes not existНяма флаг за seed в този CLI.

Този последен ред не е печатна грешка. launch_finetune.py е tyro CLI, генериран от dataclass, и този dataclass няма поле за seed. README отделно отбелязва 5 до 6 процента разлика между изпълненията, причинена от недетерминистично уголемяване на изображенията. Две изпълнения с идентични флагове няма да произведат идентични контролни точки, което е от голямо значение, когато се опитвате да решите дали промяната на хиперпараметър е помогнала или просто сте имали късмет. За сравнение, собственият обучител на lerobot по подразбиране използва seed 1000, а рецептата LeRobot GR00T подава --seed=42 изрично.

Валидацията е изключена по подразбиране, а документираният флаг не е наличен в този CLI

Финното настройване се изпълнява с eval_strategy="no", така че изобщо няма крива на загуба при валидация. Получавате само загуба при обучение и нищо друго. Ръководството за ново въплъщение ви казва да го включите с --eval-strategy steps --eval-steps 500, но този флаг не съществува в launch_finetune.py: CLI се генерира от tyro от FinetuneConfig dataclass, а eval_strategy, eval_steps и eval_batch_size са полета на TrainingConfig вместо това. Техните стойности по подразбиране там са "no", 500 и 2. За да ги достигнете, използвайте по-пълната входна точка gr00t/experiment/launch_train.py, където вложеният флаг е --training.eval-strategy. Така или иначе, само по себе си намаляващата загуба при обучение ви казва много малко за обобщението, което е точно ситуацията, описана в загубата намалява, но политиката не прави нищо.

Какво струва едно изпълнение от 20000 стъпки

GR00T N1.7 се нуждае от 80 GB карта, така че въпросът за цената има тесен отговор. На AY-Robots обучителят groot1.7 работи на ниво A100 80 GB или H100 80 GB, където едно изпълнение отнема 3 до 6 часа при 1.20 до 2.00 USD на час на спот пазара. Това е приблизително 4 до 12 USD за стандартната задача от 20000 стъпки. Същата задача на SmolVLA или ACT се изпълнява на 24 GB карта при 0.30 до 0.60 USD на час и 1 до 3 USD на изпълнение. Това е истинският компромис: GR00T струва около четири пъти повече на опит и не можете да го стартирате на 4090 под бюрото си.

МоделНиво на GPUТипично изпълнениеТипична ценаМинимален брой епизоди
GR00T N1.7A100 80 GB or H100 80 GB3 to 6 hours4 to 12 USD50
GR00T N1.5A100 80 GB or H100 80 GB3 to 6 hours4 to 12 USD50
Pi0.5A100 80 GB or H100 80 GB3 to 6 hours4 to 12 USD50
SmolVLARTX 4090 or any 24 GB card2 to 5 hours1 to 3 USD30
ACTRTX 4090 or any 24 GB card2 to 5 hours1 to 3 USD50

Минимумът от 50 епизода е долна граница, а не цел. Собствените ЧЗВ на NVIDIA са по-взискателни: приблизително 100 траектории за просто взимане и поставяне на фиксирано място, 500 или повече за сложни или многостъпкови сцени и 100 до 500 за фина манипулация. Ако сте на 20 епизода, прекарайте следобеда в записване, вместо вечерта в настройване. Ръководството за събиране на данни обхваща какво отличава полезния епизод от пропиления, запишете първия си набор от данни е кратката версия, а събиране на данни за SO-100 е специфичната за ръката.

Ръководството за обучение на AY-Robots за GR00T N1.7 на SO-100, показващо лентата със спецификации с ниво на GPU, необходим формат на набора от данни и настройките по подразбиране на обучителя
Ръководството /train/groot-n1-7-on-so-100 представя фактите, които иначе бихте възстановили на ръка: ниво на GPU, формат на набора от данни и точните настройки по подразбиране, които изпраща обучителят.

Стъпка 6: оценка в отворен цикъл, преди да докоснете ръката

Не поставяйте нова контролна точка на физическа ръка, за да разберете дали обучението е проработило. Първо стартирайте оценката с отворен цикъл. Тя преиграва записан епизод, изисква действия от модела на всяка стъпка и изобразява предсказанието спрямо реалността с MSE и MAE. Не струва нищо и улавя грешките в картографирането от стъпки 2 и 3.

bash
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
Графиките се записват в /tmp/open_loop_eval/traj_<id>.jpeg, освен ако не подадете --save-plot-path. По подразбиране: --execution-horizon 16, --steps 200, --denoising-steps 4, --traj-ids 0.

Хранилището умишлено отказва да публикува целево MSE за персонализирани данни и това е правилното решение: числото зависи от вашите единици за действие, вашата задача и размера на вашия набор от данни, така че праг, копиран от чужда ръка, не означава нищо. Това, което е смислено, е тенденцията. Ето референтното изпълнение, което хранилището документира на един H100 с демонстрационния набор от данни от пет епизода и 2000 стъпки.

Контролна точкаСредно MSE на traj 0Средно MAE на traj 0
50087.55.63
100025.43.30
150013.22.18
200010.01.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 входна точка. Тук са важни две неща. LeRobot CLI е набор от конзолни скриптове, така че всичко, което четете и казва python lerobot/scripts/train.py е остаряло и няма да работи. И LeRobot премахна поддръжката за GR00T N1.5 изцяло, отхвърляйки N1.5 контролни точки и конфигурации с бележка за миграция, така че ако имате нужда от N1.5 чрез LeRobot, трябва да фиксирате lerobot==0.5.1, последната версия, която го поддържа, публикувана на 7 април 2026 г.

bash
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
Рецептата за GR00T N1.7, вградена в LeRobot. Забележете relative_exclude_joints: гриперът е изключен от относителните действия, което е същото решение, което so100_config.py взима с ActionRepresentation.ABSOLUTE.
АспектIsaac-GR00T launch_finetune.pylerobot-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
Публикувани референтни резултатиSO-100 тенденция на MSE в отворен цикъл върху демонстрационни данниLIBERO пакети, 96.5 процента средно за четири пакета
Път за разгръщанеrun_gr00t_server.py плюс eval_so100.py през ZMQlerobot-rollout, с chunking в реално време (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 и контролирате всяка стъпка. Реално, първият път отнема един следобед, а след това – по двадесет минути всеки път.

  1. Записвайте епизоди с lerobot-record на SO-100. Получавате LeRobot v3.0 набор от данни.
  2. Конвертирайте го до v2.1 със scripts/lerobot_conversion/convert_v3_to_v2.py в собствена виртуална среда.
  3. Напишете meta/modality.json и Python конфигурация за модалност, регистрирана под EmbodimentTag.NEW_EMBODIMENT.
  4. Наемете 80 GB карта, клонирайте със субмодули, uv sync, удостоверете се срещу Hugging Face.
  5. Изпълнете launch_finetune.py, след това open_loop_eval.py на няколко контролни точки и сравнете тенденцията на MSE, преди да докоснете хардуера.
  6. Изтеглете контролната точка от машината, преди да унищожите инстанцията, след това изградете пътя за обслужване до рамото.
Стъпката, която всички забравят

Копирайте контролната точка от наетата инстанция, преди да я изключите. --save-total-limit 5 също означава, че по-старите контролни точки се изтриват с напредването на обучението, така че контролната точка, която сте искали на стъпка 5000, може вече да не съществува на стъпка 20000.

Матрицата за обучение на AY-Robots с пет модела на политики като редове и четири роботизирани рамена като колони, като всяка клетка води до конкретно ръководство за обучение
Матрицата /train: пет модела срещу четири рамена. Редът GR00T N1.7 също обхваща SO-101, Koch v1.1 и LeKiwi.

Връщане на контролната точка обратно на рамото

Isaac-GR00T използва разделение сървър-клиент през ZMQ. Политиката работи на GPU, а тънък клиент на машината на робота изпраща наблюдения и получава части от действия. Примерът със SO-100 е достатъчно пълен за копиране: стартирайте run_gr00t_server.py с вашата контролна точка и --embodiment-tag NEW_EMBODIMENT, след това изпълнете eval_so100.py от страната на робота със серийния порт, идентификатора на робота, индексите на камерата и езиковата инструкция. Имената на камерите в тази команда трябва да съответстват на приятелските имена от вашия modality.json, а не на номерата на устройствата на ОС.

bash
# 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"
--execution-horizon контролира колко от предвидените стъпки се изпълняват преди препланиране. Трябва да е най-много action_horizon на политиката, като това число е дължината на action delta_indices във вашата конфигурация на модалност, а не на базовия модел. Доставената конфигурация SO-100 предвижда 16, така че 16 е вашият таван; базовият контролен пункт nvidia/GR00T-N1.7-3B е конфигуриран за 40, а policy.md ясно посочва, че фино настроените контролни пунктове може да се различават. Превишите ли го, ще получите ValueError, посочващ и двете числа. 8 е стойността, която документацията предлага за внедряване в реално време. Старото име на флага --action-horizon все още работи, но предупреждава.
7.4 V, не 12 V

Докато свързвате отново рамото: 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 GB възел за фина настройка. За информация защо тези модели се държат по този начин, и си струва да се прочетат първо. И ако все още не притежавате ръка, предава физически SO-100 без регистрация.

Колко епизода са ми необходими, преди фината настройка на GR00T N1.7 да си струва?

AY-Robots определя минимум от 50 епизода за обучителя groot1.7. Собствените ЧЗВ на 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 GB или повече VRAM за фина настройка и посочва H100 или L40 възли; други карти работят, но отнемат много повече време. 4090 има 24 GB. AY-Robots предлага GR00T N1.7 само на ниво A100 80 GB и H100 80 GB по същата причина. Инференцията е различна история: 16 GB са достатъчни за обслужване на модела, така че 4090 може да изпълнява политика, която не може да обучи. Ако искате VLA, който можете да обучите на 24 GB, това е SmolVLA с около 450 M параметри или ACT с около 80 M.

Защо две изпълнения с идентични флагове дават различни контролни точки?

Защото launch_finetune.py няма seed. Това е tyro CLI, генериран от 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 GB или H100 на спот пазара, стартира обучителя с пакет 32, скорост на обучение 1e-4 и 20000 стъпки, и записва контролни точки в обектно хранилище. Приблизително 4 до 12 USD на изпълнение.

Отворете ръководството за обучение на GR00T N1.7

Ready for high-quality robotics data?

AY-Robots connects your robots to skilled operators worldwide.

Get Started