
What actually changed between GR00T N1.5 and N1.7: the Cosmos-Reason2 backbone swap, relative actions, why old checkpoints will not load, dataset compatibility, and when to stay.
NVIDIA shipped GR00T N1.5 on 11 June 2025, then N1.6, and GR00T N1.7 is now the General Availability release on the main branch of the Isaac-GR00T repository. The version numbers suggest a point upgrade. They are misleading. The vision-language backbone was replaced, the action space went from absolute to relative, state and action dimensions grew from 64 and 32 to 132, and the fine-tuning entry point moved to a different file with different flags.
This is a migration guide, not a launch post. It covers what changed, whether your LeRobot dataset survives the move, whether an old checkpoint still loads (it does not), which flags were renamed, and when staying on N1.5 is correct. Every number below was read from a config file, a source file or a README on 2026-08-23, and where upstream contradicts itself that is said plainly.
What you need to know
- •N1.7 is not a drop-in upgrade. Its checkpoint declares model_type Gr00tN1d7, N1.5 declares gr00t_n1_5, and no converter exists.
- •The VLM backbone moved from a vendored Eagle model to nvidia/Cosmos-Reason2-2B, a 2.44 B parameter model built on Qwen3-VL-2B-Instruct and gated on Hugging Face. Every N1.7 checkpoint pulls it on first load.
- •Your recorded data is fine. Both read a GR00T flavour of LeRobot v2 with a meta/modality.json, so you rewrite the config, not the episodes.
- •Relative actions did not start with N1.7. N1.6 already predicted state-relative chunks; N1.7 makes it a relative EEF space shared with human video.
- •Licensing reversed: N1.5 weights are noncommercial, N1.7 weights ship under the NVIDIA Open Model License and repo code is Apache 2.0.
- •On AY-Robots both stay trainable: A100 80 GB or H100 80 GB, 50 episodes minimum, LeRobot v2.0 or v2.1.
Two different models that share a family name
The fastest way to see how far apart they are is to read the config.json files side by side. Each is public, and each is what the loader parses. Here is what they declare as of 2026-08-23, with N1.6 in the middle.
| config.json field | GR00T N1.5 | GR00T N1.6 | GR00T N1.7 |
|---|---|---|---|
| architectures | GR00T_N1_5 | Gr00tN1d6 | Gr00tN1d7 |
| model_type | gr00t_n1_5 | Gr00tN1d6 | Gr00tN1d7 |
| VLM backbone | NVEagle/eagle_er-qwen3_1_7B-Siglip2_400M_stage1_5_128gpu_er_v7_1mlp_nops (vendored) | nvidia/Eagle-Block2A-2B-v2 | nvidia/Cosmos-Reason2-2B |
| action_horizon | 16 | 50 | 40 |
| max_state_dim | 64 | 128 | 132 |
| max_action_dim | 32 | 128 | 132 |
| diffusion_model_cfg.num_layers | 16 | 32 | 32 |
| model_dtype | float32 | bfloat16 | bfloat16 |
| select_layer | 12 | 16 | 16 |
| tune_top_llm_layers | not present | 4 | 0 |
| use_relative_action | not present | true | not present as a flag; relative EEF is the default |
| transformers_version | 4.51.3 | 4.51.3 | 4.57.1 |
The parameter count is unchanged at roughly 3 billion in all three, which is why the headline stayed the same and the internals did not. Note the transformers pin: N1.5 and N1.6 record 4.51.3, N1.7 records 4.57.1. One environment cannot serve both, which matters more day to day than any architectural bullet.
# Read the declarations yourself, no clone and no GPU needed
curl -s https://huggingface.co/nvidia/GR00T-N1.5-3B/raw/main/config.json \
| python3 -c "import json,sys; c=json.load(sys.stdin); h=c['action_head_cfg']; \
print(c['model_type'], 'horizon', c['action_horizon'], 'state', h['max_state_dim'])"
curl -s https://huggingface.co/nvidia/GR00T-N1.7-3B/raw/main/config.json \
| python3 -c "import json,sys; c=json.load(sys.stdin); \
print(c['model_type'], 'horizon', c['action_horizon'], 'state', c['max_state_dim'])"The backbone swap has the widest blast radius
N1.5 used a vendored Eagle vision-language model, frozen during both pretraining and fine-tuning. N1.6 switched to nvidia/Eagle-Block2A-2B-v2 and unfroze the top four LLM layers. N1.7 replaces Eagle entirely with nvidia/Cosmos-Reason2-2B, a 2.44 billion parameter VLM whose Hugging Face metadata lists Qwen/Qwen3-VL-2B-Instruct as its base model, and sets tune_top_llm_layers back to 0. The stated gain is flexible resolution: images are encoded in their native aspect ratio without padding.
nvidia/Cosmos-Reason2-2B requires you to accept a license on Hugging Face before it downloads, and every GR00T N1.7 checkpoint loads it on first use, including the base nvidia/GR00T-N1.7-3B. You can confirm the gate without an account: a plain curl of the model card returns 401. Without access, loading dies with a GatedRepoError or 401 Client Error naming the backbone rather than GR00T, so the stack trace points somewhere unhelpful. Request access, then huggingface-cli login or export HF_TOKEN. N1.5 had no gated dependency, so this catches every pipeline once. See training job stuck queued.
There is a quieter consequence. A vision-language-action model inherits its language grounding from the backbone, so prompts tuned against Eagle can land differently after the swap, especially for tasks that name objects. If your policy carried an odd prompt that happened to work, re-test it.
The action head, the horizon, and relative actions
N1.7 keeps the flow-matching diffusion transformer head, so the architecture from the GR00T N1 paper still describes it: a vision-language module reads the scene and a diffusion transformer denoises an action chunk. What changed is the chunk, and what the numbers inside it mean.
| Behaviour | GR00T N1.5 | GR00T N1.7 |
|---|---|---|
| Action head | Flow-matching DiT, 16 layers | Flow-matching DiT, 32 layers in the shipped base config |
| Predicted chunk length | 16 steps | 40 in the base config; the SO-100 example config asks for 16 |
| Action representation | Absolute joint or end-effector targets | Relative deltas for most axes, gripper absolute in the SO-100 example |
| When relative arrived | not applicable | N1.6 introduced state-relative chunks; N1.7 makes it a shared relative EEF space |
| Normalization default | min_max in the shipped so100 data config | q01/q99 percentiles (use_percentiles defaults to True) |
| Human video in pretraining | FLARE latent-alignment objective, which NVIDIA says unlocks learning from human ego video | 20K hours of EgoScale video, shared relative EEF representation |
| Rollout flag | --action-horizon | --execution-horizon |
The relative action space is NVIDIA's stated reason for N1.7's cross-embodiment behaviour: a delta means the same thing on a human arm and a robot arm, so priors from human video transfer. It is also the change most likely to break a naive port. Copy an N1.5 modality config forward and you feed absolute targets to a model expecting deltas, which reads as a calibration fault rather than a config fault. The N1.7 SO-100 example sets ActionRepresentation.RELATIVE for the arm joints and ActionRepresentation.ABSOLUTE for the gripper, since a binary open and close works better as a target.
The README's collapsed "Detailed changes from N1.6" list does not match the published config.json files, read on 2026-08-23. It claims the DiT drops 32 to 16 layers (N1.7 config: num_layers 32), select_layer 16 to 12 (config: 16), load_bf16 true to false (config: true), state and action dims 29 to 132 (N1.6 config: 128), action_horizon 16 to 40 (N1.6 config: 50), transformers 4.51.3 to 4.57.3 (N1.7 config: 4.57.1). Only tune_top_llm_layers 4 to 0 matches. Several "before" values are N1.5 numbers, so the list looks written against the wrong baseline. Treat config.json as authoritative for whatever revision you pull.
Do your old N1.5 checkpoints still load? No.
This is usually the first question and the answer is unambiguous. The N1.5 model class lived in a flat module, gr00t/model/gr00t_n1.py, holding the class GR00T_N1_5. That file is gone from main, and so is scripts/gr00t_finetune.py. The packaged layout arrived with N1.6: the n1d6 branch holds a gr00t_n1d6 package, main holds gr00t_n1d7, and there is no gr00t_n1d5 package and never was. LeRobot went further and removed N1.5 support outright rather than letting it fail obscurely.
GR00T N1.5 support was removed from LeRobot. To keep using an N1.5
checkpoint, pin the last release that supports it:
`pip install 'lerobot==0.5.1'`. To use the current release, migrate to
GR00T N1.7 (model_version='n1.7', base model nvidia/GR00T-N1.7-3B).The code comment there is unusually honest: the legacy identifier is retained so the N1.7 loader can fail loudly rather than silently treating an N1.5 checkpoint as N1.7. Mirror that in your own tooling: a silent mis-load produces a policy that runs, emits actions, and is wrong.
NVIDIA left the previous releases on branches: n1d5 and n1d6. Nothing forces a deadline. Keep a second virtualenv pinned to n1d5 and lerobot==0.5.1, keep the N1.5 checkpoints in object storage, and decommission only after the N1.7 policy beats them on your arm.

