The AY-Robots policies comparison table with GR00T N1.7, GR00T N1.5, Pi0.5, SmolVLA and ACT and their parameter counts, GPU tier, action latency and minimum episodes.
Vision-Language-ActionRobot LearningImitation LearningLeRobotSO-100

What Is a Vision-Language-Action Model? Inputs, Outputs, Limits

AY-Robots ResearchAugust 23, 202618 min read

A vision-language-action model turns camera frames, a joint-state vector and one sentence into a chunk of joint commands. What goes in, what comes out, and where it breaks.

A vision-language-action model is one neural network that reads camera frames, a robot state vector and one sentence of plain English, and writes joint commands. That is the whole idea. Everything after it is an argument about the output representation, the pretraining, and how fast the thing runs next to the servos. The glossary entry at vision-language-action model gives the short version; this is the long one.

The name comes from RT-2 (Google DeepMind, July 2023). The contribution was blunt: take a vision-language model that already knows what a banana looks like and train it to emit robot actions as if they were words. The paper describes VLAs as models that express the actions as text tokens and incorporate them directly into the training set of the model in the same way as natural language tokens. Everything since has kept the three input streams and changed the output head.

The short version

  • In: RGB frames, joint positions, a task string. Out: a chunk of future joint targets, not one command.
  • RT-2 wrote actions as text tokens, 256 bins per dimension. Pi0, GR00T N1 and SmolVLA predict continuous action chunks with flow matching instead.
  • A classical stack needs a pose, a planner and a URDF. A VLA needs demonstrations. Neither is free.
  • The chunk is why a slow model is still usable: GR00T N1 samples 16 actions per pass, Pi0 samples 50.
  • Per-action-step latency here runs from 20 ms (ACT) to 485 ms (Pi0.5).
  • The honest limit: LIBERO-Plus measured VLA success falling from 95 percent to under 30 percent under modest perturbation, and found models largely ignore the instruction.

What goes in

Three streams, every time, whether the model is 80 million parameters or 3 billion.

StreamWhat it actually isHow models cut it down
RGB framesOne to four camera views of the current instant, usually a fixed scene camera plus a wrist camera.GR00T N1 encodes each frame at 224x224 with pixel shuffle, leaving 64 image tokens per frame. SmolVLA also caps visual tokens at 64 and uses only the global image.
Proprioceptive stateThe current joint positions plus the gripper opening. On an SO-100 that is six numbers.GR00T N1.7 uses an MLP indexed by an embodiment ID, padding variable-length state vectors to a configurable maximum.
Language instructionOne task string, fixed for the episode. "Grab the black cube", not a dialogue.Encoded by the language half of the backbone. The GR00T N1.7 model card names Cosmos-Reason2-2B as the VLM backbone, with SigLip2 encoding the camera frames and T5 encoding the text.

That triple is what the LeRobot dataset format stores per frame, which is why it became the interchange layer for this class of model. An episode is one demonstration: a video per camera, a joint-state row and an action row per timestep, and one task string. When you record with the desktop client from the download page, or with lerobot-record locally, that is the file you produce.

The AY-Robots glossary entry for the LeRobot dataset format, showing the per-frame structure of episodes, camera streams and joint states.
The LeRobot dataset format is the container for all three input streams. Version mismatches kill most first training jobs.
The state vector is not optional, and it is not harmless

Proprioception is the easiest signal in the input, which is the problem. A policy can reach low training loss by continuing the current joint trajectory and only glancing at the pixels when the gripper has to close. That looks like success on a held-out split and fails the moment the object moves. NVIDIA ships a flag for exactly this: --state_dropout_prob randomly drops the state input during fine-tuning to reduce state-dependency, with a model-config default of 0.8 and a fine-tune CLI default of 0.2. If your policy tracks the demonstration path regardless of where the target is, start at loss falls, policy does nothing.

What comes out

This is where the designs differ. There are two answers, and one of them is mostly history.

Answer 1: action tokens as text (RT-2, 2023)

RT-2 did not invent this encoding; it says it bases the action encoding on the discretisation proposed for RT-1. The action is the 6-DoF positional and rotational displacement of the end effector, plus gripper extension, plus a discrete command that terminates the episode. Every continuous dimension was discretised into 256 uniform bins, so an action became eight integers, concatenated into a string and predicted like any other sentence.

