
How one model drives many robots: embodiment tags, shared action spaces, per-robot heads, and honest numbers on what actually transfers between arms and what does not.
What you need to know
- •One set of weights drives robots with different joints, cameras, grippers and control rates.
- •Every system solves three mismatches: observation spaces, action spaces, control frequencies. They differ only in where the seam between shared trunk and per-robot head sits.
- •RT-X standardises every robot into one 7-DoF end-effector command. Octo swaps a lightweight head. CrossFormer keeps 4 heads for 4 embodiment classes. GR00T N1.7 selects an MLP per embodiment tag.
- •Transfer is real but uneven: Open X-Embodiment reports RT-1-X beating per-dataset baselines by 50 percent in the small-data domain, yet not beating the specialist where data is plentiful.
- •For one SO-100 owner the payoff is that someone else paid for the pretraining, so your 50 episodes only teach the action path what your arm is.
- •On AY-Robots five policies run through one form: GR00T N1.7, GR00T N1.5, Pi0.5, SmolVLA and ACT, 30 to 50 episodes minimum, roughly 1 to 12 USD per run.
What cross-embodiment learning actually is
A policy trained on one robot is usually useless on another. Change the link lengths, swap the gripper, move the wrist camera two centimetres, and the mapping from pixels to joint targets no longer holds. Cross-embodiment learning trains one policy on data from many robots at once, so whatever is shared is learned once and only the robot-specific part is relearned.
The evidence is the Open X-Embodiment collaboration, which pooled 60 robot datasets from 34 labs into one format. The paper reports 22 robots across 21 institutions, 527 skills and 160266 tasks; the project page puts the pool above one million real trajectories.
Re-checked against upstream on 2026-08-24. GR00T details come from the main branch of NVIDIA/Isaac-GR00T, not a tagged release, so flag names can drift: run --help before copying a command. Open X-Embodiment numbers are from arXiv 2310.08864 v9, revised 14 May 2025.
The three mismatches every system has to solve
Strip away the branding and every cross-embodiment architecture answers the same three questions. Keep them separate: a design can be clever about one and naive about the others.
| Mismatch | What varies | Typical fix |
|---|---|---|
| Observation space | Camera count, mounting, image size, whether proprioception exists | Tokenise each stream, then mask the ones a robot does not have |
| Action space | Joint count and order, units, absolute vs relative, end-effector pose vs joint targets | One canonical space, or pad to fixed width and give each embodiment its own head |
| Control frequency | CrossFormer executes navigation at 4 Hz, bimanual arms and quadrupeds at 20 Hz, single arms at 5 to 15 Hz | Predict a chunk of future actions, sized per embodiment |
| Dynamics and calibration | Servo backlash, gravity sag, gripper force, zero offsets | Not solved by architecture. This needs your own data |
The fourth row gets skipped in papers and eats a weekend in practice. Two SO-100 arms from the same kit, given the same calibration, still disagree by a few degrees per joint. A model that generalises across a Franka and a WidowX can still fail because your shoulder sags under load. See policy only works in one setup.
Four architectures, four places to put the seam
RT-X: standardise the action space up front
RT-X is blunt. Each dataset's actions are converted into the same 7-DoF end effector command (x, y, z, roll, pitch, yaw, gripper opening, or their rates), normalised per dataset, then tokenised into 256 bins along each of eight dimensions: those seven plus one for episode termination. What the paper does not do is align coordinate frames across datasets, and it lets values mean either absolute or relative positions or velocities, whichever the original robot used, so the same action vector can induce very different motions on two robots. The cost is coverage: the mixture used across all RT-X experiments is 9 manipulators from 12 datasets, not the full 22-embodiment pool.
Octo: readout tokens and a swappable head
Octo is a transformer trained on 800k Open X-Embodiment trajectories. Task, observation and learned readout tokens enter a block-wise masked transformer where a readout token attends to earlier observations and tasks but is never attended to in return, and a diffusion head turns readout embeddings into action chunks. Because nothing depends on the head, you can replace it: the paper states that pretrained transformer weights are wholly retained.
Octo ships as Octo-Small at 27M parameters and Octo-Base at 93M. Each reported fine-tuning setup uses around 100 in-domain demonstrations and finishes in under 5 hours on one NVIDIA A5000, including cases with a new observation input and a new action space. Both sit in the model arena as octo-base and octo-small.
CrossFormer: one head per embodiment class
CrossFormer drops the requirement that action spaces be aligned at all. Trained on 900K trajectories across 20 embodiments at 130M parameters, it controls single and dual arm manipulators, wheeled navigation robots, quadcopters and quadrupeds with the same weights. Images go through ResNet-26 encoders, proprioception is projected directly, and missing observation types are masked so every batch element keeps all token groups at fixed positions.
| CrossFormer action head | Dimensions | Chunk length | Executed at |
|---|---|---|---|
| Single-arm Cartesian (relative) | 7 | 4 | 5 to 15 Hz |
| Navigation waypoints | 2 | 4 | 4 Hz |
| Bimanual joint positions | 14 | 100 | 20 Hz |
| Quadruped joint positions | 12 | 1 | 20 Hz |
It is tempting to read the chunk lengths as a control-rate adapter, and the bimanual row invites it: 100 steps at 20 Hz is five seconds of committed motion. The quadruped row kills that story, since it also runs at 20 Hz and predicts one action. The paper says chunk sizes are taken from prior work in each setting, not derived. What is true is that action chunking is what lets one trunk serve different rates. CrossFormer's entry is at crossformer.
HPT: stems, trunk, heads
Heterogeneous Pre-trained Transformers name the parts. Embodiment-specific stems tokenise proprioception and vision into a fixed token count, a shared trunk processes them, and heads emit actions; exactly one stem and head pair is active per embodiment. The scaling study runs to 52 datasets and reports over 20 percent improvement on unseen tasks. Checkpoints run from hpt-small to hpt-xlarge.

