GR00T Deployment & Inference Guide

July 7, 2026 · View on GitHub

Run inference with PyTorch or TensorRT acceleration for the GR00T N1.7 policy.


Prerequisites

  • Model checkpoint: nvidia/GR00T-N1.7-3B
  • Dataset in LeRobot format (e.g., demo_data/libero_demo)
  • CUDA-enabled GPU
  • Setup uv environment following README.md
PlatformInstallation
dGPU (H100, A100, RTX 4090/5090, L20, RTX Pro 5000/6000, etc.)uv sync — GPU deps (flash-attn, onnx, tensorrt) included
Jetson ThorJetson Thor Setup (Docker or bare metal)
DGX SparkDGX Spark Setup (Docker or bare metal)
Jetson OrinJetson Orin Setup (Docker or bare metal)
  • dGPU local environment: use the installation commands below, then use the PyTorch or TensorRT commands in this guide
  • Thor Docker or bare metal: skip to Jetson Thor Setup
  • Spark Docker or bare metal: skip to DGX Spark Setup
  • Orin Docker or bare metal: skip to Jetson Orin Setup

dGPU Installation

uv sync

GPU dependencies (flash-attn, onnx, tensorrt) are included in the default install.

Download Model and Dataset

Download the finetuned model to a local directory (HuggingFace does not support nested repo paths directly):

uv run hf download nvidia/GR00T-N1.7-LIBERO \
  --include "libero_10/config.json" "libero_10/embodiment_id.json" \
  "libero_10/model-*.safetensors" "libero_10/model.safetensors.index.json" \
  "libero_10/processor_config.json" "libero_10/statistics.json" \
  --local-dir checkpoints/GR00T-N1.7-LIBERO

For demo dataset setup, see the Data Format section in the main README.


Quick Start: PyTorch Inference

Run inference on demo trajectories using PyTorch (no TRT setup needed):

uv run python scripts/deployment/standalone_inference_script.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA \
  --traj-ids 0 1 2 3 4 \
  --inference-mode pytorch \
  --execution-horizon 8

TensorRT Acceleration

The trt_full_pipeline mode (passed via --inference-mode trt_full_pipeline in standalone_inference_script.py) accelerates all model components with TRT engines. Speedup varies by platform — see benchmark tables below for measured results on each device. The same pipeline is referred to as n17_full_pipeline inside the engine-loading and build scripts (trt_model_forward.py, build_trt_pipeline.py); the two names describe the same set of engines.

ComponentEngineNotes
ViTTRTQwen3-VL Vision (24 blocks, FP32 for accuracy)
LLMTRTQwen3-VL Text Model (16 layers, with deepstack injection)
VL Self-AttentionTRTSelfAttentionTransformer (4 layers, if present)
State EncoderTRTCategorySpecificMLP
Action EncoderTRTMultiEmbodimentActionEncoder
DiTTRTAlternateVLDiT (32 layers)
Action DecoderTRTCategorySpecificMLP

Lightweight ops remain in PyTorch: embed_tokens, masked_scatter, get_rope_index, VLLN.

TRT Export Modes

Export modeTRT componentsPyTorch componentsTypical use
dit_onlyDiT onlyBackbone, state encoder, action encoder, action decoderLegacy path and Orin
action_headState encoder, action encoder, DiT, action decoderBackboneIsolate action-head TRT accuracy/performance
full_pipelineBackbone and action headLightweight glue ops listed aboveRecommended fast path on dGPU, Thor, and Spark
DiT-only mode (legacy from N1.6)

The dit_only export mode (--export-mode dit_only) optimizes only the action head DiT, leaving the backbone in PyTorch. This was the default in N1.6. For N1.7, full_pipeline is recommended as it accelerates the backbone (ViT + LLM) which dominates inference time.

Build TRT Engines

The unified build_trt_pipeline.py script runs all steps (export ONNX → build engines → verify accuracy → benchmark) in a single command:

uv run python scripts/deployment/build_trt_pipeline.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA

Finetuned models: Replace --model-path with your checkpoint path. The pipeline is identical for base and finetuned models.

Note: Engine build takes ~2-5 minutes depending on GPU. Engines are GPU-architecture-specific and must be rebuilt for different GPUs.

Batch size: The --batch-size value is baked as a static dimension into the ONNX and TRT models. Engines built with one batch size cannot be used with a different batch size at runtime. If you need a different batch size, re-run the full pipeline (--steps export,build,verify) with the new --batch-size value.