text
# RT-2 action target, section 3.2 (Robot-Action Fine-tuning) of arXiv:2307.15818
# terminate  d_pos_x d_pos_y d_pos_z  d_rot_x d_rot_y d_rot_z  gripper
"1 128 91 241 5 101 127"

# 256 uniform bins per continuous dimension.
# PaLI-X: integers up to 1000 each have a unique token, so bins map straight onto them.
# PaLM-E: the 256 least frequently used tokens in the vocabulary get overwritten as the action vocabulary.
An RT-2 action is a string. That is the trick and also the cost: one forward pass, one action.

It worked, and it was slow: 1 to 3 Hz for the 55B PaLI-X variant, about 5 Hz for the 5B, served from a multi-TPU cloud service over the network. Full breakdown in how RT-2 transfers web knowledge to robot control.

Answer 2: continuous action chunks (Pi0, GR00T N1, SmolVLA)

Every VLA you can train here uses the second answer. Instead of one action per forward pass, the network emits a whole action chunk: the next H joint targets at once, produced by iterative denoising, either diffusion or flow matching, on a small head conditioned on the VLM's output tokens. ACT, the fifth trainable policy here, also emits chunks, but by direct regression rather than denoising and with no VLM in front of it. That difference is the subject of a later section.

ModelBackboneAction headChunk length H
RT-2 (2023)PaLI-X 5B / 55B, PaLM-E 12BDiscrete text tokens, 256 bins1
Pi0 (2024)PaliGemma, 3BFlow-matching action expert, 300M extra parameters on top of the 3B backbone (3.3B total)50, control up to 50 Hz
GR00T N1 (2025)NVIDIA Eagle-2 (SmolLM2 decoder, SigLIP-2 encoder), 1.34B of 2.2B totalDiffusion transformer with flow matching, cross-attending to the VLM tokens16
Pi0.5 (2025)PaliGemma VLM, 2B as configured in the paperTwo stages: discrete FAST tokens in pre-training, a 300M flow-matching action expert after50
SmolVLA (2025)SmolVLM-2 (SigLIP encoder, SmolLM2 decoder), first half of the layers onlyFlow-matching expert, interleaved self- and cross-attentionset per config
Action tokens are a whole design space now

The July 2025 survey A Survey on Vision-Language-Action Models: An Action Tokenization Perspective (arXiv:2507.01925) sorts VLA outputs into eight categories: language description, code, affordance, trajectory, goal state, latent representation, raw action, and reasoning. Raw action, joint targets straight out of the head, is what all five models on the policies page emit. It is one option of eight, not the definition.

The chunk is why a 485 ms model is usable at all. If Pi0.5 predicts 50 actions in one pass and the arm executes them at 30 fps, the model has about 1.6 seconds of runway before it has to think again. It is the first thing to tune when a policy stutters, and the reason inference latency alone is a misleading number.

How it differs from a classical controller

Same task: pick up a red block, drop it in a bin. Here is what the classical ROS 2 stack asks for, and what a VLA trained by imitation learning asks for instead.

Classical stack (MoveIt 2 + ros2_control)VLA policy
What you writeA URDF, a planning scene, and a motion plan request with kinematic constraints. MoveIt's four inbuilt types are position, orientation, visibility and joint constraints.A task string and 50 demonstrations.
Where the object pose comes fromA separate perception stage. The planner needs a pose and will not invent one.Nowhere explicit. The pose never becomes a variable you can print.
Who computes the pathhttps://moveit.picknik.ai/main/doc/concepts/motion_planning.html">OMPL, which MoveIt uses as its primary and default set of planners, then a trajectory controller.The action head. No path, just the next H joint targets.
When it failsLoudly: no IK solution, planning timeout, collision.Quietly. The arm moves smoothly to the wrong place.
DebuggabilityEvery stage has an inspectable input and output.One tensor in, one tensor out. Ablate cameras and re-run.
New taskNew perception, new constraints, new code.New demonstrations, same code.
Choosing a VLA over a hand-written controller
What you gain
  • No pose estimation stage. The policy consumes pixels directly, so the fiducial markers and the perception pipeline both disappear.
  • Contact-rich behaviour comes free: compliance, regrasping and small corrections are copied, not modelled.
  • Retargeting is a data problem, not a code problem: train your first policy.
  • The web pretraining is real: RT-2's ablation showed co-fine-tuning beats robot-only fine-tuning, and the same architecture trained from scratch performs badly even at 5B.
