
Which vision encoder each VLA policy actually ships with, what freezing the backbone costs in accuracy and saves in VRAM, and how to tell when the encoder is your bottleneck.
Every vision-language-action model on this site begins the same way. A camera frame goes into a pretrained image encoder, comes out as a small number of tokens, and everything downstream - the language model, the action head, the servo commands - only ever sees those tokens. If the encoder discards the detail your task depends on, no amount of training on the action head gets it back.
So two questions are worth answering before you rent a GPU: which encoder is actually inside the policy you picked, and is that encoder being trained or held fixed while you fine-tune. The answers differ per model, they are usually one level deeper than the model card, and for one of the five policies you can train here the default flipped between the paper and the current code.
What you need to know
- •You do not pick SigLIP or DINOv2. The encoder comes with the VLM your policy inherits: Pi0.5 gets SigLIP-So400m/14 via PaliGemma, SmolVLA a 93M SigLIP-B/16 via SmolVLM2, GR00T N1.5 SigLIP-2 via Eagle-2, and GR00T N1.7 a Qwen3-VL tower via nvidia/Cosmos-Reason2-2B.
- •DINOv2 appears in only one major VLA: OpenVLA, fused channel-wise with SigLIP. Removing it cost about 5 points of success rate in the paper's own ablation, against 30 points for removing the pretraining data.
- •Freezing is the real decision. OpenVLA measured 69.7% success with full fine-tuning against 47.0% frozen, and the frozen run still trained 6.76 of 7.19 billion parameters.
- •Isaac-GR00T ships tune_visual = False today; the docs say flipping it moves recommended VRAM from about 35 GB to 80 GB or more per GPU. lerobot ships freeze_vision_encoder = True for SmolVLA, False for Pi0.5.
- •Suspect the encoder when the policy works in the recorded scene and collapses when lighting or camera pose move. Do not suspect it when the loss falls and the arm does nothing.
- •Here you choose the policy and the policy chooses the encoder. The training form has no freeze toggle, so you get each vendor's default.
The encoder is the narrowest part of the pipe
Look at how few numbers actually cross from the camera into the transformer. GR00T N1 encodes images at 224 by 224 and applies pixel shuffle, leaving 64 image token embeddings per frame. SmolVLA lands on the same number from the other end: SmolVLM2-500M runs a patch-16 tower at 512 by 512, a 32 by 32 grid of 1024 patches, and a pixel shuffle with scale factor 4 collapses that by 16 to exactly 64. Pi0.5 spends more, with SigLIP-So400m at patch 14 on a 224 by 224 image giving a 16 by 16 grid, so 256 tokens per camera.
| Policy | Vision tower | Where it comes from | Input handling | Tokens per camera frame |
|---|---|---|---|---|
| GR00T N1.7 | Qwen3-VL vision transformer | nvidia/Cosmos-Reason2-2B (2,438,696,960 params, gated) | Flexible resolution, native aspect ratio, no padding | Varies with image size |
| GR00T N1.5 | SigLIP-2 | Eagle VLM backbone | 224 x 224 plus pixel shuffle (N1 architecture) | 64 (as described for N1) |
| Pi0.5 | SigLIP So400m/14 | PaliGemma, via openpi models/pi0.py | resize_with_pad to 224 x 224 | 256 |
| SmolVLA | SigLIP-B/16, about 93M params | SmolVLM2-500M-Video-Instruct | resize_imgs_with_padding = (512, 512) | 64 |
| ACT | ResNet-18 | torchvision, ImageNet weights | Raw camera frames, no VLM | 300 feature vectors per 480x640 image |
That last row is the odd one out on purpose. ACT has no vision-language model at all. The ALOHA paper describes ResNet-18 backbones turning a 480 by 640 by 3 image into a 15 by 20 by 512 feature map, flattened to a 300 by 512 sequence per camera, with no language conditioning and no internet pretraining beyond ImageNet. That is why it trains from scratch on your task and why it is the cheapest row on the training matrix.
A 512 by 512 frame reduced to 64 tokens is not 'higher resolution' than a 224 by 224 frame reduced to 256 tokens. SmolVLA sees a wider field compressed harder; Pi0.5 sees a narrower field kept finer. If your task turns on a two-millimetre alignment cue in a wrist camera, the token budget matters more than the input resolution in the config.
Which encoder each policy actually ships
The model cards mostly say 'a pretrained vision transformer'. The configs say which one. Everything below was read out of the repositories on 2026-08-24, and the version matters, because at least one of these changed twice in a year.
GR00T N1.7 and N1.5: from SigLIP-2 to Qwen3-VL
The GR00T N1 white paper describes an Eagle-2 vision-language backbone that is itself fine-tuned from a SmolLM2 language model and a SigLIP-2 image encoder. The published GR00T-N1-2B had 2.2B parameters total with 1.34B in the VLM. GR00T N1.5 keeps that lineage; its model card states that RGB camera frames are processed through a pre-trained SigLIP2 vision transformer. GR00T N1.7 does not. The Isaac-GR00T README is explicit that the backbone changed from the vendored Eagle model nvidia/Eagle-Block2A-2B-v2 to nvidia/Cosmos-Reason2-2B, which is post-trained from Qwen3-VL-2B-Instruct and encodes images in their native aspect ratio without padding.
# gr00t/model/modules/qwen3_backbone.py (Isaac-GR00T, main, read 2026-08-24)
class Qwen3Backbone(torch.nn.Module):
def __init__(
self,
model_name: str = "nvidia/Cosmos-Reason2-2B",
tune_llm: bool = False,
tune_visual: bool = False,
...
tune_top_llm_layers: int = 0,
):
def set_trainable_parameters(self, tune_llm, tune_visual, tune_top_llm_layers):
for p in self.parameters():
p.requires_grad = True
if not tune_llm:
self.model.language_model.requires_grad_(False)
if not tune_visual:
self.model.visual.requires_grad_(False)Pi0.5: SigLIP-So400m, and nothing frozen
Pi0.5 inherits PaliGemma, which pairs SigLIP-So400m with Gemma-2B. In openpi the instantiation is unambiguous, and the model's freeze filter returns nothing at all unless you explicitly ask for a LoRA variant. Even then the filter matches paths under the language model, never the image tower. In other words, on the reference implementation the SigLIP encoder trains along with everything else.
# src/openpi/models/pi0.py (openpi, main, read 2026-08-24)
img = nnx_bridge.ToNNX(
_siglip.Module(
num_classes=paligemma_config.width,
variant="So400m/14",
pool_type="none",
scan=True,
dtype_mm=config.dtype,
)
)
# src/openpi/models/pi0_config.py
def get_freeze_filter(self) -> nnx.filterlib.Filter:
...
if not filters:
return nnx.Nothing # default: nothing is frozenSmolVLA: a 93M SigLIP, frozen, and only half the language model
SmolVLA is the one that optimises hardest for small GPUs, and it does it in three places at once. The SmolVLM paper puts the 500M variant together from a 93M SigLIP-B/16 and SmolLM2-360M, against a 428M SigLIP-SO400M in the 2.2B variant. The SmolVLA paper then drops image tiling, keeps only the global image, and skips half the language decoder: the action expert reads features up to layer N, with N = L/2 in practice. SmolVLM2-500M has 32 decoder layers, and lerobot's default is 16.
# src/lerobot/policies/smolvla/configuration_smolvla.py (lerobot v0.5.1)
resize_imgs_with_padding: tuple[int, int] = (512, 512)
freeze_vision_encoder: bool = True
train_expert_only: bool = True
train_state_proj: bool = True
optimizer_lr: float = 1e-4
vlm_model_name: str = "HuggingFaceTB/SmolVLM2-500M-Video-Instruct"
num_vlm_layers: int = 16 # first 16 of the VLM's 32 layers
self_attn_every_n_layers: int = 2ACT: the only backbone you can actually swap
ACT is the exception where the encoder is a config field rather than a consequence of the base model. lerobot validates that the value starts with 'resnet' and gives the backbone its own learning rate, which is the classic detection-transformer pattern of training the CNN more gently than the head. The paper's own hyperparameters - learning rate 1e-5, batch size 8, chunk size 100 - line up with what this platform sends for ACT, and the code carries a comment that the original implementation used 7 decoder layers where lerobot uses 1.
# src/lerobot/policies/act/configuration_act.py (lerobot v0.5.1)
vision_backbone: str = "resnet18"
pretrained_backbone_weights: str | None = "ResNet18_Weights.IMAGENET1K_V1"
replace_final_stride_with_dilation: int = False
optimizer_lr: float = 1e-5
optimizer_lr_backbone: float = 1e-5
chunk_size: int = 100
n_action_steps: int = 100
What freezing actually does
Freezing a vision encoder means its weights stop receiving gradients. Two things follow, and only one of them is the one people expect. The obvious one: the encoder can no longer adapt to your cameras, your lighting or your table. The less obvious one: you save far less memory than you think, because the activations still have to be computed and kept for the backward pass through everything above the encoder.
- Preserves internet-scale features that a few dozen episodes cannot re-learn. The DINOv2 authors make exactly this argument: features that work across image distributions and tasks without fine-tuning.
- Cuts optimiser state. Adam keeps two moments per trainable parameter, so a frozen 400M tower is 400M fewer momentum and variance buffers.
- Removes the failure mode where a small, single-background dataset drags a good encoder into overfitting.
- For GR00T, the hardware guide puts default fine-tuning at under about 35 GB peak VRAM per GPU, versus 80 GB or more once --tune-visual or --tune-llm is on.
- The encoder never learns your wrist camera. Internet images are not close-up views of a gripper at 30 cm.
- Measured cost in OpenVLA: 47.0% success frozen against 69.7% with full fine-tuning, same tasks.
- The memory saving is small: 6,760.4M trainable parameters against 7,188.1M, and 156.2 GB against 163.3 GB.
- It hides the problem. A frozen encoder that cannot see your task still trains cleanly and reports a falling loss.
If you hit an out-of-memory error and reach for the freeze flag, look at OpenVLA's numbers first: frozen vision saved 7.1 GB out of 163.3 GB and cost 22.7 points of success rate. LoRA at rank 32 trained 97.6M parameters instead of 7,188.1M, fit in 59.7 GB, and still scored 68.2%. Freezing the encoder is a modelling decision, not a memory fix. For the actual memory fixes, see out of memory during training.
The experiment that settled it, and the one that did not
OpenVLA is the only widely cited VLA that ran the ablation cleanly and published the table. It is built on the Prismatic-7B VLM: a 600M-parameter visual encoder that passes image patches separately through SigLIP and DINOv2 and concatenates the feature vectors channel-wise, a two-layer MLP projector, and a Llama 2 7B backbone. The paper is blunt that this contradicted the VLM literature: prior work found freezing vision encoders during VLM training leads to higher performance, and they found the opposite for control. OpenVLA itself is on the arena page for OpenVLA with its published benchmark numbers.
| Fine-tuning strategy | Success rate | Trainable params (millions) | VRAM at batch 16 |
|---|---|---|---|
| Full fine-tuning | 69.7% +/- 7.2 | 7,188.1 | 163.3 GB (2 GPUs, FSDP) |
| LoRA, rank 32 | 68.2% +/- 7.5 | 97.6 | 59.7 GB |
| LoRA, rank 64 | 68.2% +/- 7.8 | 195.2 | 60.5 GB |
| Sandwich (encoder + embeddings + last layer) | 62.1% +/- 7.9 | 914.2 | 64.0 GB |
| Frozen vision encoder | 47.0% +/- 6.9 | 6,760.4 | 156.2 GB (2 GPUs, FSDP) |
| Last layer only | 30.3% +/- 6.1 | 465.1 | 51.4 GB |
Read the table as a ranking of what your gradient budget should buy. Spending it on the vision encoder plus a low-rank update everywhere else beats spending it on 6.76 billion parameters that exclude the encoder. In a separate appendix experiment the gap is starker still: across evaluations where both were run, fine-tuning the vision encoder averaged 80.0% success against 46.7% frozen, and some frozen runs were abandoned for near-zero performance and unstable robot behaviour.
The DINOv2 question got a much smaller answer. Dropping the DINOv2 half of the fused encoder moved mean success from 45.6% to 40.6% in the Bridge-only ablation, which the authors call about a 5 percent reduction against a 30 percent drop from removing Open X-Embodiment pretraining. Their summary is that DINOv2's low-level spatial features aid generalisation in only some cases. If you hoped a spatial encoder was the missing ingredient, the published evidence says data comes first, which is where the Open X-Embodiment work ends up too. If the architecture terms above are new, this introduction to VLA models is the place to start.
The same paper compared 224 x 224 and 384 x 384 inputs and found no performance difference, while the 384 px model took 3x longer to train. Before hunting for a higher-resolution encoder, check that your LeRobot dataset contains the detail you want the encoder to see.
So why does GR00T freeze it, then?
This is the part where dating the claim matters. The GR00T N1 white paper's hyperparameter table lists the backbone's vision encoder as unfrozen for both pre-training and post-training, with only the text tokenizer frozen. The current Isaac-GR00T fine-tuning config, read from main on 2026-08-24, ships the opposite default.
# gr00t/configs/finetune_config.py (Isaac-GR00T, main, read 2026-08-24)
tune_llm: bool = False
tune_visual: bool = False
tune_projector: bool = True
tune_diffusion_model: bool = True
global_batch_size: int = 64
learning_rate: float = 1e-4
max_steps: int = 10000
weight_decay: float = 1e-5
warmup_ratio: float = 0.05
save_steps: int = 1000
save_total_limit: int = 5Two things reconcile it. The audience changed: the paper describes pre-training at batch size 16,384 over 200,000 gradient steps, while the shipped fine-tuning path targets one GPU and a few thousand steps. And the cost changed: the hardware guide says default fine-tuning keeps peak VRAM under about 35 GB per GPU, while --tune-visual or --tune-llm pushes the recommendation to 80 GB or more. Both GR00T versions sit on the 80 GB tier here for that reason, which is also why a run costs more than on the 24 GB pair.
FinetuneConfig has no seed. The Isaac-GR00T README states that users may observe 5-6% variance between runs due to non-deterministic image augmentations. If you A/B test --tune-visual on a single run each, a 4-point difference tells you nothing. lerobot, by contrast, exposes a seed and defaults it to 1000. Plan for repeats, and see the training docs for how runs are configured here.
When the encoder is your bottleneck, and when it is not
Most failures blamed on the vision encoder are not the vision encoder. Here is the split that has held up in practice, mapped onto the failure pages on this site.
| Symptom | Likely cause | Where to look |
|---|---|---|
| Works in the recorded scene, fails after you move a lamp or the camera | Encoder features are not invariant to your setup, or the dataset never varied it | policy only works in one setup |
| Loss falls smoothly, the arm barely moves | Action normalisation, state dominance or too few episodes - not the encoder | loss falls, policy does nothing |
| Approach is right, the gripper closes on empty air | Wrist camera view or camera-to-slot mapping, before anything about encoder weights | gripper does not close |
| Motion is hesitant and lags the scene | Control-loop latency, not perception quality | inference latency |
| Policy freezes partway through the motion | Chunk boundaries and streaming, not the image tower | policy freezes mid-motion |
A cheap way to find out which one you have: ablate the images and see whether the policy notices. If you feed the trained policy black frames and the predicted joint targets barely change, the policy is not reading your cameras at all - it is extrapolating from proprioception, and unfreezing the encoder will not help. If the predictions collapse when you swap two camera streams, the encoder is doing real work and the question becomes whether it does it well enough.
- 1Record the baseline predictions
Run the trained checkpoint open-loop over a held-out episode and store the predicted action chunk for every step. Do this before touching any flag.
bashuv run python gr00t/eval/open_loop_eval.py \ --dataset-path /data/my_so100_task \ --embodiment-tag NEW_EMBODIMENT \ --model-path /checkpoints/run-a/checkpoint-2000 - 2Blind the policy and repeat
Feed the same episode with every camera replaced by a constant frame. Compare the mean absolute deviation of the predicted joint targets against the baseline. A small deviation means the images are not driving the actions.
pythonobs = dict(baseline_obs) for key in obs: if key.startswith("video."): obs[key] = np.zeros_like(obs[key]) pred_blind = policy.get_action(obs) - 3A/B the freeze flag with repeats, not once
For GR00T, run the same config twice per arm of the test, because the README documents 5-6% run-to-run variance from non-deterministic augmentation. Everything else in the command stays identical.
bash# arm A: shipped default, vision tower frozen CUDA_VISIBLE_DEVICES=0 uv run python gr00t/experiment/launch_finetune.py \ --base-model-path nvidia/GR00T-N1.7-3B \ --dataset-path demo_data/my_task \ --embodiment-tag NEW_EMBODIMENT \ --modality-config-path examples/SO100/so100_config.py \ --num-gpus 1 --max-steps 2000 --global-batch-size 32 \ --output-dir /tmp/ft_frozen # arm B: same run with the vision tower training CUDA_VISIBLE_DEVICES=0 uv run python gr00t/experiment/launch_finetune.py \ --base-model-path nvidia/GR00T-N1.7-3B \ --dataset-path demo_data/my_task \ --embodiment-tag NEW_EMBODIMENT \ --modality-config-path examples/SO100/so100_config.py \ --num-gpus 1 --max-steps 2000 --global-batch-size 32 \ --tune-visual \ --output-dir /tmp/ft_tuned - 4Do the same on the lerobot side
lerobot exposes the policy dataclass fields directly on the command line, so the flag is the config field. SmolVLA ships frozen, Pi0.5 ships unfrozen, so the interesting direction is opposite for each.
bashlerobot-train \ --policy.path=lerobot/smolvla_base \ --dataset.repo_id=${HF_USER}/mydataset \ --policy.freeze_vision_encoder=false \ --policy.train_expert_only=false \ --batch_size=64 --steps=20000 \ --output_dir=outputs/train/smolvla_unfrozen \ --job_name=smolvla_unfrozen \ --policy.device=cuda - 5Judge on the arm, not on the loss curve
Validation loss on teleoperated data rewards copying the operator's smoothing, not completing the task. Score both checkpoints over the same set of physical trials and count successes.