ONNX exporter: The N1.7 TRT export path uses PyTorch's legacy ONNX exporter explicitly (dynamo=False) for all components. Keep this explicit in custom export code as well: the dynamo exporter can specialize dynamic sequence dimensions such as vl_seq_len, which breaks TensorRT runtime flexibility for different token lengths.

You can also run a subset of steps:

# Export + build only (skip verify and benchmark)
uv run python scripts/deployment/build_trt_pipeline.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA \
  --steps export,build
What each step does

The pipeline runs 4 steps in sequence:

  1. Export to ONNX (export) — Exports all model components (LLM, VL Self-Attention, State Encoder, Action Encoder, DiT, Action Decoder) to ONNX format under <output-dir>/onnx/.
  2. Build TensorRT Engines (build) — Compiles each ONNX model into a GPU-specific TensorRT engine under <output-dir>/engines/.
  3. Verify Accuracy (verify) — Runs PyTorch vs TRT output comparison. Expected: Cosine Similarity: 0.999+ (PASS).
  4. Benchmark (benchmark) — Measures E2E latency for PyTorch Eager, torch.compile, and TRT modes.

Each step can be run individually via --steps <step>. Verbose logs are written to <output-dir>/pipeline.log.


Performance

Benchmark Results

GR00T N1.7 Inference Timing (4 denoising steps, 1 camera):

DeviceModeData ProcessingBackboneAction HeadE2EFrequencyE2E Speedup
dGPU
H100 80GB HBM3PyTorch Eager6.2 ms31.3 ms48.2 ms85.8 ms11.7 Hz1.00x
torch.compile6.2 ms30.4 ms12.0 ms48.6 ms20.6 Hz1.77x
TensorRT (Full Pipeline)6.2 ms8.8 ms12.3 ms27.9 ms35.9 Hz3.08x
H20 96GB HBM3PyTorch Eager5.33 ms30.8 ms47.3 ms83.4 ms12.0 Hz1.00x
torch.compile5.33 ms31.1 ms13.3 ms49.7 ms20.1 Hz1.68x
TensorRT (Full Pipeline)5.33 ms14.2 ms14.5 ms34.0 ms29.4 Hz2.45x
RTX Pro 6000 BlackwellPyTorch Eager4.8 ms29.3 ms44.0 ms78.4 ms12.8 Hz1.00x
torch.compile4.8 ms29.4 ms16.5 ms50.7 ms19.7 Hz1.55x
TensorRT (Full Pipeline)4.8 ms9.9 ms13.2 ms27.9 ms35.9 Hz2.81x
RTX Pro 5000 72GBPyTorch Eager8.85 ms54.01 ms63.19 ms126.4 ms7.9 Hz1.00x
torch.compile8.85 ms55.74 ms20.38 ms84.9 ms11.8 Hz1.49x
TensorRT (Full Pipeline)8.85 ms14.37 ms17.33 ms40.5 ms24.7 Hz3.13x
L40PyTorch Eager6.6 ms42.8 ms78.9 ms128.3 ms7.8 Hz1.00x
torch.compile6.6 ms42.7 ms19.8 ms69.0 ms14.5 Hz1.86x
TensorRT (Full Pipeline)6.6 ms13.1 ms18.8 ms38.4 ms26.0 Hz3.34x
L20PyTorch Eager5.7 ms47.58 ms86.92 ms140.3 ms7.1 Hz1.00x
torch.compile5.7 ms47.2 ms20.18 ms73.1 ms13.7 Hz1.92x
TensorRT (Full Pipeline)5.7 ms17.27 ms19.79 ms42.8 ms23.3 Hz3.28x
Jetson / Spark
DGX SparkPyTorch Eager13.14 ms38.22 ms74.94 ms126.4 ms7.9 Hz1.00x
torch.compile13.14 ms39.23 ms56.49 ms108.8 ms9.2 Hz1.16x
TensorRT (Full Pipeline)13.14 ms33.43 ms52.37 ms98.6 ms10.1 Hz1.28x
AGX ThorPyTorch Eager8.21 ms55.26 ms81.65 ms144.9 ms6.9 Hz1.00x
torch.compile8.21 ms55.59 ms64.66 ms128.4 ms7.8 Hz1.13x
TensorRT (Full Pipeline)8.21 ms28.89 ms56.64 ms93.8 ms10.7 Hz1.54x
OrinPyTorch Eager9.45 ms127.6 ms205.39 ms342.8 ms2.9 Hz1.00x
torch.compile9.45 ms128.59 ms78.94 ms217.0 ms4.6 Hz1.58x
TensorRT (DiT-only)9.45 ms128.38 ms78.6 ms216.5 ms4.6 Hz1.58x