What you give up
  • No guarantees: no joint-limit proof, no collision certificate, no bounded error. You still need a safety envelope.
  • It covers only the distribution you demonstrated. Move a camera 10 cm and you are outside it.
  • Latency moves into the control loop. ros2_control runs its real-time update loop at a configured rate, 100 Hz by default; a VLA action step here costs 152 to 485 ms, roughly 2 to 7 Hz, before chunking hides it.
  • Debugging is empirical. The pages under fix exist because there is no stack trace for "it went to the wrong place".

The loop, from data to a moving arm

The manual path is three commands plus a lot of waiting. These are the lerobot entry points as documented in August 2026. Note that lerobot-rollout and lerobot-eval are two different tools, not one renamed: lerobot-rollout deploys a policy on a real robot, while lerobot-eval scores a policy inside a simulation environment and wants an --env.type. Reaching for the wrong one is a common first-run stumble.

  1. 1
    Record demonstrations

    Drive the arm by leader-follower teleoperation and record. The single_task string is the sentence the model gets conditioned on, so write the one you intend to type at inference time. LeRobot's guidance is at least 50 episodes, 10 per object position.

    bash
    lerobot-record \
        --robot.type=so101_follower \
        --robot.port=/dev/tty.usbmodem585A0076841 \
        --robot.id=my_awesome_follower_arm \
        --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 1920, height: 1080, fps: 30}}" \
        --teleop.type=so101_leader \
        --teleop.port=/dev/tty.usbmodem58760431551 \
        --teleop.id=my_awesome_leader_arm \
        --dataset.repo_id=${HF_USER}/record-test \
        --dataset.num_episodes=5 \
        --dataset.single_task="Grab the black cube"
  2. 2
    Fine-tune a base checkpoint

    Not from scratch: this is fine-tuning on a vendor checkpoint that already saw robot data. Hugging Face documents roughly 4 hours on one A100 for 20k steps of SmolVLA.

    bash
    cd lerobot && lerobot-train \
      --policy.path=lerobot/smolvla_base \
      --dataset.repo_id=${HF_USER}/mydataset \
      --batch_size=64 \
      --steps=20000 \
      --output_dir=outputs/train/my_smolvla \
      --job_name=my_smolvla_training \
      --policy.device=cuda
  3. 3
    Run the policy on the arm

    lerobot-rollout loads the checkpoint and closes the loop. The --task string must match what you recorded. --strategy.type picks the execution mode (base, sentry, highlight, dagger or episodic). --inference.type defaults to sync, one policy call per control tick; rtc is Real-Time Chunking, which smooths execution across chunk boundaries and is the one the docs point slow VLAs at.

    bash
    lerobot-rollout \
      --strategy.type=base \
      --policy.path=${HF_USER}/my_policy \
      --robot.type=so100_follower \
      --robot.port=/dev/ttyACM1 \
      --robot.cameras="{ up: {type: opencv, index_or_path: /dev/video10, width: 640, height: 480, fps: 30}}" \
      --task="Put lego brick into the transparent box" \
      --duration=60
The trap that eats a day: dataset format version

LeRobot v3.0 is the current recording format and Pi0.5, SmolVLA and ACT read it. GR00T does not: a v3.0 dataset crashes the GR00T loader and has to be converted down to v2.1 first. The error is not "wrong version", it is a stack trace from deep inside the loader, which is why people lose an afternoon to it. Check the format column on the policies page before queueing, and see dataset rejected as v3 if you already hit it.

What a VLA cannot do

This is the part most explainers skip. The published robustness work is unambiguous, and it matches what happens on a desk with an SO-100 on it.

  • It cannot survive a moved camera. LIBERO-Plus (October 2025) perturbed seven dimensions - object layout, camera viewpoint, robot initial state, language, lighting, background texture, sensor noise - and reported success dropping from 95 percent to below 30 percent under modest perturbation, worst for viewpoints and initial states. If your policy only works in one setup, that is expected behaviour: policy only works in one setup.
  • It often does not read your instruction. The same paper found models "largely insensitive to language variations" and that they "tend to ignore language instructions completely". The L does less work than the name suggests, especially after a single-task fine-tune where the string never varied.
  • It cannot recover reliably. A June 2026 benchmark of Pi0.5, SmolVLA, Wall-X and ACT on the SO-101 found execution instability to be the dominant failure source, with recovery varying substantially across architectures.
  • It cannot be fast and remote at once. Inference has to sit next to the servos for anything reactive. The control loop here is 20 to 485 ms per action step, and internet round trips on top turn a working policy into a hesitant one.
  • It cannot tell you why. There is no intermediate representation to inspect. The method is ablation: black out one camera, re-run, see what changes.
  • It cannot generalise from data you did not collect. The minimums here, 30 episodes for SmolVLA and 50 for the rest, are floors for one tightly controlled task.