Testing the freeze question: by hand, or here
Everything above is runnable. The friction is not the code, it is the setup around it: gated weights, two different training stacks, and a GPU big enough to hold the unfrozen arm of the experiment.
- 1Get access to the gated backbone
GR00T's VLM backbone nvidia/Cosmos-Reason2-2B is gated, and every GR00T checkpoint loads it on first use, including the base model. Without access the run fails with a GatedRepoError.
bash# request access on https://huggingface.co/nvidia/Cosmos-Reason2-2B first uv run huggingface-cli login # or: export HF_TOKEN=<your_token> - 2Install the two stacks you need
Isaac-GR00T for GR00T N1.7 and N1.5, lerobot for SmolVLA, Pi0.5 and ACT. They do not share a training entry point.
bashgit clone https://github.com/NVIDIA/Isaac-GR00T && cd Isaac-GR00T uv sync --python 3.12 uv run python -c "import gr00t; print('GR00T installed successfully')" # lerobot, for SmolVLA, Pi0.5 and ACT pip install lerobot - 3Convert the dataset if you are training GR00T
GR00T expects LeRobot v2.0 or v2.1. A v3.0 dataset has to be converted down first; the repo ships the script.
bashuv run python scripts/lerobot_conversion/convert_v3_to_v2.py --help - 4Rent a card that fits the unfrozen arm
Frozen GR00T fine-tuning stays under about 35 GB peak. With --tune-visual, NVIDIA recommends 80 GB or more per GPU. If you only have a 24 GB card, the unfrozen arm of the experiment is not available to you for GR00T at all.
- 5Run both arms twice and score on hardware
Two runs per arm, because of the documented 5-6% variance. Then physical trials, not validation loss.
Four GR00T runs at 2,000 steps each, plus the dataset conversion, plus the physical trials. The GPU bill is the small part. The day goes to the gated-repo round trip and to discovering that your dataset is v3.0.
The platform removes the setup, not the decision. You pick a model and a dataset on the training form, the backend rents a GPU on a spot market sized by the VRAM the model needs, runs the trainer and writes checkpoints to object storage. What it sends is each vendor's defaults.
| Policy | Batch size | Learning rate | Max steps | Grad accumulation | Does grad accum apply? |
|---|---|---|---|---|---|
| GR00T N1.7 | 32 | 1e-4 | 20000 | 1 | yes |
| GR00T N1.5 | 1 | 1e-5 | 2000 | 16 | yes |
| Pi0.5 | 1 | 5e-5 | 30000 | 16 | no (lerobot 0.5.1 has no such flag) |
| SmolVLA | 2 | 1e-4 | 20000 | 8 | no |
| ACT | 8 | 1e-5 | 100000 | 1 | no |
The extra knobs the form exposes are per policy: saveSteps for both GR00T versions, seed and logFreq for Pi0.5 and SmolVLA, and chunkSize (default 100), nActionSteps (default 100), seed and logFreq for ACT. Encoder freezing is not among them. GR00T N1.7 and Pi0.5 are cloud-only here; SmolVLA and ACT also run locally. Full price ranges are on the pricing page, and train your first policy walks the whole loop end to end.
| GPU tier | Policies | Typical run | Price per hour | Cost per run |
|---|---|---|---|---|
| A100 80 GB / H100 80 GB | GR00T N1.7, GR00T N1.5, Pi0.5 | 3 to 6 hours | 1.20 to 2.00 USD | about 4 to 12 USD |
| RTX 4090 / any 24 GB card | SmolVLA, ACT | 2 to 5 hours | 0.30 to 0.60 USD | about 1 to 3 USD |
GPU provisioning on a spot market sized by the VRAM the model needs, checkpoints written to object storage, and an inference pod from /api/inference/pod that carries an idle watchdog and destroys itself, so nothing keeps billing silently. The same operations are available from the CLI and the MCP server. The dataset version rule still applies either way: a LeRobot v3.0 dataset has to be converted down to v2.1 before GR00T will load it, which is what dataset rejected as v3 is about.