Note: Orin uses DiT-only TensorRT (--inference-mode tensorrt) because TRT 10.3 does not support the backbone engine. All other platforms use the full pipeline (--inference-mode trt_full_pipeline).

Raw benchmark output (H100 80GB HBM3)
Hardware: NVIDIA H100 80GB HBM3
Model: checkpoints/GR00T-N1.7-LIBERO/libero_10
1 camera, Denoising Steps: 4

PyTorch Eager:
  E2E:             85.8 ms (11.7 Hz)
  Data Processing: 6.2 ms | Backbone: 31.3 ms | Action Head: 48.2 ms

torch.compile:
  E2E:             48.6 ms (20.6 Hz), 1.77x speedup
  Data Processing: 6.2 ms | Backbone: 30.4 ms | Action Head: 12.0 ms

TensorRT (Full Pipeline):
  E2E:             27.9 ms (35.9 Hz), 3.08x speedup
  Data Processing: 6.2 ms | Backbone: 8.8 ms  | Action Head: 12.3 ms

Standalone Inference with TRT

The standalone inference script serves as both an accuracy validation and a reference for deploying TRT inference in your own code. It runs per-step inference on real trajectories and compares action predictions:

uv run python scripts/deployment/standalone_inference_script.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA \
  --traj-ids 0 1 2 3 4 \
  --inference-mode trt_full_pipeline \
  --trt-engine-path ./gr00t_trt_deployment/engines \
  --save-plot-path ./output/trt_inference.png

Expected accuracy: MSE/MAE match PyTorch within noise. TRT produces identical action quality. Speedup varies by platform — run build_trt_pipeline.py --steps benchmark on your hardware for exact numbers.

Optional: LIBERO Closed-Loop Sim Evaluation

To validate TRT accuracy in end-to-end robotic tasks, run the LIBERO closed-loop evaluation. This requires a separate environment setup (~10-30 min, MuJoCo simulator + dependencies).

Setup, commands, and results (H100, 20 episodes)

Task: KITCHEN_SCENE3_turn_on_the_stove_and_put_the_moka_pot_on_it, 20 episodes:

ModeSuccess Rate
PyTorch100% (20/20)
TRT (n17_full_pipeline)95% (19/20)

Difference is within simulation noise (p >> 0.05).

Note: Use --n-envs 1 for TRT evaluation (ViT engine has static shapes for single-observation inference).

# One-time LIBERO setup (~10 min)
bash gr00t/eval/sim/LIBERO/setup_libero.sh

# Activate LIBERO venv and install additional deps
source gr00t/eval/sim/LIBERO/libero_uv/.venv/bin/activate
uv pip install diffusers transformers accelerate safetensors torchcodec

# TRT full pipeline evaluation
python gr00t/eval/rollout_policy.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --env-name "libero_sim/KITCHEN_SCENE3_turn_on_the_stove_and_put_the_moka_pot_on_it" \
  --n-episodes 20 --n-envs 1 --max-episode-steps 504 \
  --trt-engine-path ./gr00t_trt_deployment/engines \
  --trt-mode n17_full_pipeline

Run python scripts/deployment/build_trt_pipeline.py --steps benchmark to generate benchmarks for your hardware.


Platform-Specific Setup

Jetson and Spark platforms use different dependency stacks than dGPU. Thor and Spark use CUDA 13 with PyTorch 2.10.0 from the Jetson AI Lab cu130 index. Orin uses CUDA 12.6 with PyTorch 2.10.0 from the Jetson AI Lab cu126 index.

⚠️ aarch64 users (Spark / Thor / Orin): After running install_deps.sh, always activate the venv with source .venv/bin/activate && source scripts/activate_<platform>.sh (activate_spark.sh, activate_thor.sh, or activate_orin.sh) and run the example commands with plain python / torchrun, not uv run python / uv run torchrun — the latter re-syncs against the root pyproject.toml (x86_64 Python 3.12) and destroys the platform-specific environment. This applies to every platform below; see also the aarch64 note in the main README.