Dataset compatibility: episodes survive, config does not
The good news dominates. Both versions consume a GR00T flavour of the LeRobot v2 format: parquet under data/chunk-000/, mp4 under videos/chunk-000/, and a GR00T-specific meta/modality.json mapping the concatenated state and action arrays into named fields. That schema did not change, so a dataset recorded a year ago for an SO-100 is still valid input.
What changed is the layer above. N1.5 selected a registered Python class by name with --data-config so100, and that class carried its transforms inline: crop scale 0.95, resize to 224x224, color jitter, min_max normalization. N1.7 replaced it with --modality-config-path, a Python file you supply that builds ModalityConfig objects and calls register_modality_config. The transforms moved onto the CLI as --color-jitter-params, --shortest-image-edge, --crop-fraction and --use-percentiles.
- 1Confirm the dataset version first
GR00T reads LeRobot v2. A v3.0 dataset will not load, and the downstream failure is not obvious.
bashpython3 -c "import json;print(json.load(open('my_dataset/meta/info.json'))['codebase_version'])" # expect: v2.0 or v2.1 - 2Convert down from v3 if needed
The repo ships a helper with its own pyproject.toml, installed separately so its LeRobot pin does not fight the GR00T one.
bashcd scripts/lerobot_conversion uv venv && source .venv/bin/activate uv pip install -e . --verbose python convert_v3_to_v2.py --repo-id <DATASET_REPO_ID> - 3Put modality.json back where the loader expects it
Conversion does not produce the GR00T-specific mapping file. The SO-100 example maps single_arm to indices 0 to 5 and gripper to 5 to 6, for both state and action, with video keys front and wrist.
bashcp examples/SO100/modality.json \ my_dataset/meta/modality.json - 4Rewrite the data config as a modality config
The real porting work: rebuild the old class as a file registering ModalityConfig objects under EmbodimentTag.NEW_EMBODIMENT, action representation set explicitly per key.
pythonfrom 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], modality_keys=["front", "wrist"]), "state": ModalityConfig(delta_indices=[0], modality_keys=["single_arm", "gripper"]), "action": ModalityConfig( delta_indices=list(range(0, 16)), modality_keys=["single_arm", "gripper"], action_configs=[ ActionConfig(rep=ActionRepresentation.RELATIVE, type=ActionType.NON_EEF, format=ActionFormat.DEFAULT), ActionConfig(rep=ActionRepresentation.ABSOLUTE, 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)
The N1.5 SO-100 data config normalized state and action with min_max. The N1.7 finetune config defaults use_percentiles to True, which its own docstring defines as q01/q99 percentile statistics instead of full min/max. On clean data the difference is small. With a few outlier frames - a servo at its limit, one bad reading - the two produce visibly different action scaling, and the symptom is a policy that consistently undershoots or overshoots. When comparing versions, set the flag explicitly on both sides. See also joint stops early and dataset rejected as v3.
The CLI is a different program now
Both entry points are tyro CLIs generated from a dataclass, so --help is authoritative. Here is the mapping between the flags you had and the flags you need.
| GR00T N1.5 | GR00T N1.7 | What to watch |
|---|---|---|
| scripts/gr00t_finetune.py | gr00t/experiment/launch_finetune.py | The old path returns 404 on the main branch |
| --data-config so100 | --modality-config-path examples/SO100/so100_config.py | A registered name becomes a Python file you write |
| --batch-size 32 (per device) | --global-batch-size 32 (summed over GPUs, pre-accumulation) | Same number, different meaning; on 8 GPUs this is an 8x cut |
| --lora_rank 64 --lora_alpha 128 | removed | gr00t/utils/peft.py is gone; no LoRA path in the N1.7 config |
| --video-backend torchcodec|decord|torchvision_av | removed | torchcodec only, and it needs FFmpeg 4 to 7, not 8 |
| --embodiment-tag defaults to new_embodiment | --embodiment-tag is required | It has no default in FinetuneConfig, so the run refuses to start without it |
| --action-horizon (rollout) | --execution-horizon | How many predicted actions execute per policy call |
| --resume | --resume-from-checkpoint | Defaults to False, so a rerun into an existing output-dir starts fresh |
| report_to defaults to wandb | --use-wandb, defaults to False | But examples/finetune.sh sets USE_WANDB=1 unless you override it |
| not available | --ds-weights-alpha, --state-dropout-prob | Dataset mixture weighting and state-input dropout |
# GR00T N1.5, the way it was (n1d5 branch)
python scripts/gr00t_finetune.py \
--dataset-path ./my_dataset \
--data-config so100 \
--embodiment-tag new_embodiment \
--batch-size 32 \
--max-steps 20000 \
--num-gpus 1
# GR00T N1.7, the way it is (main branch)
CUDA_VISIBLE_DEVICES=0 uv run python \
gr00t/experiment/launch_finetune.py \
--base-model-path nvidia/GR00T-N1.7-3B \
--dataset-path ./my_dataset \
--embodiment-tag NEW_EMBODIMENT \
--modality-config-path examples/SO100/so100_config.py \
--num-gpus 1 \
--output-dir /tmp/so100_finetune \
--max-steps 20000 \
--global-batch-size 32 \
--dataloader-num-workers 4global_batch_size 64, learning_rate 1e-4, max_steps 10000, gradient_accumulation_steps 1, dataloader_num_workers 2, save_steps 1000, save_total_limit 5, warmup_ratio 0.05, state_dropout_prob 0.2, tune_llm False, tune_visual False, tune_projector True, tune_diffusion_model True. Three matter. save_total_limit: 5 prunes older checkpoints, so a long run will not keep the early ones you wanted for a learning-curve check. state_dropout_prob is 0.2 on the CLI but 0.8 in the model config, and the benchmark scripts override it per suite - lower it if your task leans on proprioceptive state. And neither version lets you set a seed from the CLI: N1.5 hardcodes seed=42 inside gr00t_finetune.py, N1.7's FinetuneConfig has no seed field at all. The README puts run-to-run variance from non-deterministic image augmentation at 5 to 6 percent, so treat smaller single-run deltas with suspicion.
Does the new model actually do better?
The most comparable public evidence is LIBERO, because both branches publish a table for it: examples/Libero/README.md on n1d5 and examples/LIBERO/README.md on main.
| LIBERO suite | GR00T N1.5 (n1d5 branch) | GR00T N1.7 (main branch) |
|---|---|---|
| Spatial | 46/50 (92%) | 195/200 (97.65%) |
| Goal | 43/50 (86%) | 195/200 (97.5%) |
| Object | 46/50 (92%) | 197/200 (98.45%) |
| 10 (Long) | 38/50 (76%), 60K steps | 189/200 (94.35%), 20K steps |
| Batch size used | 128, and 72 with grad accum 4 for Goal | 640 |
| Episodes per suite | 50 | 200 |
The N1.5 README says its numbers came from "minimal hyperparameter tuning" and were "intended primarily for demonstration purposes", and points at published work scoring higher. The runs also differ in batch size (128 versus 640), evaluation episodes (50 versus 200), and training length on the Long suite (60K versus 20K steps). The direction is credible; the gap is not a measurement. LeRobot's N1.7 integration reports a different set again from its own harness - 95, 100, 98 and 93 percent for Spatial, Object, Goal and Long - which shows the harness matters as much as the model.
For the wider picture, the arena tracks 85 VLA models with 332 benchmark results, each linked to its paper or model card, with separate entries for GR00T N1.5, GR00T N1.6 and GR00T N1.7.

Licensing: the quiet reason most teams move
This gets less attention than the backbone swap and decides more migrations. The N1.5 card says the model is "ready for non-commercial use" and links the NVIDIA OneWay Noncommercial License. The N1.7 card says "ready for commercial/non-commercial use" and links the NVIDIA Open Model License, with repo code under Apache 2.0. If you built a product on an N1.5 fine-tune, that driver does not care whether N1.7 is better on your task.
- Weights you can use commercially under the NVIDIA Open Model License, with Apache 2.0 code.
- A maintained branch. N1.5 is frozen and LeRobot has already dropped it.
- Relative end-effector actions and 20K hours of EgoScale human video in pretraining.
- Higher published LIBERO success rates on all four suites, per the repo's own tables.
- Slightly faster on this platform: 152 ms per action step against 165 ms for N1.5.
- Full ONNX and TensorRT export, plus documented Jetson Thor, Orin and DGX Spark install paths.
- Every existing N1.5 checkpoint is dead weight. No converter, no shortcut; retrain from the new base.
- A gated Hugging Face dependency in the critical path of every load, including CI.
- LoRA is gone, so fine-tuning on a 24 GB card the way N1.5 allowed no longer exists.
- Guidance moved up: N1.5 documented 4090 fine-tuning with --no-tune_diffusion_model, N1.7 recommends 40 GB or more.
- A whole new environment: N1.5 was tested on Python 3.10 and CUDA 12.4, N1.7 wants Python 3.12 and CUDA 12.8.
- torchcodec is the only video backend and needs FFmpeg 4 to 7, so a distro shipping FFmpeg 8 breaks the install.
When staying on N1.5 is correct
Migration is not free, and a working N1.5 policy on a fixed task beats an untested N1.7 one. Stay put if any of these describe you.
- You have a deployed policy hitting its target on one arm, one cell, one task, and nothing is changing. A frozen branch is a stable branch.
- Your use is academic or internal, so the noncommercial license was never a constraint.
- Your hardware tops out at 24 GB and you relied on LoRA. Plan a hardware step, or look at SmolVLA and ACT, which run on any 24 GB card.
- You cannot accept a gated dependency in an air-gapped or tightly reviewed build. Cosmos-Reason2-2B is not optional for N1.7.
- You are mid-experiment. Changing the base model invalidates every baseline you recorded; finish, then migrate.
- Your task is fast and reactive rather than slow pick-and-place. Neither version fixes that, and 13 ms will not either.
One thing that is not a reason to stay: fear that your recorded episodes are wasted. The format is the part that survived intact, and a well-recorded dataset outlives every model generation you train on it. The data-collection guide covers what makes one durable.
Two ways to run the migration
You need 40 GB or more for fine-tuning (the repo recommends H100 or L40 nodes; A6000 works but converges slower), CUDA 12.8, Python 3.12 and FFmpeg between 4 and 7. Budget the first day for the environment, not the model.
- 1Clone with submodules and build the environment
git-lfs is required for the demo parquet files, and uv handles GPU dependencies pip does not.
bashsudo apt install git-lfs && git lfs install git clone --recurse-submodules https://github.com/NVIDIA/Isaac-GR00T cd Isaac-GR00T sudo apt-get update && sudo apt-get install -y ffmpeg curl -LsSf https://astral.sh/uv/install.sh | sh uv sync --python 3.12 uv run python -c "import gr00t; print('GR00T installed successfully')" - 2Unlock the gated backbone before you touch the model
Accept the license on the Cosmos-Reason2-2B page, then authenticate. Do this before the first launch, not after it fails at 3 a.m.
bashuv run huggingface-cli login # or: export HF_TOKEN=<your_token> - 3Prove the stack works on the shipped example first
demo_data/cube_to_bowl_5 is five SO-100 episodes with a matching modality config. If it does not run, your own data will not either.
bashCUDA_VISIBLE_DEVICES=0 NUM_GPUS=1 uv run bash examples/finetune.sh \ --base-model-path nvidia/GR00T-N1.7-3B \ --dataset-path demo_data/cube_to_bowl_5 \ --modality-config-path examples/SO100/so100_config.py \ --embodiment-tag NEW_EMBODIMENT \ --output-dir /tmp/so100_finetune - 4Establish a baseline you can compare against
Upstream deliberately publishes no target MSE here, because five episodes will not transfer to your task. The curve shape is the signal. Their reference run on 1x H100 at --max-steps 2000, on traj 0, went 87.5 at step 500, 25.4 at 1000, 13.2 at 1500, 10.0 at 2000.
bashuv run python gr00t/eval/open_loop_eval.py \ --dataset-path demo_data/cube_to_bowl_5 \ --embodiment-tag NEW_EMBODIMENT \ --model-path /tmp/so100_finetune/checkpoint-2000 \ --traj-ids 0 \ --execution-horizon 16 \ --steps 400 \ --modality-keys single_arm gripper - 5Serve the policy and drive the arm
Server on the GPU box, thin client next to the servos, port 5555 by default.
bashuv run python gr00t/eval/run_gr00t_server.py \ --model-path /tmp/so100_finetune/checkpoint-2000 \ --embodiment-tag NEW_EMBODIMENT \ --device cuda:0 --host 0.0.0.0 --port 5555
Keep the old environment alive in parallel. A second virtualenv on the n1d5 branch with transformers 4.51.3 costs disk and nothing else, and it is the only way to run the A/B that justifies the migration.
The platform keeps both as separate trainer targets, so the migration is a dropdown change plus a retrain rather than an environment rebuild. Pick the dataset, pick GR00T N1.7 instead of GR00T N1.5, and the backend rents an A100 80 GB or H100 80 GB by required VRAM, runs the trainer, and writes checkpoints to object storage.
| GR00T N1.5 | GR00T N1.7 | |
|---|---|---|
| Trainer key | groot1.5 | groot1.7 |
| Default batch size | 1 | 32 |
| Default learning rate | 1e-5 | 1e-4 |
| Default max steps | 2000 | 20000 |
| Gradient accumulation | 16 (applied) | 1 (applied) |
| GPU tier | A100 80 GB or H100 80 GB | A100 80 GB or H100 80 GB |
| Minimum episodes | 50 | 50 |
| Dataset format | LeRobot v2.0 or v2.1 | LeRobot v2.0 or v2.1 |
| Inference latency | 165 ms per action step | 152 ms per action step |
| Base checkpoint | nvidia/GR00T-N1.5-3B | nvidia/GR00T-N1.7-3B |
It cannot convert a GR00T N1.5 checkpoint into an N1.7 one, because nobody can. Switching the model in the training form starts a fresh fine-tune from nvidia/GR00T-N1.7-3B against the same dataset. It also cannot give you a seed: the Isaac-GR00T entry point exposes none, so runs here are not bit-for-bit reproducible either. GR00T is cloud-only here for both versions; only SmolVLA and ACT also run locally.
Because the dataset requirement is identical on both sides, the honest comparison is cheap: train the same dataset twice, once per version, and compare on your arm rather than on LIBERO. At 3 to 6 hours and 1.20 to 2.00 USD per hour, each run lands around 4 to 12 USD. The GR00T N1.7 on SO-100 guide and the GR00T N1.5 on SO-100 guide list the exact defaults each one sends.
Latency and cost after the move
N1.7 is marginally faster per action step than N1.5 here, 152 ms against 165 ms, on the same GPU tier. That is real but small, and it does not change the class of task either model can do. The inference latency constraint is unchanged: the policy has to sit next to the servos for anything fast. Across the five trainable models the control loop runs from 20 ms to 485 ms per step, and public-internet round trips on top of a 152 ms loop turn a working policy into a hesitant one. Remote inference suits slow pick-and-place, not fast reactive motion.
| GPU tier | Models | Typical run | Spot price | Cost per run |
|---|---|---|---|---|
| A100 80 GB or H100 80 GB | GR00T N1.7, GR00T N1.5, Pi0.5 | 3 to 6 hours | 1.20 to 2.00 USD per hour | about 4 to 12 USD |
| RTX 4090 or any 24 GB card | SmolVLA, ACT | 2 to 5 hours | 0.30 to 0.60 USD per hour | about 1 to 3 USD |
Inference pods carry an idle watchdog and destroy themselves after an idle period, so a forgotten migration test does not keep billing. Full numbers are on the pricing page, and the training docs record what the form sends to the trainer.
The migration checklist
- Record the N1.5 baseline first: success rate on your task, over enough trials to mean something. Without it the migration has no verdict.
- Check
meta/info.jsonfor codebase_version v2.0 or v2.1, and convert down from v3 if needed. - Rewrite the data config as a modality config file: RELATIVE for the arm axes, ABSOLUTE for the gripper.
- Request access to nvidia/Cosmos-Reason2-2B and authenticate everywhere, including CI.
- Run the shipped demo_data/cube_to_bowl_5 fine-tune end to end before touching your own data.
- Retrain from
nvidia/GR00T-N1.7-3Bon the same dataset and episode count, with--use-percentilesset explicitly on both sides. - Compare on the arm, not on a benchmark, over enough trials to clear the 5 to 6 percent run-to-run variance. Then decommission n1d5.
If the retrained policy converges but the arm does nothing useful, that is a mapped failure rather than a migration problem. Loss falls, policy does nothing and policy only works in one setup are the two you will hit most. The CLI exposes the same operations if you would rather script the A/B than click it.

GR00T N1.5 to N1.7 is a backbone swap plus an action-space change, both moves the wider VLA field has been making. Pi0's flow-matching design reached a similar action head from another direction, and the wider VLA overview puts the family in order. If this migration is your entry point, start from the SO-100 setup guide.
Five policies, real numbers, no marketing
GR00T N1.7, GR00T N1.5, Pi0.5, SmolVLA and ACT compared on parameters, GPU tier, inference latency, minimum episodes and dataset format. The same table the trainer reads.
Compare the policiesCan I load a GR00T N1.5 checkpoint with the GR00T N1.7 code?▾
No. The N1.5 checkpoint declares architectures GR00T_N1_5 and model_type gr00t_n1_5; N1.7 declares Gr00tN1d7. N1.5's model class lived in gr00t/model/gr00t_n1.py, which no longer exists on main, and the packaged model tree (gr00t_n1d6, then gr00t_n1d7) only started with N1.6. LeRobot detects N1.5 checkpoints specifically so it can reject them rather than mis-load them, and tells you to pin lerobot==0.5.1 for the old path. There is no conversion script.
Do I have to re-record my dataset?▾
No. Both read the same GR00T flavour of LeRobot v2 with a meta/modality.json describing state, action and video keys, and that schema did not change. You rewrite the Python data config: N1.5 selected a registered class with --data-config, N1.7 wants a file passed to --modality-config-path that registers ModalityConfig objects. A v3.0 dataset must be converted down first with scripts/lerobot_conversion/convert_v3_to_v2.py, for either version.
Why does GR00T N1.7 fail with a 401 or GatedRepoError before training starts?▾
Because the VLM backbone nvidia/Cosmos-Reason2-2B is a gated Hugging Face repository and every GR00T N1.7 checkpoint loads it on first use, including the base nvidia/GR00T-N1.7-3B. Accept the license on the model page, then run huggingface-cli login or export HF_TOKEN. The error names the backbone rather than GR00T, which is why it reads as unrelated. N1.5 had no gated dependency.
Is GR00T N1.7 commercially usable when N1.5 was not?▾
The N1.5 card states the model is ready for non-commercial use and links the NVIDIA OneWay Noncommercial License. The N1.7 card states it is ready for commercial and non-commercial use and links the NVIDIA Open Model License; the repository puts code under Apache 2.0 and weights under the Open Model License. Read both yourself; this summarises the cards and is not legal advice.
Does GR00T N1.7 need more GPU than N1.5?▾
The published guidance moved up. The N1.5 README documented fine-tuning on H100, L40, RTX 4090 and A6000 with Python 3.10 and CUDA 12.4, plus a note to pass --no-tune_diffusion_model on a 4090 to avoid running out of memory, and it supported LoRA. The N1.7 README recommends 40 GB or more for fine-tuning and 16 GB or more for inference, on Python 3.12 and CUDA 12.8, with no LoRA path in its finetune config. On AY-Robots both run on the same A100 80 GB or H100 80 GB tier, so cost per run is unchanged at roughly 4 to 12 USD.
Should I stop at GR00T N1.6 instead?▾
There is little reason to. N1.6 is a frozen branch like N1.5, it still uses an Eagle backbone, and its config records action_horizon 50 with 128-dimensional state and action, so porting to it costs nearly as much as porting to N1.7 without the licensing or maintenance benefit. It is worth knowing for one reason: N1.6, not N1.7, is where state-relative action chunks were introduced. If you are doing the work anyway, land on the branch that still receives fixes.
Sources
- NVIDIA Isaac-GR00T repository README, N1.7 main branch (What's New, Key Changes from N1.6, install, hardware, training tips)
- Isaac-GR00T n1d5 branch, the GR00T N1.5 code path
- Isaac-GR00T n1d6 README, What's New in GR00T N1.6 (state-relative action chunks)
- Isaac-GR00T FinetuneConfig: the N1.7 fine-tuning defaults and required fields
- Isaac-GR00T n1d5 gr00t_finetune.py: the N1.5 fine-tuning flags, LoRA options and hardcoded seed=42
- Isaac-GR00T n1d5 data_config.py: So100DataConfig with crop 0.95, 224x224 resize and min_max normalization
- Isaac-GR00T N1.7 SO-100 modality config: RELATIVE arm joints, ABSOLUTE gripper
- Isaac-GR00T: Fine-tune on Custom Embodiments (NEW_EMBODIMENT), including the reference open-loop MSE curve
- Isaac-GR00T LIBERO benchmark results for GR00T N1.7
- Isaac-GR00T LIBERO benchmark results for GR00T N1.5 (n1d5 branch)
- nvidia/GR00T-N1.7-3B model card, license and config.json
- nvidia/GR00T-N1.6-3B config.json
- nvidia/GR00T-N1.5-3B model card, license and config.json
- nvidia/Cosmos-Reason2-2B, the gated Qwen3-VL based backbone used by GR00T N1.7
- LeRobot groot policy configuration: the N1.5 rejection guidance and legacy aliases
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started