Where this platform does not help you
Three honest limits, because pretending otherwise wastes your money rather than ours. None of them is fixed by picking a different checkpoint.
- You cannot toggle the freeze from the form. The training form sends batch size, learning rate, max steps, gradient accumulation and the per-policy extras listed above. If you want the unfrozen arm of the GR00T experiment, that is a local Isaac-GR00T run today.
- You cannot change the encoder. Picking a policy picks its vision tower. The only encoder that is genuinely a config field is ACT's ResNet variant, and that is a lerobot feature rather than a platform one.
- Latency is physics, not a setting. The control loop runs at 20 ms per action step for ACT and 485 ms for Pi0.5, with GR00T N1.7 at 152 ms, GR00T N1.5 at 165 ms and SmolVLA at 245 ms. Adding public-internet round trips on top turns a working policy into a hesitant one. Remote inference is viable for slow pick-and-place and not for fast reactive motion - keep the policy next to the servos when the task is fast.
One more worth saying out loud: no encoder setting fixes a dataset. The minimum episode counts here are 50 for GR00T N1.7, GR00T N1.5, Pi0.5 and ACT, and 30 for SmolVLA, and those are minimums for the job to be worth running rather than targets for a policy that generalises. If your episodes all come from one camera pose under one lamp, an unfrozen SigLIP will happily learn that lamp. How to collect high-quality VLA training data covers the variation that pays, and the dataset directory shows what other people's coverage looks like.
Five policies, five different vision towers
GR00T N1.7 on Cosmos-Reason2-2B, GR00T N1.5 on SigLIP-2, Pi0.5 on SigLIP-So400m, SmolVLA on a 93M SigLIP-B/16, ACT on a ResNet-18. Compare them side by side with parameter counts, GPU tier, inference latency and minimum episodes.
Compare the five policiesFrequently asked questions
Which vision encoder does each policy use?▾
Pi0.5 uses SigLIP-So400m at patch 14, inherited from PaliGemma. SmolVLA uses the 93M SigLIP-B/16 inside SmolVLM2-500M-Video-Instruct. GR00T N1 and N1.5 use SigLIP-2 through the Eagle-2 backbone. GR00T N1.7 replaced Eagle with nvidia/Cosmos-Reason2-2B, a Qwen3-VL model, so its tower is a native-resolution ViT rather than SigLIP. ACT uses a torchvision ResNet-18 from ImageNet weights and has no VLM at all.
Should I unfreeze the vision encoder?▾
If you have the VRAM, the published evidence favours it: OpenVLA measured 69.7% with full fine-tuning against 47.0% frozen, and 80.0% against 46.7% in a separate appendix comparison. Their best trade-off was neither, though. LoRA at rank 32 reached 68.2% while training 97.6M parameters instead of 7,188.1M.
Is DINOv2 better than SigLIP for robot control?▾
They do different jobs. SigLIP is trained on image-text pairs with a sigmoid loss and carries language-alignable semantics; DINOv2 is trained self-supervised on the curated LVD-142M image set with no text at all, and carries stronger dense spatial structure. OpenVLA is the only major VLA that fuses both, and its ablation put DINOv2's contribution at roughly 5 points of success rate. Useful, not decisive.
Why does GR00T freeze the vision tower when the GR00T N1 paper trained it?▾
Different scale and different audience. The paper's hyperparameter table lists the vision encoder as unfrozen at batch size 16,384 over 200,000 gradient steps. The shipped fine-tuning config targets one GPU and a few thousand steps, where the hardware guide puts default fine-tuning under about 35 GB peak VRAM and warns that --tune-visual needs 80 GB or more. Both are correct for their context, so date any claim about GR00T defaults.
Can I change the encoder or the freeze setting on AY-Robots?▾
No. The form exposes batch size, learning rate, max steps, gradient accumulation and a small set of per-policy extras - saveSteps for GR00T, seed and logFreq for Pi0.5 and SmolVLA, plus chunkSize and nActionSteps for ACT. Encoder choice and freeze flags are not among them, so what runs is each vendor's default.
Would a higher-resolution camera help?▾
Check the token budget first. OpenVLA compared 224 x 224 and 384 x 384 inputs and found no performance difference, while the larger one took 3x longer to train. Pi0.5 resizes every camera to 224 x 224 with padding and SmolVLA to 512 x 512, both before the encoder runs, so a 4K stream is discarded long before the action head sees it.
Sources
- Sigmoid Loss for Language Image Pre-Training (SigLIP)
- SigLIP 2: Multilingual Vision-Language Encoders with Improved Semantic Understanding, Localization, and Dense Features
- DINOv2: Learning Robust Visual Features without Supervision
- OpenVLA: An Open-Source Vision-Language-Action Model
- GR00T N1: An Open Foundation Model for Generalist Humanoid Robots
- pi-0.5: a Vision-Language-Action Model with Open-World Generalization
- SmolVLA: A Vision-Language-Action Model for Affordable and Efficient Robotics
- PaliGemma: A versatile 3B VLM for transfer
- Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware (ACT / ALOHA)
- Isaac-GR00T FinetuneConfig defaults (tune_visual, tune_llm, tune_projector)
- Isaac-GR00T Qwen3Backbone: Cosmos-Reason2-2B and set_trainable_parameters
- Isaac-GR00T hardware recommendation guide (VRAM with and without --tune-visual)
- openpi pi0.py: SigLIP So400m/14 instantiation for Pi0 and Pi0.5
- lerobot v0.5.1 SmolVLAConfig (freeze_vision_encoder, num_vlm_layers)
- nvidia/GR00T-N1.5-3B model card
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started