Benchmark numbers are not competence

The arena holds 85 VLA models with 332 benchmark results, each value linked to its paper or model card. Use it to see what a family claims and on which benchmark, then treat the number as an upper bound under the authors' conditions. LIBERO-Plus exists because high scores on the standard suite did not survive small, realistic perturbations.

The AY-Robots arena leaderboard: a sortable table of 85 vision-language-action models with 332 benchmark results, every value linked to its source paper or model card.
85 models, 332 benchmark results, each value linked to its source. Sorting it shows how thin the overlap between benchmarks is.

Is ACT a VLA? No, and that matters

ACT sits on the same policies page as GR00T and Pi0.5, which makes people assume it belongs to the same family. It does not. ACT, from the ALOHA paper (Zhao et al., 2023), is an Action Chunking Transformer trained as a conditional VAE. Its vision backbone is a ResNet-18; its inputs are camera images, joint positions and a latent style variable z that is set to zero at inference. No language encoder, no web pretraining.

ACTA VLA (SmolVLA, GR00T N1.7, Pi0.5)
Language inputNone. The task string sits in the dataset and is ignored.Encoded by the backbone, conditions the action head.
PretrainingNone. Trained from scratch on your episodes, one model per task.Vendor base checkpoint: nvidia/GR00T-N1.7-3B, nvidia/GR00T-N1.5-3B, lerobot/pi05_base, lerobot/smolvla_base.
Size hereAbout 80M parameters.About 450M (SmolVLA) to about 3B (GR00T, Pi0.5).
Action latency here20 ms per step.152 ms (GR00T N1.7), 245 ms (SmolVLA), 485 ms (Pi0.5).
Multi-taskOne policy, one task, in practice.Language conditioning makes multi-task possible.

ACT is the cheapest thing that works on a single fixed task, and the baseline every VLA should beat. The paper trains it in about 5 hours on one 11 GB RTX 2080 Ti and measures inference at roughly 0.01 seconds, which is the whole argument for keeping it in the lineup. It also adds temporal ensembling, averaging overlapping chunks to smooth the motion. If it beats your VLA on your data, the data is the problem. There is no ACT base model, which is why the ACT page lists no vendor checkpoint. Compare it to a real VLA on ACT versus SmolVLA before spending an A100 hour.

Getting one running: the two paths

