
OpenVLA is 7B parameters with a contested weights licence. What LoRA fine-tuning really costs in VRAM, why its 7-DoF action space fights an SO-100, and what to run instead.
What you need to know
- •OpenVLA is a 7 B-parameter VLA: a Llama 2 backbone, a fused DINOv2 plus SigLIP vision encoder, trained on 970,000 real robot demonstrations from Open X-Embodiment.
- •LoRA at rank 32 matches full fine-tuning on the paper's Franka tasks (68.2% against 69.7%) while training 1.4% of the parameters. The paper finds LoRA rank has negligible effect and recommends r = 32 as the default.
- •The repo's LoRA example assumes a single A100 80 GB: batch 16 with no gradient accumulation costs about 72 GB. The stated floor is about 27 GB if you shrink the batch.
- •The hard part is not the GPU. OpenVLA emits seven end-effector deltas from one camera; a LeRobot SO-100 dataset carries six absolute joint targets and usually two cameras.
- •Inference is roughly 6 Hz on an RTX 4090 in bfloat16, needing 15 GB of GPU memory. The paper's int4 result (7.0 GB, 71.9% on Bridge against 71.3% for bfloat16) was measured on a smaller model variant, not the released 7B checkpoint.
- •Upstream has moved on: since 2025-03-03 the README points at OpenVLA-OFT, which lifts LIBERO from 76.5% to 97.1% and multiplies throughput by 26.
- •AY-Robots does not train OpenVLA. The five policies it does train already speak LeRobot format and joint-space actions.
What OpenVLA actually is
OpenVLA is what made vision-language-action models reproducible outside a large industrial lab. Before it the strong results belonged to RT-2-X, a closed 55 B-parameter model. OpenVLA published weights, training code and data mixture, and beat RT-2-X by 16.5 points of absolute task success across 29 tasks and multiple embodiments, with 7x fewer parameters.
Architecturally it is a vision-language model with the text head repurposed. An image and an instruction go in, and the model autoregressively emits action tokens. The trick is the tokenizer: each action dimension is discretized into 256 bins, with edges at the 1st and 99th quantile rather than the min and max, so outlier demonstrations cannot blow out the resolution of the action space. Those 256 values overwrite the 256 least-used tokens in the Llama vocabulary. No new head, no new loss.
| Component | What OpenVLA uses |
|---|---|
| Parameters | 7 B (repo says "all 7.5 billion parameters"; paper counts 7,188.1 M trainable) |
| Language backbone | Llama 2 |
| Vision encoder | DINOv2 ViT-L/14 and SigLIP ViT-So400M/14, features fused |
| Base VLM | prism-dinosiglip-224px, from the Prismatic VLM codebase |
| Input image | One 224 x 224 px third-person view. 384 px gave no gain for 3x the training time |
| Action output | 7 normalized end-effector deltas: x, y, z, roll, pitch, yaw, gripper |
| Action encoding | 256 bins per dimension, 1st to 99th quantile, mapped onto the last 256 Llama tokens |
| Pretraining data | 970 K demonstrations curated from Open X-Embodiment |
| Pretraining cost | 64 A100s for 14 days, 21,500 A100-hours, batch size 2048, 27 epochs, fixed LR 2e-5, no warmup |
| Code licence | MIT |
| Weights licence | Disputed. The model card says MIT for all checkpoints; the repo README says the models derive from Llama-2 and are subject to the Llama Community License |
What it was trained on, and what that excludes
The pretraining mixture decides whether OpenVLA has ever seen anything like your arm. It starts from Open X-Embodiment, which at the time held more than 70 robot datasets and over 2 M trajectories, then filters hard.
- Manipulation only. No navigation, no locomotion.
- At least one third-person camera in the dataset.
- Single-arm end-effector control. This is the filter that matters: joint-space datasets were excluded by construction.
- Mixture weights borrowed from Octo, which down-weights low-diversity datasets.
- DROID went in at 10% weight, then was pulled entirely for the final third of training because action token accuracy on it stayed low.
Open X-Embodiment predates the low-cost arm wave, and the single-arm end-effector filter would have removed joint-space SO-100 data anyway. The model card is blunt: OpenVLA models "do not zero-shot generalize to new (unseen) robot embodiments, or setups that are not represented in the pretraining mix". On an SO-100 it is not a zero-shot policy but an initialization you must fine-tune, and that pretraining used other robots' action spaces.
The fine-tuning bill, from the paper's own table
The paper compares five adaptation strategies on Franka-Tabletop tasks. It is the most useful table in the paper if you are budgeting a fine-tuning run. VRAM is at batch size 16.
| Strategy | Success rate | Trainable params | VRAM at batch 16 |
|---|---|---|---|
| Full fine-tuning | 69.7 +/- 7.2 % | 7,188.1 M | 163.3 GB (sharded over 2 GPUs with FSDP) |
| Last layer only | 30.3 +/- 6.1 % | 465.1 M | 51.4 GB |
| Frozen vision encoder | 47.0 +/- 6.9 % | 6,760.4 M | 156.2 GB (sharded) |
| Sandwich fine-tuning | 62.1 +/- 7.9 % | 914.2 M | 64.0 GB |
| LoRA, rank 32 | 68.2 +/- 7.5 % | 97.6 M | 59.7 GB |
| LoRA, rank 64 | 68.2 +/- 7.8 % | 195.2 M | 60.5 GB |
Two conclusions. Freezing the vision encoder is the one thing you must not do: it costs 22 points against full fine-tuning while still burning 156 GB, because the visual features genuinely need to adapt to your scene. And LoRA at rank 32 lands within 1.5 points of full fine-tuning while training 1.4% of the model. Full fine-tuning needs 8 A100s for 5 to 15 hours per task; LoRA needs one A100 for 10 to 15 hours, an 8x compute reduction.
The README says you can fine-tune "as long as it has at least ~27 GB of memory, by modifying the batch size". True, and also the sentence that eats a day. The documented configuration, --batch_size 16 with --grad_accumulation_steps 1, needs about 72 GB. To reach 27 GB you cut the batch hard, raise gradient accumulation to keep the effective batch stable, and drop shuffle_buffer_size from its default of 100,000, a documented OOM source on its own. A 24 GB consumer card is below the floor either way. Three numbers circulate for the same setup: Table 1 of the paper says 59.7 GB at batch 16, the README says about 72 GB, and the header comment in finetune.py says a 48 GB card fits batch 12 and an 80 GB card batch 24. Plan against the README. See out of memory during training.

