Anatomy of a vision-language-action model
π₀, OpenVLA, and GR00T are transformers you already know how to read: a VLM prefill plus an unusual decode. This teardown maps image tokens to action chunks, with the parameter counts and latency numbers that decide what runs on your workstation.
- Diagram the π₀-class stack — SigLIP vision tower, Gemma-class LM, proprioceptive token, flow-matching action expert — with the parameter count of each piece.
- Compare the four action-head families (regression, token bins, diffusion, flow matching) on expressiveness, inference cost, and training stability, with numbers.
- Compute the prefix token budget, action quantization error, and chunk-feasibility condition for a WidowX AI with two RealSense views.
- State precisely what OXE-scale pretraining transfers to your robot and what must come from your own fine-tuning data.
Here is the demystification up front: a VLA is a VLM whose decoder has been repurposed to emit robot actions. Take PaliGemma — a 3 B-parameter vision-language model of exactly the kind you have quantized, served, and profiled — and change only what the output layers produce and what the training targets are. Everything genuinely new lives in one place: the action interface, the machinery by which a discrete-token machine is made to emit continuous, multimodal, 50 Hz motor commands. This lesson is a teardown of that interface, with the parameter counts, token budgets, and latency numbers that decide what runs on your RTX workstation and WidowX AI.
Foundations: The Two Clocks and the Action Chunk
Before dissecting the architecture, we must resolve a conceptual compression that plagues many VLA tutorials: the conflation of policy inference and control execution. These are two distinct processes running on different hardware at different rates. Policy inference is the GPU-bound computation that maps observations to a sequence of future actions. Control execution is the CPU/RTOS-bound loop that sends motor commands to the arm. The abstraction that bridges them is the Action Chunk.
An Action Chunk is a sequence of future control commands, , predicted simultaneously by the policy. Here, is the horizon (the number of control steps into the future), not the number of tokens. For a WidowX AI with 6 joints and a gripper, each action is a 7-dimensional vector. The chunk is a matrix of shape . The policy runs at a frequency (e.g., 10 Hz), while the controller runs at (e.g., 50 Hz). The chunk bridges these rates: one inference produces actions, which the controller consumes over seconds.
A critical limitation of this abstraction is Staleness. The first action in the chunk is fresh; the last action is computed seconds before it is executed. If the scene changes (e.g., a human moves an object), the policy is acting on outdated observations. The staleness error is bounded by the end-effector velocity times the chunk duration: . This is a lower bound; acceleration and scene dynamics make the actual error worse.
Another undefined term in many texts is Multimodality. In signal processing, this implies multiple frequencies. In VLA action spaces, it refers to the probability distribution having multiple peaks. For example, grasping a mug can be done from the left or the right. A direct regression head (MSE) fits the conditional mean, which is the center of the mug—a collision. A token-based or flow-matching head can represent the full distribution, allowing the policy to sample one mode or the other.
Finally, consider the Proprioceptive Token. The robot's state (joint positions, gripper width) is projected into a single token via a linear layer. This is a lossy bottleneck. It assumes the LM can infer velocity and acceleration from the position history in the context window. If the state changes rapidly, this assumption fails, and the policy may react sluggishly. This is a known limitation of the current architecture.
Worked Example: Feasibility and Staleness on an RTX 4090
Let us compute the feasibility and staleness for a -class policy on an RTX 4090. Assume the VLM prefill takes ms. The flow-matching expert takes steps, each taking ms. The control rate is Hz, so ms. The chunk length is .
The feasibility condition is . Here, , so the policy is feasible. The Duty Cycle is the fraction of time the GPU is busy: . This leaves 90% of the time for other tasks or overlap.
Now, consider the staleness at the end of the chunk. The 50th action is executed at ms relative to the chunk start. It was computed at ms. The staleness is ms. If the end-effector moves at m/s, the potential error is:
Why can a Cartesian command computed with become unsafe near a kinematic singularity even when the desired motion is small?
The backbone: a VLM you have already served
π₀'s backbone is PaliGemma (opens in a new tab): a SigLIP-So400m vision encoder (about 0.4 B parameters) feeding a Gemma-2B decoder-only LM (about 2.6 B). Each 224×224 camera image comes out of the vision tower as a 16×16 grid of patch embeddings — 256 soft tokens per view — projected into the LM's embedding space; the instruction ('fold the towel') is SentencePiece-tokenized and concatenated. No cross-attention module, no fusion network with a special name: one decoder-only transformer mixing image and text tokens in a single sequence, the standard multimodal-LLM layout you have served.
Multi-camera support falls out for free: a second view is just 256 more tokens. π₀'s configurations expect an exterior base camera plus wrist views, masking out whichever are missing — on your rig, one RealSense over the workspace plus one at the wrist. Size the prefix the way you would size any prompt:
Proprioception enters embarrassingly simply: joint positions plus gripper state pass through a learned linear projection and become a single token. The subtle part is routing. π₀ does not push state and action tokens through the Gemma weights — it adds a second, much smaller set of weights, the 300 M-parameter action expert, and routes by token type, mixture-of-experts style: image and text tokens use the VLM weights, state and action tokens use the expert, everything sharing one attention operation under a blockwise mask. The VLM's semantic knowledge reaches the actions through attention alone. Language conditioning is just prefix tokens: changing the prompt changes behavior the way it changes a chat model's answer.
Why bolt actions onto a VLM rather than train a control transformer from scratch? Data asymmetry. The largest robot-action corpora total on the order of hours — roughly timesteps at 50 Hz, which a frontier LLM pretraining cluster chews through in minutes. Every VLA is a bet that visual and semantic competence — what a towel is, where mug handles tend to be — transfers in from web-scale pretraining, so scarce robot data only has to teach motor behavior. That bet is the load-bearing assumption of this phase.
The action interface: four ways to get motion out of a token machine
Now the genuinely new part. Your arm needs actions that are continuous (7 real numbers: 6 joints plus gripper), high-rate (20–50 Hz), and multimodal — a mug can be grasped from the left or the right, and as you saw in Phase 03, averaging the two modes drives the gripper into the middle of the mug. A decoder-only LM natively emits one thing: a categorical distribution over discrete tokens. Every VLA architecture is one of four answers to that mismatch.
Direct regression pools the backbone's final hidden states through an MLP into a continuous chunk, trained with MSE. One forward pass — the fastest possible head — and completely blind to multimodality: MSE fits the conditional mean, and the mean of grasp-left and grasp-right is a collision. You built this head in Phase 03; it is the baseline every fancier head must beat under last lesson's protocol.
Discretized token bins are RT-2 (opens in a new tab)'s move, inherited by OpenVLA (opens in a new tab): chop each action dimension's range into 256 uniform bins, name each bin with a token (OpenVLA overwrites the 256 least-used tokens in the Llama-2 vocabulary), and let the LM emit actions as text. The elegance is real: actions become a language, so robot episodes and web VQA co-train under one cross-entropy loss; training inherits the maximally stable LM recipe; the categorical output represents multimodality exactly. Both costs are computable, so compute them.
First, quantization. A uniform quantizer with step commits an error distributed uniformly on ; its variance is , so the RMS error is . For a joint with range split into bins:
Push it through the lever arm: a base-yaw error displaces the end effector by roughly , and the WidowX AI reaches m:
Nine millimeters of worst-case fingertip error from one joint — nearly ten times the arm's 1 mm repeatability — is on the order of the tolerance for grasping small objects. Binned policies get away with it because closed-loop corrections absorb residual error, but it is a real ceiling on precision. The second cost bites harder. Autoregressive decoding is sequential in tokens, not timesteps:
import numpy as np
BINS = 256
H, D = 50, 7 # chunk length x action dims (6 joints + gripper)
LO, HI = -np.pi, np.pi # normalized per-dimension range, radians
# A smooth 1 s reach segment sampled at 50 Hz: sinusoidal joint sweep
t = np.linspace(0.0, 1.0, H)
chunk = 0.8 * np.sin(np.pi * t)[:, None] * np.linspace(0.3, 1.0, D)[None, :]
def tokenize(actions):
frac = (actions - LO) / (HI - LO) # map to [0, 1)
return np.clip((frac * BINS).astype(np.int64), 0, BINS - 1)
def detokenize(ids):
centers = (ids.astype(np.float64) + 0.5) / BINS # decode to bin centers
return centers * (HI - LO) + LO
ids = tokenize(chunk)
recon = detokenize(ids)
err = np.abs(recon - chunk)
rms = np.sqrt(np.mean((recon - chunk) ** 2))
print("tokens per chunk :", ids.size) # 350
print("max err (rad) : %.5f" % err.max()) # ~ (HI-LO)/512
print("rms err (rad) : %.5f" % rms) # ~ (HI-LO)/256/sqrt(12)
print("fingertip max (mm): %.1f" % (0.769 * err.max() * 1e3)) # WidowX AI reach
# Autoregressive cost model: one LM forward pass per token
T_TOK_MS = 6.0 # bf16 bandwidth floor for a 3B backbone (Lesson 3)
print("AR decode per chunk: %.0f ms vs chunk duration 1000 ms"
% (ids.size * T_TOK_MS))An RT-2-style head emits a 50-step, 7-dim chunk as 256-bin tokens, one token per LM forward pass at ~6 ms each. Roughly how long does one chunk take to decode, and why is that a structural problem?
Diffusion heads keep the backbone as a conditioner and generate the chunk by iterative denoising: start from Gaussian noise shaped like the chunk and apply a learned denoiser times. Diffusion Policy — which you weighed against ACT in Phase 03 — is the small-scale original; Octo (a 93 M-parameter open generalist) is the transformer-scale exemplar. Diffusion buys exact multimodality and continuous output with a stable regression-to-noise objective; the price is extra passes at inference, anywhere from 10 to 100 depending on the sampler.
Flow-matching experts are π₀'s refinement of the same idea, and the reason the next lesson exists. Instead of a stochastic denoising chain, the 300 M action expert learns a velocity field that transports noise to the action chunk along a deterministic ODE, integrated in about 10 fixed steps. All 50 actions are refined in parallel at every step; the VLM prefix is computed once, its KV cache reused across all 10 steps; the output is continuous — no bins, no quantization floor. What the velocity field is and why 10 steps suffice is next lesson's business. Today it is a black box with a known interface and a known cost.
| Head | Output form | Multimodality | Cost per chunk | Exemplars |
|---|---|---|---|---|
| Direct regression | MLP maps pooled features to a continuous chunk (MSE) | None — averages modes | 1 forward pass | Simple BC baselines (your Phase 03 MLP) |
| Discretized token bins | H × D tokens from a 256-bin vocabulary, decoded autoregressively | Full categorical per dimension | H × D sequential decode steps (350 for 50 × 7) | RT-2, OpenVLA |
| Diffusion head | Iterative denoising of the whole chunk | Samples the full distribution | K denoising passes, K ≈ 10–100 | Diffusion Policy, Octo |
| Flow-matching expert | ODE integration from noise to chunk via separate expert weights | Samples the full distribution | 1 VLM prefill + K ≈ 10 expert passes | π₀, GR00T N1 |
Cross-embodiment pretraining: what a million trajectories buy
The word 'pretrained' in every model above means the same thing structurally: a mixture over many robots. Open X-Embodiment (opens in a new tab) pooled roughly 60 datasets from 21 institutions — over 1 M trajectories, 22 embodiments, 500+ skills — into a common format, and a curated slice of it sits inside the training mixture of π₀, OpenVLA, and Octo alike. π₀ adds Physical Intelligence's own teleoperation corpus, roughly 10,000 hours across 7+ robot configurations — about robot timesteps, orders of magnitude below the token counts your LLM intuitions are calibrated on.
Ablations across these papers document what the mixture buys: pretrained-then-fine-tuned models beat from-scratch training by wide margins, most dramatically below ~10 hours of task demonstrations. Mechanistically, pretraining transfers what is true about manipulation in general — visual robustness to clutter and lighting, language grounding, object and affordance priors, the coarse temporal shape of reach-grasp-move-place. It is the robotics analogue of what web pretraining gives a code model: not your codebase, but fluency in the language it is written in.
What it cannot buy is your rig. The pretrained model has never seen your camera extrinsics, table height, lighting, controller gains, gripper closing speed, or your action convention — joint-space versus Cartesian, delta versus absolute; get that wrong and the policy is wrong in units, not in skill. The sharp version: BridgeData V2 (opens in a new tab), 60,000+ trajectories collected on WidowX-250 arms, is inside these training mixtures. Your WidowX AI is that arm's larger, stronger successor — same family, same joint-plus-gripper layout, but different kinematics and actuation — so your embodiment is a close cousin of the training data, not literally in it; and your rig certainly is not, so zero-shot behavior on your bench will range from comically bad to unsafe. Closing that gap with a few hours of your own demonstrations is the point of Lesson 4.
Scale reality: parameters, VRAM, and why chunks exist
Now the numbers that determine what runs on your desk. π₀: 0.4 B (SigLIP) + 2.6 B (Gemma) + 0.3 B (action expert) ≈ 3.3 B parameters. OpenVLA: 7 B-class. GR00T N1: about 2 B. RT-2 was 12 B to 55 B and ran at 1–3 Hz on multi-TPU cloud serving — it never lived on the robot. The field's retreat from 55 B to the 2–7 B class was not scientific modesty; it is the deployability constraint you would have predicted: the model has to fit and run on a workstation GPU physically near the arm.
VRAM at inference follows from your usual arithmetic: bf16 weights cost 2 bytes per parameter — about 6.6 GB for π₀, about 14 GB for OpenVLA — plus activations, a KV cache for a ~533-token prefix (small), and framework overhead. The OpenPI repository (opens in a new tab) quotes floors that match: over 8 GB for inference, over 22.5 GB for LoRA fine-tuning, over 70 GB for full fine-tuning. A 24 GB RTX 4090-class card serves π₀ comfortably, fits LoRA with modest headroom, and cannot touch full fine-tuning: Lesson 4 is a LoRA lesson by arithmetic, not by preference.
Latency is the harder constraint. One full π₀ inference — two vision-tower passes, a ~533-token prefill through 3 B parameters, ten flow-matching passes through the expert — lands on the order of 100 ms on a 4090-class GPU. One action per inference would cap you at ~10 Hz, every action at least 100 ms stale — your entire measured latency budget, gone before the arm moves. The escape is the decision that makes this model class deployable at all: emit a chunk. One inference produces actions consumed at 50 Hz, and feasibility is a one-liner:
Chunking converts an infeasible serving problem into a comfortable scheduling problem — the same move as batching, except the batch dimension is time. And like batching, it is paid for in staleness: the 50th action executes almost 1.1 s after the observation it was computed from. Apply the staleness formula from the time lesson, : at 0.25 m/s end-effector speed, a full-chunk-old prediction can be 250+ mm wrong if the scene changed. On a static tabletop nothing changed, which is why open-loop chunks work startlingly well in demos; add a human hand or a rolling object and chunk length becomes the reactivity bottleneck. Managing that tradeoff at serve time is your capstone's research question — and you now know where it lives in the architecture.
You keep π₀'s ~100 ms inference and 50 Hz control but shrink the chunk from H = 50 to H = 10 for reactivity. What is the main systems consequence?
The landscape, without the hype
The π₀ family (Physical Intelligence). π₀ (opens in a new tab) is the flow-matching architecture this lesson dissected; π₀-FAST swaps the decode for autoregressive tokens over a compressed action representation (Lesson 3); π₀.₅ pushes open-world generalization. Open: checkpoint weights, the JAX training and serving code in OpenPI, and a Trossen tutorial targeting exactly your WidowX AI — though its published examples are bimanual, so single-arm adaptations need your own validation. Not open: the ~10,000-hour dataset, and any way to independently rerun the headline evaluations, which live on their robots. The honest read: the strongest published manipulation results in this class — multi-stage laundry folding, table bussing — with claims you can verify only by fine-tuning on your own hardware, which is what this phase does.
OpenVLA. A 7 B Prismatic VLM — SigLIP and DINOv2 vision towers fused, Llama-2-7B decoder — trained on roughly 970 k OXE episodes with RT-2-style 256-bin action tokens. It is the fully open triad — weights, code, and training data all public — and it was evaluated on WidowX-250 arms in BridgeData V2 scenes — the predecessor of your WidowX AI, the closest published baseline to your arm's family. The honest read: unmatched openness, but the decode is the bottleneck — one 7-token action per step at roughly 6 Hz on a 4090, no chunking in the base recipe (follow-up variants add parallel decoding and chunked heads).
GR00T N1 (NVIDIA). An open foundation model aimed at humanoids: an Eagle-class VLM paired with a flow-matching diffusion-transformer action head, about 2 B parameters total — a slow System 2 (the VLM, around 10 Hz) feeding a fast System 1 (the action head, over 100 Hz). Weights and code (opens in a new tab) are open; the training mixture of real teleoperation, human video, and synthetic trajectories is only partially released. The honest read — house loyalty notwithstanding — is that its claims center on humanoid benchmarks and synthetic-data scaling, not WidowX-class tabletop manipulation: a later comparison branch, after OpenPI works on your arm.
| Model | Backbone and size | Action head | Weights | Code | Training data |
|---|---|---|---|---|---|
| π₀ (OpenPI) | PaliGemma 3 B + 0.3 B expert ≈ 3.3 B | Flow matching, H = 50 | Open | Open (JAX) | Closed (~10k h proprietary + OXE) |
| OpenVLA | Prismatic 7 B (SigLIP + DINOv2 → Llama-2) | 256-bin autoregressive tokens | Open | Open (PyTorch) | Open (OXE, ~970 k episodes) |
| GR00T N1 | Eagle-class VLM + DiT ≈ 2 B | Flow-matching diffusion transformer | Open | Open | Partial (synthetic released; full mixture not) |
Draft the I/O contract for a π₀-class policy on your rig
Before touching OpenPI, write the complete tensor-level interface for serving π₀ on your setup, on paper plus a few lines of numpy. (1) Count prefix tokens for two RealSense views at 224×224 plus instruction plus state. (2) Define state and action vectors for a WidowX AI (6 joints + gripper) and how they map into the checkpoint's wider padded action width. (3) Pick a chunk length and control rate and verify , using a measured forward time on your GPU or the 100 ms placeholder. (4) Estimate weights-only VRAM in bf16 and reconcile it against OpenPI's published inference floor.
Need a hint?
224/14 = 16, so 256 tokens per view. If your Trossen stack controls at 25 Hz rather than π₀'s native 50 Hz, a 50-step chunk covers 2 s — decide whether to shorten the chunk or accept the longer horizon, and say why in one sentence.
Where this goes next: the previous lesson, Evaluating policies: statistics you can defend, fixed the protocol every model in this phase will be judged by; this lesson gave you the anatomy — a VLM prefill you already know how to serve, plus an action decode that is the real design space. Next, Flow matching: how π₀ generates actions opens the one box left black today: the 300 M action expert, the velocity field it learns, and why ten integration steps buy a continuous, multimodal 50-action chunk for one prefill's worth of compute.