Everything above runs on your own machine. The friction is not the training loop, it is the environment: three vendors, three CLIs, three dataset expectations.

  1. 1
    SmolVLA or ACT, locally

    Both fit a 24 GB card. Install lerobot, add the SmolVLA extra, train.

    bash
    git clone https://github.com/huggingface/lerobot.git
    cd lerobot
    pip install -e ".[smolvla]"
    
    lerobot-train \
      --policy.path=lerobot/smolvla_base \
      --dataset.repo_id=${HF_USER}/mydataset \
      --batch_size=64 --steps=20000 \
      --policy.device=cuda
  2. 2
    GR00T N1.7, on a rented A100 or H100

    Separate repo, separate CLI, uv-based. The README asks for 16 GB+ VRAM for inference and recommends 40 GB+ for fine-tuning. The entry point is a tyro CLI with no seed flag, so GR00T runs are not bit-for-bit reproducible (lerobot's default seed is 1000). NVIDIA also warns of 5 to 6 percent variance between runs from non-deterministic image augmentations.

    bash
    git clone https://github.com/NVIDIA/Isaac-GR00T.git
    cd Isaac-GR00T
    
    CUDA_VISIBLE_DEVICES=0 uv run python \
        gr00t/experiment/launch_finetune.py \
        --base-model-path nvidia/GR00T-N1.7-3B \
        --dataset-path demo_data/cube_to_bowl_5 \
        --embodiment-tag NEW_EMBODIMENT \
        --modality-config-path examples/SO100/so100_config.py \
        --num-gpus 1 \
        --output-dir /tmp/test_finetune \
        --max-steps 2000 \
        --global-batch-size 32
  3. 3
    Pi0.5, via openpi

    Third repo, JAX-based. The openpi README puts LoRA fine-tuning above 22.5 GB (a 4090 will do) and full fine-tuning above 70 GB. Normalisation statistics are a separate step people forget.

    bash
    uv run scripts/compute_norm_stats.py --config-name pi05_libero
    
    XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 \
      uv run scripts/train.py pi05_libero --exp-name=my_experiment --overwrite
    
    uv run scripts/serve_policy.py policy:checkpoint \
      --policy.config=pi05_libero \
      --policy.dir=checkpoints/pi05_libero/my_experiment/20000
What this path actually costs you

Not money, if you own a 4090. Time: three toolchains, three dataset conversions, and a GR00T loader that rejects the format lerobot writes by default. Budget a day before the first step counter moves.

The AY-Robots training matrix on /train: five policies as rows, four supported arms as columns, every cell linking to that exact model-and-arm guide.
The /train matrix: pick the model row and the arm column, land on the guide for that exact pair.

Five VLA policies, compared on numbers that matter

Parameters, GPU tier, latency per action step, minimum episodes and dataset format for all five trainable policies. The table you need before you queue a run.

Compare the policies

How fast is fast enough

Latency is where the abstraction leaks into hardware, so be precise about which number you are reading. Several measurements get quoted as "VLA latency" and they are not comparable.

MeasurementValueSource and conditions
Per action step, on this platform20 ms (ACT), 152 ms (GR00T N1.7), 165 ms (GR00T N1.5), 245 ms (SmolVLA), 485 ms (Pi0.5)What the serving path here measures per step.
End-to-end forward pass, GR00T N1.785.8 ms on H100 in PyTorch eager, 27.9 ms with the TensorRT full pipeline, 342.8 ms on Jetson Orin eagerNVIDIA's model card, 4 denoising steps, 1 camera.
Chunk sampling, GR00T N163.9 ms for 16 actions on an L40 in bf16GR00T N1 paper, arXiv:2503.14734.
Historical, RT-21 to 3 Hz for the 55B model, about 5 Hz for the 5BRT-2 paper, served over the network from a multi-TPU cloud service.

The chunk hides most of this. SmolVLA goes further with an asynchronous stack that decouples execution from the next prediction: the paper reports a task finishing in 9.7 seconds instead of 13.75, and 19 pick-and-place cycles in a fixed window against 9 synchronously. In lerobot that is --inference.type=rtc, which the docs point at the models with high inference latency: Pi0, Pi0.5 and SmolVLA.

Where to go from here

Is a vision-language-action model just an LLM for robots?

Not quite. The backbone is a vision-language model, but the output head is different. RT-2 kept the language head and wrote actions as text tokens, 256 bins per dimension. Every model you can train today replaces that head with a diffusion or flow-matching module that emits continuous joint targets in chunks, because one action per forward pass is too slow for a real arm.

Does the language instruction actually change what the robot does?

Less than the name implies. LIBERO-Plus (arXiv:2510.13626) found VLAs largely insensitive to language variation and reported that models tend to ignore the instruction entirely. After a single-task fine-tune where the string never varied, expect it to be ignored. To make language matter, record several tasks with different strings in one dataset.

How many demonstrations do I need before it is worth training?

The minimums here are 30 episodes for SmolVLA and 50 for GR00T N1.7, GR00T N1.5, Pi0.5 and ACT, and those are floors for one tightly controlled task. Hugging Face's SmolVLA guidance is about 50 episodes with 10 per object position, and notes that 25 was not enough.

Can I run a VLA without a GPU next to the robot?

For slow pick-and-place, yes: an inference pod serves the policy and the robot client talks to it over the network. For anything reactive, no. The loop is already 20 to 485 ms per action step, and internet round trips on top produce a hesitant policy. SmolVLA and ACT also run locally.

Is ACT a VLA?

No. ACT is an Action Chunking Transformer with a ResNet-18 backbone, trained as a conditional VAE on images, joint positions and a latent style variable. No language encoder, no pretraining, no base model to start from. It is here because it is the cheapest policy that works on one fixed task, and the baseline a VLA has to beat.

What does one training run cost?

On the A100 80 GB or H100 tier (GR00T N1.7, GR00T N1.5, Pi0.5), 3 to 6 hours at 1.20 to 2.00 USD per hour, about 4 to 12 USD per run. On the RTX 4090 or 24 GB tier (SmolVLA, ACT), 2 to 5 hours at 0.30 to 0.60 USD per hour, about 1 to 3 USD. Spot-market prices, hence the ranges.

Ready for high-quality robotics data?

AY-Robots connects your robots to skilled operators worldwide.

Get Started