Shared Docker Workflow

The Docker steps below are identical across Thor, Spark, and Orin except the image tag (gr00t-thor, gr00t-spark, or gr00t-orin). Each platform section builds its image, then reuses these steps:

  1. Download the model once on the host — see Download Model and Dataset.
  2. Start an interactive session (replace <profile> with thor, spark, or orin):
docker run -it --rm --runtime nvidia --gpus all \
  --ipc=host \
  --ulimit memlock=-1 \
  --ulimit stack=67108864 \
  --network host \
  -v "$(pwd)":/workspace/repo \
  -v "${HF_HOME:-${HOME}/.cache/huggingface}":/root/.cache/huggingface \
  -w /workspace/repo \
  -e HF_TOKEN="${HF_TOKEN:-}" \
  gr00t-<profile> \
  bash

Then run the platform's TRT pipeline command inside the container (shown per platform below).

Jetson Thor Setup

Thor uses CUDA 13 and Python 3.12, which require a different dependency stack than x86 or Orin. Tested with JetPack 7.1. There are two ways to run on Thor: Docker (recommended) or bare metal.

Docker (Recommended)

Build the Thor container from the repo root:

cd docker && bash build.sh --profile=thor && cd ..

Then follow the Shared Docker Workflow (image gr00t-thor) to download the model and start the container. Inside the container, run the full TRT pipeline (export, build, verify, benchmark):

python scripts/deployment/build_trt_pipeline.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA
Bare Metal
# One-time install (temporarily copies the Thor pyproject.toml and uv.lock to repo root,
# installs NVPL libs, uv, Python deps, and builds torchcodec from source against the
# system FFmpeg runtime)
bash scripts/deployment/thor/install_deps.sh

# In each new shell
source .venv/bin/activate
source scripts/activate_thor.sh

Then run the TRT pipeline or PyTorch inference as shown in the TensorRT Acceleration and Quick Start sections above. The activation script exports the PyTorch and CUDA library/include paths that torchcodec and torch.compile need on Thor.


DGX Spark Setup

Spark uses CUDA 13 and Python 3.12 like Thor, but requires a dedicated dependency stack and source-built flash-attn for sm121. There are two ways to run on Spark: Docker (recommended) or bare metal.

Docker (Recommended)

Build the Spark container from the repo root:

cd docker && bash build.sh --profile=spark && cd ..

Then follow the Shared Docker Workflow (image gr00t-spark) to download the model and start the container. Inside the container, run the full TRT pipeline (export, build, verify, benchmark):

python scripts/deployment/build_trt_pipeline.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA
Bare Metal
# One-time install (temporarily copies the Spark pyproject.toml and uv.lock to repo root,
# installs NVPL libs, uv, Python deps, source-builds flash-attn for sm121, and builds
# torchcodec from source against the system FFmpeg runtime)
bash scripts/deployment/spark/install_deps.sh

# In each new shell
source .venv/bin/activate
source scripts/activate_spark.sh

Then run the TRT pipeline or PyTorch inference as shown in the TensorRT Acceleration and Quick Start sections above. If you later rerun uv sync, rerun bash scripts/deployment/spark/install_deps.sh so the Spark-specific flash-attn build is restored and revalidated.


Jetson Orin Setup

Note: On Orin, only the DiT (action head) TRT export is currently supported. Use --export-mode dit_only instead of full_pipeline. Full pipeline support is in progress.

Orin uses CUDA 12.6 and Python 3.10 (JetPack 6.2), which require a different dependency stack than x86 or Thor. Tested with JetPack 6.2. There are two ways to run on Orin: Docker (recommended) or bare metal.

Docker (Recommended)

Build the Orin container from the repo root:

cd docker && bash build.sh --profile=orin && cd ..

Then follow the Shared Docker Workflow (image gr00t-orin) to download the model and start the container. Inside the container, run the TRT pipeline (DiT-only on Orin):

python scripts/deployment/build_trt_pipeline.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA \
  --export-mode dit_only
Bare Metal
# One-time install (temporarily copies the Orin pyproject.toml and uv.lock to repo root,
# installs uv, Python deps, and builds torchcodec from source against JetPack's FFmpeg
# runtime)
bash scripts/deployment/orin/install_deps.sh

# In each new shell
source .venv/bin/activate
source scripts/activate_orin.sh