Where OpenVLA and an SO-100 disagree
This section decides the question in the title, and it has nothing to do with parameter counts. Put a real public LeRobot SO-100 dataset schema next to what OpenVLA emits.
# lerobot/svla_so100_pickplace -> meta/info.json (codebase_version v3.0)
action [6] main_shoulder_pan, main_shoulder_lift,
main_elbow_flex, main_wrist_flex,
main_wrist_roll, main_gripper
observation.state [6] the same six joints
observation.images.top [480, 640, 3]
observation.images.wrist [480, 640, 3]
# openvla/openvla-7b
action [7] dx, dy, dz, droll, dpitch, dyaw, gripper
(normalized end-effector deltas)
image one 224 x 224 third-person view, and only one| Axis | LeRobot SO-100 | OpenVLA | Can you bridge it? |
|---|---|---|---|
| Action dimension | 6 | 7 | No. You change the action space and retrain the mapping. |
| Action space | Absolute joint positions | End-effector deltas | Only via inverse kinematics you write and calibrate yourself. |
| Cameras | Typically two, including a wrist view | Exactly one, third-person | You drop the wrist camera, a real loss on gripper-critical tasks. |
| Dataset format | LeRobot v2.1 or v3.0 parquet | RLDS / TFDS | Yes, via a converter plus two files you edit in the repo. |
| Framework | lerobot | openvla repo, Prismatic lineage | Separate stacks; lerobot has no OpenVLA policy. |
None of these are impossible. Together they mean you are not fine-tuning a model, you are porting one: convert every episode to RLDS, either relabel your LeRobot dataset into end-effector deltas or redefine the action space to six joints and accept that the pretrained action tokens no longer mean what they meant, drop the wrist camera, then write the end-effector to joint-command bridge for inference. That last piece has to be right or the policy will look broken when it is fine.
The imitation learning signal in your data is fine. The mismatch is plumbing and representation, which is why this takes weeks rather than an afternoon.
Running OpenVLA yourself, end to end
Here is the honest path, with the repo's real flags and defaults. It pins versions and means it: PyTorch 2.2.0, torchvision 0.17.0, transformers 4.40.1, tokenizers 0.19.1, timm 0.9.10, flash-attn 2.5.5.
- 1Build the pinned environment
Flash Attention 2 has to be installed without build isolation or it will fail to compile against your torch. The LoRA script additionally requires
peft==0.11.1.bashconda create -n openvla python=3.10 -y conda activate openvla conda install pytorch torchvision torchaudio pytorch-cuda=12.4 -c pytorch -c nvidia -y git clone https://github.com/openvla/openvla.git cd openvla pip install -e . pip install packaging ninja pip install "flash-attn==2.5.5" --no-build-isolation pip install "peft==0.11.1" - 2Get a dataset into RLDS
The README example uses BridgeData V2, a 124 GB download. Renaming is not optional; the loader finds the dataset by name.
bashcd <PATH TO BASE DATASETS DIR> wget -r -nH --cut-dirs=4 --reject="index.html*" \ https://rail.eecs.berkeley.edu/datasets/bridge_release/data/tfds/bridge_dataset/ # Required. Skipping this produces runtime errors later. mv bridge_dataset bridge_orig - 3Register your own data
Convert to RLDS with kpertsch/rlds_dataset_builder, then edit two files: a dataset config and a transform function mapping your columns onto the model's action layout. This is where the 6-versus-7 problem becomes code you write.
textprismatic/vla/datasets/rlds/oxe/configs.py # add your dataset config prismatic/vla/datasets/rlds/oxe/transforms.py # add your transform fn - 4Launch LoRA fine-tuning
These are the repo's documented values. finetune.py defaults that are easy to miss: max_steps 200000, save_steps 5000, image_aug True, shuffle_buffer_size 100000, lora_dropout 0.0, use_quantization False.
bashtorchrun --standalone --nnodes 1 --nproc-per-node 1 vla-scripts/finetune.py \ --vla_path "openvla/openvla-7b" \ --data_root_dir <PATH TO BASE DATASETS DIR> \ --dataset_name bridge_orig \ --run_root_dir <PATH TO LOG/CHECKPOINT DIR> \ --adapter_tmp_dir <PATH TO TEMPORARY ADAPTER DIR> \ --lora_rank 32 \ --batch_size 16 \ --grad_accumulation_steps 1 \ --learning_rate 5e-4 \ --image_aug True \ --save_steps 5000 - 5Serve the checkpoint
deploy.py exposes a REST endpoint; defaults are host 0.0.0.0 and port 8000. Your client posts an image plus an instruction and gets seven normalized deltas back, which you un-normalize and convert to joint commands yourself.
bashpython vla-scripts/deploy.py \ --openvla_path openvla/openvla-7b \ --host 0.0.0.0 \ --port 8000 - 6Un-normalize with the right key
Actions come back normalized against a specific dataset's statistics. Pass the unnorm_key for the dataset you fine-tuned on, or the numbers will be silently wrong rather than obviously wrong.
pythonfrom transformers import AutoModelForVision2Seq, AutoProcessor import torch processor = AutoProcessor.from_pretrained("openvla/openvla-7b", trust_remote_code=True) vla = AutoModelForVision2Seq.from_pretrained( "openvla/openvla-7b", attn_implementation="flash_attention_2", torch_dtype=torch.bfloat16, low_cpu_mem_usage=True, trust_remote_code=True, ).to("cuda:0") action = vla.predict_action(**inputs, unnorm_key="bridge_orig", do_sample=False)
Two routes to the same goal
You keep full control and own every failure. Budget for the conversion work, not the training.
- Rent a card with at least 27 GB, realistically 80 GB for the documented batch size.
- Convert your SO-100 episodes from LeRobot parquet to RLDS and register them in two source files.
- Settle the action space: relabel to end-effector deltas via forward kinematics, or redefine to six joints and lose alignment with the pretrained tokens.
- Discard the wrist camera, because OpenVLA takes exactly one image.
- LoRA fine-tune for 10 to 15 hours on a single A100.
- Write and calibrate the inference-side bridge from deltas back to joint commands.
If you are researching VLA adaptation itself, this is the correct path and the codebase is genuinely good. You are buying a research platform, not a shortcut to a working arm.
The platform does not train OpenVLA. What it removes is every step above, by using models that already speak your data format.
- Record with the desktop client from a teleoperation session: a LeRobot dataset with joint-space actions and every camera you plugged in.
- Pick one of five policies on the policies page, from ACT at ~80 M to GR00T N1.7 at ~3 B. No format conversion, no action-space surgery.
- The training form rents a spot GPU sized to the model's VRAM need and writes checkpoints to object storage.
- Inference pods auto-provision, carry an idle watchdog and destroy themselves, so nothing bills silently. See run your first policy.
- Same operations from the terminal via the CLI or from an agent via MCP.
A run on the 24 GB tier costs roughly 1 to 3 USD and takes 2 to 5 hours. The 80 GB tier is roughly 4 to 12 USD over 3 to 6 hours. SmolVLA on SO-100 is the closest thing to an OpenVLA-shaped experience that actually finishes, and GR00T N1.7 on SO-100 is the closest on capability.
How OpenVLA compares to what this platform trains
Latency first, because it is the number people get wrong. At bfloat16 on an RTX 4090 OpenVLA runs at roughly 6 Hz, which inverts to about 167 ms per action. That lands just above both GR00T figures, 152 ms for N1.7 and 165 ms for N1.5, and well ahead of Pi0.5 at 485 ms. OpenVLA is not slow for its class. It is memory-hungry and format-hostile, which is a different complaint.
| OpenVLA 7B | GR00T N1.7 | SmolVLA | ACT | |
|---|---|---|---|---|
| Parameters | 7 B | ~3 B, ~40 M trained | ~450 M | ~80 M |
| Per-step latency | ~167 ms (6 Hz, RTX 4090, bf16) | 152 ms | 245 ms | 20 ms |
| Fine-tuning hardware | ~72 GB at batch 16 (README), ~27 GB stated floor | A100 or H100 80 GB | RTX 4090 or any 24 GB | RTX 4090 or any 24 GB |
| Reads LeRobot data | No, RLDS only | Yes, v2.0 or v2.1 | Yes, v3.0 | Yes, v3.0 |
| Native action space | 7 EE deltas | joint space | joint space | joint space |
| Cameras | One | multiple | multiple | multiple |
| Trainable on AY-Robots | No | Yes | Yes | Yes |
OpenVLA's measured figure is 6 Hz on an RTX 4090, without compilation or speculative decoding; the 167 ms is that rate inverted. The platform figures are per action step on the tier each model runs on. Not the same measurement, so treat the ordering as informative and the decimals as not. Whatever the model, inference latency has to sit next to the servos for fast tasks. Remote inference over the public internet is viable for slow pick-and-place, not reactive motion.