Embodiment tags in practice: how GR00T N1.7 does it
An embodiment tag is what the idea looks like as a CLI flag on a production vision-language-action model. In GR00T N1.7, every command takes --embodiment-tag, which picks the modality config: which state and action keys exist, how they are normalised, which projector runs. The model card describes proprioception as an MLP indexed by embodiment ID with inputs padded to a configurable maximum, and actions decoded by an MLP, one per unique embodiment.
# gr00t/data/embodiment_tags.py (Isaac-GR00T main, N1.7)
class EmbodimentTag(Enum):
# Pretrain tags: baked into nvidia/GR00T-N1.7-3B, ready for zero-shot
OXE_DROID_RELATIVE_EEF_RELATIVE_JOINT = "oxe_droid_relative_eef_relative_joint"
XDOF = "xdof_relative_eef_relative_joint"
XDOF_SUBTASK = "xdof_relative_eef_relative_joint_subtask"
REAL_G1 = "real_g1_relative_eef_relative_joints"
REAL_R1_PRO_SHARPA = "real_r1_pro_sharpa_relative_eef"
# ... plus _HUMAN / _MAXINSIGHTS / _MECKA variants of R1 Pro Sharpa
# Pre-registered posttrain tags: require a finetuned checkpoint
UNITREE_G1 = "unitree_g1_full_body_with_waist_height_nav_cmd"
UNITREE_G1_SONIC = "unitree_g1_sonic"
SIMPLER_ENV_GOOGLE = "simpler_env_google"
SIMPLER_ENV_WIDOWX = "simpler_env_widowx"
LIBERO_PANDA = "libero_sim"
# Finetune-only tags, in no shipped checkpoint. The first is the one you will use.
NEW_EMBODIMENT = "new_embodiment"
ROBOCASA_GR1_TABLETOP = "robocasa_gr1_tabletop"
ROBOCASA_PANDA_OMRON = "robocasa_panda_omron"The pretrain tags are DROID, a generic X-DOF description (X being a variable number of degrees of freedom), a Unitree G1 humanoid and R1 Pro variants. There is no SO-100 tag. Your SO-100, Koch v1.1 and LeKiwi all land in the same bucket: NEW_EMBODIMENT.
The source lists the finetune-only tags as tags for custom robots, in no shipped checkpoint, and the policy guide's dataset table says the repo's own SO-100 demo set only works with a finetuned checkpoint, not the base model. NEW_EMBODIMENT is a fine-tuning tag, not an inference tag. Same for Pi0.5, where lerobot/pi05_base is a starting point, and ACT has no base model at all.
Telling the model what your action vector means
Two files do the work. The dataset carries a meta/modality.json slicing the flat state and action arrays into named fields, and a Python modality config registers those fields under EmbodimentTag.NEW_EMBODIMENT. For the SO-100 example that ships with the repo, the whole robot is six numbers.
{
"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/so100_config.py (abridged, comments are upstream)
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)), # predict 16 future steps
modality_keys=["single_arm", "gripper"],
action_configs=[
# single_arm: RELATIVE = delta from current state (better generalization)
ActionConfig(rep=ActionRepresentation.RELATIVE,
type=ActionType.NON_EEF, # joint-space, not end-effector
format=ActionFormat.DEFAULT),
# gripper: ABSOLUTE = target position (binary open/close works better absolute)
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 Isaac-GR00T README says N1.7 adopts a relative end-effector action space shared across robot and human embodiments, and calls that a key factor in its cross-embodiment performance. The shipped SO-100 config does not use it: both action entries are NON_EEF, so the arm runs in relative joint space and its freshly created head learns its own mapping instead of reusing the shared one. A real limit on transfer, visible in a config file rather than a paper.
Shared action spaces: standardise, pad, or both
| Model | Strategy | Concrete detail | Where it breaks |
|---|---|---|---|
| RT-1-X / RT-2-X | Standardise | One 7-DoF end-effector command, 256 bins per dimension | Robots that cannot be cast to that command stay out of the mixture |
| Pi0 / Pi0.5 | Pad | action_dim defaults to 32 in openpi's Pi0Config; smaller robots are zero-padded | Padding convention must match at training and serving |
| Octo | Swap the head | Pretrained trunk kept; new head plus positional embeddings per target | The new head starts from scratch, so it needs target-domain data |
| CrossFormer | Group into classes | 4 heads: single-arm, navigation, bimanual, quadruped | A robot that fits no class needs a fifth head and a retrain |
| GR00T N1.7 | Tag plus per-embodiment MLP | --embodiment-tag selects the projector; proprioception padded to a max | NEW_EMBODIMENT gets no pretrained head, so zero-shot is out |
The padding number bites. In openpi, Pi0Config.action_dim defaults to 32 and action_horizon to 50, for Pi0 and Pi0.5 alike. A six-channel SO-100 vector, five arm joints plus the gripper, fills 6 of 32 slots; the other 26 are zeros the model still predicts. Normalisation statistics must therefore be computed with the padding you serve with, which is how you get loss falls, policy does nothing.
What the dataset format does and does not carry
Cross-embodiment training needs a container that holds data from different robots without lying about it. The LeRobot dataset format is the de facto standard. In v3.0: meta/info.json for schema, FPS and path templates, meta/stats.json for normalisation statistics, meta/tasks.jsonl for language annotations, meta/episodes/ for per-episode records, plus shards holding many episodes each.
Here is the honest bit. robot_type does exist in the LeRobot info schema, but in the source it sits under a comment reading # Optional metadata and is typed str | None = None. No trainer keys off it. To learn what your action vector means, GR00T reads modality.json and the modality config you passed.
The request to make MultiLeRobotDataset accept datasets with different schemas is issue #542, opened 3 December 2024 and closed as not planned in October 2025. To pool a Koch dataset and an SO-101 dataset into one run today you write the collator yourself. A v3.0 dataset also crashes the GR00T loader and has to be converted down to v2.1: dataset rejected as v3.

The manual path: fine-tuning GR00T N1.7 on a new embodiment
This is the sequence NVIDIA documents for a custom arm, against the main branch of Isaac-GR00T. The repo ships demo_data/cube_to_bowl_5, five real SO-100 episodes that already carry a modality.json, so you can run the whole thing before you own an arm.
- 1Convert your dataset to the v2 flavour GR00T expects
GR00T reads a GR00T-flavoured LeRobot v2 dataset. Anything from a current lerobot is v3.0 and must be converted down. The converter lives in its own environment because it still needs a lerobot that can read v3.0. Skip this if you use the shipped demo data.
bashcd scripts/lerobot_conversion uv venv source .venv/bin/activate uv pip install -e . --verbose python convert_v3_to_v2.py --repo-id <YOUR_DATASET_REPO_ID> - 2Put a modality.json in the dataset
This file tells the model which slice of the flat action vector is the arm and which is the gripper. Without it the projector does not know what it is predicting. For a standard SO-100 or SO-101 recording the shipped example is already correct.
bashcp examples/SO100/modality.json <YOUR_DATASET_ROOT>/meta/modality.json - 3Register the modality config under NEW_EMBODIMENT
Only one NEW_EMBODIMENT modality config may be registered per Python process, so do not import two into the same script. In CLI use the file passed to --modality-config-path is the only one imported.
pythonregister_modality_config(so100_config, embodiment_tag=EmbodimentTag.NEW_EMBODIMENT) - 4Launch the fine-tune
A tyro CLI; run --help first, because the flag set changes between releases. Note that --global-batch-size is summed across GPUs before gradient accumulation, not after. --save-steps is lowered to 500 so you get intermediate checkpoints.
bashCUDA_VISIBLE_DEVICES=0 uv run python \ gr00t/experiment/launch_finetune.py \ --base-model-path nvidia/GR00T-N1.7-3B \ --dataset-path ./demo_data/cube_to_bowl_5 \ --embodiment-tag NEW_EMBODIMENT \ --modality-config-path examples/SO100/so100_config.py \ --num-gpus 1 \ --output-dir /tmp/so100 \ --save-total-limit 5 \ --save-steps 500 \ --max-steps 2000 \ --global-batch-size 32 \ --dataloader-num-workers 4 - 5Check that the fine-tune learned something
Open-loop evaluation replays a training trajectory and overlays predicted against ground-truth actions. NVIDIA publishes no target MSE, because a fixed number would not transfer between datasets. Look for the trend across checkpoints and a curve that tracks the ground-truth shape rather than sitting flat.
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/checkpoint-2000 \ --traj-ids 0 \ --execution-horizon 16 \ --steps 400 \ --modality-keys single_arm gripper - 6Serve it and close the loop
Policy server and robot client are separate processes talking over ZMQ. With no trained model yet, start the server with --dataset-path and no --model-path: it replays recorded actions so you can verify wiring first. That replay path also requires --execution-horizon, and the server raises a ValueError without it.
bashuv run python gr00t/eval/run_gr00t_server.py \ --embodiment-tag NEW_EMBODIMENT \ --model-path /tmp/so100/checkpoint-2000 \ --device cuda:0 --host 0.0.0.0 --port 5555
NVIDIA's own run of that 2000-step command on one H100, evaluated on training trajectory 0, gave an average MSE of 87.5 at checkpoint 500, then 25.4, 13.2 and 10.0 at 1000, 1500 and 2000, with MAE falling from 5.63 to 1.76. Those absolute values are not a target. The shape is the signal.
FinetuneConfig has fields for batch size, learning rate, warmup ratio, weight decay, save cadence and state dropout, and no seed. NVIDIA's own training tips note 5 to 6 percent variance between runs from non-deterministic image augmentations, so do not call one GR00T checkpoint better than another on a single run each. lerobot exposes a seed and defaults it to 1000, so SmolVLA and ACT runs can be pinned.
What actually gets updated during a fine-tune
The default tuning fields in the Isaac-GR00T fine-tune config are the clearest statement of where the seam sits in this model.
| Field | Default | Meaning |
|---|---|---|
| tune_llm | False | The language backbone stays frozen |
| tune_visual | False | The visual encoder stays frozen |
| tune_projector | True | The multimodal projector layers do train |
| tune_diffusion_model | True | The diffusion-based action decoder does train |
| state_dropout_prob | 0.2 | Randomly drops state inputs so the policy does not become a state copier |
Frozen perception, trained action path. The part that understands scenes is shared and untouched; the part that talks to your servos is what your fine-tuning run pays for. The AY-Robots catalog puts the trainable slice of GR00T N1.7 at roughly 40 M parameters out of about 3 B, which is the same story from the other end.
Two different defaults exist for the same quantity: the model config default is 0.8, the fine-tune CLI default is 0.2. NVIDIA's benchmark scripts then override it per suite, with LIBERO 10-Long at 0.2, SimplerEnv Bridge at 0.8 and SimplerEnv Fractal at 0.5. High state dropout forces the policy to look at the cameras instead of copying the current joint state.
Two ways to get there
Clone Isaac-GR00T, build the environment for your platform (dGPU on CUDA 12.8 with Python 3.12), rent or own an 80 GB card, run the six steps above. Expect environment failures rather than model failures.
- Install the
uvenvironment and CUDA paths; on CUDA 13 platforms runscripts/patch_triton_cuda13.shfirst. - Request access to the gated
nvidia/Cosmos-Reason2-2Bbackbone, which every GR00T checkpoint loads on first use. - Convert with
convert_v3_to_v2.pyif the dataset came from a current lerobot. - Write
meta/modality.jsonand a modality config registered underNEW_EMBODIMENT. - Train with
launch_finetune.py, verify withopen_loop_eval.pyacross checkpoints. - Serve with
run_gr00t_server.py, client next to the servos.
- Every flag is yours, including the ones no wrapper exposes
- You can mix in your own datasets, augmentations and eval harness
- Nothing is hidden, so when it breaks you can read the code
- The environment is the hard part, not the training
- You provision and destroy the GPU yourself, and forgetting is expensive
- Dataset version mismatches surface as opaque loader crashes
- No seed on the GR00T CLI, so comparing runs needs repeats
The training form picks a model, a dataset and hyperparameters; the backend rents a spot GPU sized by required VRAM and writes checkpoints to object storage. The embodiment side is preconfigured per arm, with a guide for each model and arm pair, for example GR00T N1.7 on SO-100 and SmolVLA on SO-101. Datasets come from the public directory, a Hugging Face repo id, or the desktop client.
| Policy | Min episodes | GPU tier | Dataset format | Latency per action step |
|---|---|---|---|---|
| GR00T N1.7 | 50 | A100 80 GB or H100 80 GB | LeRobot v2.0 or v2.1 | 152 ms |
| GR00T N1.5 | 50 | A100 80 GB or H100 80 GB | LeRobot v2.0 or v2.1 | 165 ms |
| Pi0.5 | 50 | A100 80 GB or H100 80 GB | LeRobot v3.0 | 485 ms |
| SmolVLA | 30 | RTX 4090 or any 24 GB card | LeRobot v3.0 | 245 ms |
| ACT | 50 | RTX 4090 or any 24 GB card | LeRobot v3.0 | 20 ms |
The A100 or H100 tier takes 3 to 6 hours at 1.20 to 2.00 USD per hour, so roughly 4 to 12 USD; the 24 GB tier takes 2 to 5 hours at 0.30 to 0.60 USD per hour, so roughly 1 to 3 USD. For inference, /api/inference/pod auto-provisions a pod with an idle watchdog that destroys itself. See pricing.
- No CUDA environment to build and no dataset conversion to hand-run
- Spot GPU rented and released around the run
- Same operations from the CLI and from AI agents via the MCP server
- Idle watchdog on inference pods, so a forgotten pod stops billing
- Only the five catalog policies, so no OpenVLA or Octo training here
- GR00T and Pi0.5 are cloud only; SmolVLA and ACT also run locally
- You get the exposed hyperparameters, not every upstream flag
- Remote inference adds internet round trips, fine for slow pick-and-place and not for fast reactive motion

What actually transfers, and what does not
| Result | Source | What it says |
|---|---|---|
| RT-1-X beats per-dataset baselines by 50 percent in the small-data domain | Open X-Embodiment project page | Pretraining is a large win when your dataset is small. That is your case. |
| RT-1-X does not beat the embodiment-specific RT-1 baseline in large-data domains | Open X-Embodiment, Table I | Attributed to underfitting. More data needs more capacity, not just more diversity. |
| RT-2-X outperforms RT-2 by 3x on emergent skill evaluations | Open X-Embodiment project page | Skills in one robot's data showed up on another. Transfer in the strong sense. |
| HPT improves fine-tuned performance by over 20 percent on unseen tasks | HPT, 52 datasets | Shared trunk plus per-embodiment stems and heads beats the same architecture from scratch. |
| Octo adapts to new observation and action spaces with ~100 demos in under 5 hours on one A5000 | Octo | Adaptation costs hours and dozens of demos, not weeks. |
| CrossFormer matches specialist policies across 20 embodiments | CrossFormer | Parity, not dominance, but one set of weights covers arms, wheels, rotors and legs. |
| SmolVLA pretrained on 487 curated community SO-100 datasets, ~10 million frames at 30 fps | SmolVLA release post | Community data transfers to a close relative. The narrowest, most reproducible transfer. |
Read it as a gradient. Transfer is strongest between close relatives, which is why the SmolVLA line is the most reliable one here, its pretraining pool being SO-100 community data and its reported real-world tasks covering SO100 and SO101 alike, and why SO-100 versus SO-101 is a smaller gap than SO-100 versus Koch. It is weakest, and can go negative, when a shared model is capacity-limited against a specialist trained on a large single-robot dataset.
- You inherit visual and language understanding that would take millions of frames to learn
- 30 to 50 episodes becomes a workable dataset size instead of an obvious joke
- Language conditioning arrives for free, which makes multi-task policies possible on one arm
- Frozen backbones mean your run trains a small slice, so a fine-tune costs single-digit dollars
- No pretrained head exists for your arm, so zero-shot on a NEW_EMBODIMENT tag is out
- Padding and normalisation must match between training and serving or the policy silently does nothing
- A 3 B model at 152 to 485 ms of inference latency per step is too slow for reactive motion over a network link
- Bigger is not automatically better than a small specialist like ACT at 20 ms
- The transfer benefit shrinks the more data you collect, the opposite of the intuition
What this means if you own exactly one arm
Almost nobody reading this will train across 20 embodiments. The value for a single-arm owner is indirect and still large: somebody else paid for the pretraining, and your job is to teach the action path what your robot is.
- Pick the smallest model that clears your task. Run ACT as a baseline first: if an 80 M model at 20 ms solves it, a 3 B model at 152 ms is a downgrade on hardware.
- Keep the camera setup fixed across every episode. The transfer you get is largely visual and it evaporates when the wrist camera moves between recording and inference.
- Record more distinct starting positions rather than repetitions of one. Diversity is what the shared trunk can use; repetition mostly teaches the head.
- Write real language annotations.
task_indexmapped to one constant sentence wastes the language pathway. Recording your first dataset covers the mechanics. - Compare against a from-scratch baseline before concluding that pretraining helped.
For background, the VLA overview covers the architecture family and the RT-2 article covers the web-knowledge half this page leaves out. For the route from nothing to a running policy, train your first policy is the short version and the training docs the long one.
Five policies, real numbers, one comparison table
GR00T N1.7, GR00T N1.5, Pi0.5, SmolVLA and ACT with parameter counts, GPU tier, inference latency per action step, minimum episodes and dataset format.
Compare the policiesCan I train one policy on my SO-100 data and my Koch v1.1 data together?▾
Not with an off-the-shelf command. LeRobot's MultiLeRobotDataset does not accept datasets with different schemas; that request is issue #542, closed as not planned. You either convert both into one common schema first or write your own collator. GR00T is no better: only one NEW_EMBODIMENT modality config can be registered per Python process.
Does an embodiment tag mean the model already knows my robot?▾
No, and this is the most common misreading. A pretrain tag such as OXE_DROID_RELATIVE_EEF_RELATIVE_JOINT means the base checkpoint carries a trained head for that embodiment and can run zero-shot. NEW_EMBODIMENT is listed among tags for custom robots that are in no shipped checkpoint, so a head is created during your fine-tune.
Why does Pi0 pad everything to 32 dimensions?▾
So one architecture covers a six-channel arm, a 14-dimensional bimanual setup and a mobile base without changing shape. In openpi, Pi0Config.action_dim defaults to 32 and action_horizon to 50, for Pi0 and Pi0.5 alike. The risk: the padding and normalisation convention must be identical at training and serving, or the policy looks trained and behaves like it is not.
Is a 3 B cross-embodiment model better than ACT on my one task?▾
Often not. Open X-Embodiment found RT-1-X did not beat the embodiment-specific RT-1 baseline in large-data domains, attributed to underfitting. Pretraining is a large win when your dataset is small, and the advantage narrows as you collect more. ACT is about 80 M parameters, runs at 20 ms per action step and trains on a 24 GB card for roughly 1 to 3 USD.
What does the relative end-effector action space actually buy?▾
The Isaac-GR00T README calls it a relative end-effector action space shared across robot and human embodiments and a key factor in cross-embodiment performance, since deltas from the current pose mean roughly the same thing on differently sized robots. The shipped SO-100 config does not use it: relative joint deltas with an absolute gripper, both NON_EEF.
Can I run cross-embodiment inference over the internet?▾
For slow pick-and-place, yes. For fast reactive motion, no. The control loop on AY-Robots runs between 20 ms and 485 ms per action step depending on the model, and public-internet round trips on top turn a working policy into a hesitant one. Inference wants to sit next to the servos. Cloud pods auto-destroy after an idle period.
Sources
- Open X-Embodiment: Robotic Learning Datasets and RT-X Models (arXiv 2310.08864, v9 revised 14 May 2025)
- Open X-Embodiment project page: 60 datasets, 34 labs, 1M+ trajectories, the RT-1-X 50 percent and RT-2-X 3x results
- Octo: An Open-Source Generalist Robot Policy (arXiv 2405.12213)
- Scaling Cross-Embodied Learning: One Policy for Manipulation, Navigation, Locomotion and Aviation (CrossFormer, arXiv 2408.11812)
- Scaling Proprioceptive-Visual Learning with Heterogeneous Pre-trained Transformers (HPT, arXiv 2409.20537)
- NVIDIA/Isaac-GR00T README: relative EEF action space, demo datasets, training tips, v3-to-v2 conversion helper
- Isaac-GR00T EmbodimentTag enum: pretrain, posttrain and finetune-only tag sets
- Isaac-GR00T: Fine-tune on Custom Embodiments (NEW_EMBODIMENT), with the checkpoint MSE and MAE trend table
- Isaac-GR00T Policy API guide: tag categories, the one-config-per-process rule, the demo dataset table
- Isaac-GR00T FinetuneConfig: tune_llm, tune_visual, tune_projector, tune_diffusion_model, state_dropout_prob, and no seed field
- nvidia/GR00T-N1.7-3B model card: 3B parameters, MLP indexed by embodiment ID, padded proprioception
- openpi Pi0Config: action_dim defaults to 32, action_horizon to 50, pi05 flag
- LeRobotDataset v3.0 documentation: meta/info.json, stats, tasks, episodes and the v2.1 migration
- lerobot issue #542: MultiLeRobotDataset with different schemas, closed as not planned
- SmolVLA release post: 487 curated community SO-100 datasets, around 10 million frames at 30 fps, 450M parameters
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started