Then run the TRT pipeline (with --export-mode dit_only) or PyTorch inference as shown in the TensorRT Acceleration and Quick Start sections above. The activation script exports the PyTorch and CUDA library/include paths that torchcodec and torch.compile need on Orin.

Orin storage tip: If your eMMC root is low on space, redirect the HuggingFace cache to an NVMe SSD with export HF_HOME=/path/to/ssd/.cache/huggingface before downloading models.

Orin TRT limitations: TRT 10.3 on Orin does not support the backbone (LLM) engine. Use --export-mode dit_only for the unified pipeline and --inference-mode tensorrt (DiT-only TRT, backbone runs in PyTorch) for inference:

python scripts/deployment/build_trt_pipeline.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA \
  --export-mode dit_only

python scripts/deployment/standalone_inference_script.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA \
  --traj-ids 0 \
  --inference-mode tensorrt \
  --trt-engine-path ./gr00t_trt_deployment/engines

Command-Line Arguments

build_trt_pipeline.py

ArgumentDefaultDescription
--model-path(required)Path to model checkpoint
--dataset-pathdemo_data/libero_demoPath to dataset (LeRobot format)
--embodiment-tagAuto-detectedEmbodiment tag (auto-detected from processor_config.json if single embodiment)
--output-dir./gr00t_trt_deploymentRoot output directory. ONNX → <output-dir>/onnx/, engines → <output-dir>/engines/
--precisionbf16Precision for ONNX export and TRT engine build (bf16 only)
--batch-size1Batch size baked into exported ONNX/TRT models (static — see note below)
--export-modefull_pipelineExport mode: dit_only, action_head, or full_pipeline
--workspace8192TRT builder workspace size in MB
--num-iterations20Number of benchmark iterations
--warmup5Number of warmup iterations
--skip-compilefalseSkip torch.compile benchmark
--stepsallSteps to run: all or comma-separated subset of export,build,verify,benchmark
--log-file<output-dir>/pipeline.logLog file path

standalone_inference_script.py

ArgumentDefaultDescription
--model-path(required)Path to model checkpoint
--dataset-pathdemo_data/droid_samplePath to dataset (LeRobot format)
--embodiment-tagOXE_DROID_RELATIVE_EEF_RELATIVE_JOINTRobot embodiment tag
--traj-ids[0]Episode indices to evaluate (space-separated)
--steps200Max steps per trajectory (capped by actual length)
--execution-horizon16Steps of each predicted chunk to execute per inference (old --action-horizon deprecated)
--inference-modepytorchpytorch, tensorrt (DiT-only TRT), or trt_full_pipeline (all engines)
--trt-engine-path./gr00t_trt_deployment/enginesDirectory containing pre-built TRT engines (matches build_trt_pipeline.py output)
--denoising-steps4Diffusion denoising iterations
--save-plot-pathNoneSave per-trajectory GT-vs-predicted comparison plots
--skip-timing-steps1Initial steps excluded from timing stats (warmup)
--host / --port127.0.0.1 / 5555Server address (when using client mode without --model-path)
--seed42Random seed for reproducibility

Files

FileDescription
build_trt_pipeline.pyUnified pipeline: export ONNX, build engines, verify, benchmark
standalone_inference_script.pyMain inference script (PyTorch + DiT-only TensorRT)
trt_torch.pyTRT Engine wrapper class (load, bind, execute)
trt_model_forward.pyTRT forward functions and setup (backbone + action head)

Troubleshooting

Engine Build Fails

  • Ensure you have enough GPU memory (16GB+ recommended for full pipeline)
  • Try reducing workspace size: --workspace 4096
  • Ensure TensorRT version matches your CUDA version
  • LLM engine requires batch_size dimension handling when using custom shape profiles

ONNX Export Issues

  • If export fails with COMPLEX128 error: ensure _simple_causal_mask is used (not HuggingFace's create_causal_mask)
  • If masked_scatter size assertion fails: ensure visual_pos_masks has the correct number of True values matching deepstack tensor size
  • Check that the dataset path is valid and contains at least one trajectory

Accuracy Issues

  • If cosine < 0.99: check that LLM export does NOT include the final RMSNorm (backbone returns pre-norm hidden_states[-1])
  • If output magnitude is ~12x too small: this is the norm bug — see above
  • Run build_trt_pipeline.py --steps verify --export-mode action_head first to isolate backbone vs action head drift