- Fully open: MIT code, published weights, published data mixture, published ablations.
- LoRA rank 32 genuinely matches full fine-tuning at 1.4% of the trainable parameters.
- Int4 inference fits in 7.0 GB at 71.9% Bridge success against 71.3% for bfloat16, measured across 8 tasks and 80 rollouts on a smaller model variant.
- The codebase is readable and the paper documents what did not work.
- A remote REST inference server ships with the repo, so the robot side needs no large GPU.
- Seven end-effector deltas against an SO-100 commanded as six joint positions. This is the whole problem.
- Single image only, so you lose the wrist camera that carries most of the gripper signal.
- RLDS is mandatory for the supported path, so every LeRobot dataset needs converting and registering.
- The weights licence is contested: the Hugging Face model card says MIT for all checkpoints, the repo README points at the Llama Community License. Settle it before commercial use.
- No SO-100 class embodiment in pretraining, so you get an initialization rather than a zero-shot policy.
- The paper itself notes success rates typically below 90% on its own tasks.
- Last push 2025-03-23, and the README now recommends a different recipe.
OpenVLA-OFT changed the answer
If you are evaluating OpenVLA today you are evaluating two things, and the README says so. Since a note dated 2025-03-03 it recommends the Optimized Fine-Tuning recipe. OFT keeps the base model and changes four things: parallel decoding instead of autoregressive, action chunking, continuous actions instead of the 256-bin tokens, and an L1 regression objective instead of cross-entropy.
The effect is large. Average LIBERO success goes from 76.5% to 97.1%, and action generation throughput improves 26-fold. On a bimanual ALOHA setup the recipe beat Pi0 and RDT-1B fine-tuned with their own defaults, and beat Diffusion Policy and ACT trained from scratch by up to 15 points absolute. Three of those four changes are things the models on this platform's policies page already do by design: chunked, continuous actions with a regression or flow objective.
| LIBERO suite | Diffusion Policy from scratch | Octo fine-tuned | OpenVLA LoRA r32 |
|---|---|---|---|
| Spatial | 78.3 +/- 1.1 % | 78.9 +/- 1.0 % | 84.7 +/- 0.9 % |
| Object | 92.5 +/- 0.7 % | 85.7 +/- 0.9 % | 88.4 +/- 0.8 % |
| Goal | 68.3 +/- 1.2 % | 84.6 +/- 0.9 % | 79.2 +/- 1.0 % |
| Long | 50.5 +/- 1.3 % | 51.1 +/- 1.3 % | 53.7 +/- 1.3 % |
| Average | 72.4 +/- 0.7 % | 75.1 +/- 0.6 % | 76.5 +/- 0.6 % |
Read that honestly. These numbers are Appendix E.2, over 500 trials per suite and three seeds. OpenVLA takes both the best average success rate and the best average rank, 1.5, but Diffusion Policy from scratch beats it outright on LIBERO-Object, and every method is near 50% on the long-horizon suite. The paper attributes the narrow margins to OpenVLA being pretrained purely on real-world data with no simulation. It also lists the cleaning required first: no-op actions filtered out, images rotated 180 degrees, failed demonstrations removed, including 121 of 500 in LIBERO-Long, and wrist-camera images discarded for every method so the comparison matches OpenVLA's single third-person input.

The verdict for an SO-100 owner
OpenVLA is an important model and a good codebase. For a low-cost joint-space arm it is also the wrong tool for getting a task working, not because 7 B is too big or 167 ms too slow, but because the whole interface, from dataset format to action space to camera count, was built for a different family of robots.
- Studying VLA adaptation or tokenization: use OpenVLA, starting from the OFT recipe.
- Franka or WidowX data already in RLDS with end-effector control: OpenVLA is a strong initialization and LoRA rank 32 is cheap.
- An SO-100 and a LeRobot dataset, and you want a working policy: use a model that reads it natively. Start with training your first policy.
- Fewer than 50 episodes: SmolVLA accepts 30, and collecting better data beats changing models.
- Want data rather than an opinion: the Arena carries 85 models and 332 benchmark results.
For background, read vision-language-action models and the complete SO-100 setup guide. What a run costs is on pricing, and the training form is documented in the training docs.
85 VLA models, 332 benchmark results, every number sourced
OpenVLA, OpenVLA-OFT, GR00T, Pi0.5, SmolVLA and 80 more in one sortable table. Each value links back to the paper or model card it came from.
Open the ArenaCan I fine-tune OpenVLA directly on my SO-100 LeRobot dataset?▾
Not directly. The supported path reads RLDS, not LeRobot parquet, so you convert the dataset and register it in two files inside the repo. Beyond format, OpenVLA predicts seven end-effector deltas while a LeRobot SO-100 dataset stores six absolute joint targets, so you must either relabel through forward kinematics or redefine the action space and lose alignment with the pretrained action tokens. lerobot has no OpenVLA policy.
What GPU do I need for OpenVLA LoRA fine-tuning?▾
The documented example uses a single A100 with 80 GB. Batch size 16 with gradient accumulation 1 needs about 72 GB. The stated minimum is around 27 GB if you reduce the batch, raise gradient accumulation to compensate and lower shuffle_buffer_size from 100,000. A 24 GB card is below the floor. Full fine-tuning needs a node of 8 A100s.
Is OpenVLA free for commercial use?▾
The code in the openvla repository is MIT licensed. The weights are a separate question. The Hugging Face model card lists its licence field as mit, while the repository README states that the pretrained models are derived from Llama-2 and are therefore subject to the Llama Community License. Those two statements are not the same, so read the Llama Community License terms before shipping the weights in a product.
How fast is OpenVLA at inference?▾
About 6 Hz on one RTX 4090 in bfloat16 with no compilation or speculative decoding, roughly 167 ms per action step, needing 15 GB of GPU memory. The quantization table was run on a smaller model variant, not the released 7B: int4 there needs 7.0 GB and scores 71.9 percent on Bridge against 71.3 percent for bfloat16, at 3 Hz on the A5000 used for those evaluations. Int8 is the one to avoid: 58.1 percent and only 1.2 Hz on the same card.
Is OpenVLA still the model to pick in 2026?▾
As a research base yes, but start from OpenVLA-OFT rather than the original recipe. OFT lifts average LIBERO success from 76.5 to 97.1 percent and multiplies throughput by 26 using parallel decoding, action chunking, continuous actions and an L1 objective. The original repo's last push was 2025-03-23.
Does AY-Robots train OpenVLA?▾
No. The platform trains GR00T N1.7, GR00T N1.5, Pi0.5, SmolVLA and ACT. All five read LeRobot datasets and joint-space actions directly, which removes the conversion and action-space work OpenVLA requires on an SO-100. If you specifically need OpenVLA, follow the manual path in this article.
Sources
- OpenVLA: An Open-Source Vision-Language-Action Model (Kim et al., arXiv 2406.09246, v3 2024-09-05)
- openvla/openvla GitHub repository (README and vla-scripts, state of 2025-03-23)
- openvla/openvla-7b model card on Hugging Face
- openvla/openvla-7b-prismatic, the checkpoint required for full fine-tuning
- Fine-Tuning Vision-Language-Action Models: Optimizing Speed and Success (OpenVLA-OFT, arXiv 2502.19645)
- OpenVLA-OFT project page
- moojink/openvla-oft, the OFT implementation
- OpenVLA project page
- Open X-Embodiment: Robotic Learning Datasets and RT-X Models
- LoRA: Low-Rank Adaptation of Large Language Models (Hu et al.)
- LIBERO benchmark project page
- kpertsch/rlds_dataset_builder, the recommended RLDS conversion path
- BridgeData V2
- TRI-ML/prismatic-vlms, the VLM codebase OpenVLA is built on
- huggingface/lerobot, whose policy list contains no OpenVLA entry
Sources
- OpenVLA: An Open-Source Vision-Language-Action Model (Kim et al., arXiv 2406.09246, v3 2024-09-05)
- openvla/openvla GitHub repository (README and vla-scripts, state of 2025-03-23)
- openvla/openvla-7b model card on Hugging Face
- openvla/openvla-7b-prismatic, the checkpoint required for full fine-tuning
- Fine-Tuning Vision-Language-Action Models: Optimizing Speed and Success (OpenVLA-OFT, arXiv 2502.19645)
- OpenVLA-OFT project page
- moojink/openvla-oft, the OFT implementation
- OpenVLA project page
- Open X-Embodiment: Robotic Learning Datasets and RT-X Models
- LoRA: Low-Rank Adaptation of Large Language Models (Hu et al.)
- LIBERO benchmark project page
- kpertsch/rlds_dataset_builder, the recommended RLDS conversion path
- BridgeData V2
- TRI-ML/prismatic-vlms, the VLM codebase OpenVLA is built on
- huggingface/lerobot, whose policy list contains no OpenVLA entry
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started