The AY-Robots Arena leaderboard showing a sortable table of 85 vision-language-action models with 332 benchmark results, including OpenVLA
OpenVLAVision-Language-ActionLoRA Fine-TuningSO-100Robot Learning

OpenVLA on a Low-Cost Arm: 7B Params, LoRA, and the SO-100

AY-Robots ResearchAugust 23, 202617 min read

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.

ComponentWhat OpenVLA uses
Parameters7 B (repo says "all 7.5 billion parameters"; paper counts 7,188.1 M trainable)
Language backboneLlama 2
Vision encoderDINOv2 ViT-L/14 and SigLIP ViT-So400M/14, features fused
Base VLMprism-dinosiglip-224px, from the Prismatic VLM codebase
Input imageOne 224 x 224 px third-person view. 384 px gave no gain for 3x the training time
Action output7 normalized end-effector deltas: x, y, z, roll, pitch, yaw, gripper
Action encoding256 bins per dimension, 1st to 99th quantile, mapped onto the last 256 Llama tokens
Pretraining data970 K demonstrations curated from Open X-Embodiment
Pretraining cost64 A100s for 14 days, 21,500 A100-hours, batch size 2048, 27 epochs, fixed LR 2e-5, no warmup
Code licenceMIT
Weights licenceDisputed. 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.
No SO-100 in the mixture

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.

StrategySuccess rateTrainable paramsVRAM at batch 16
Full fine-tuning69.7 +/- 7.2 %7,188.1 M163.3 GB (sharded over 2 GPUs with FSDP)
Last layer only30.3 +/- 6.1 %465.1 M51.4 GB
Frozen vision encoder47.0 +/- 6.9 %6,760.4 M156.2 GB (sharded)
Sandwich fine-tuning62.1 +/- 7.9 %914.2 M64.0 GB
LoRA, rank 3268.2 +/- 7.5 %97.6 M59.7 GB
LoRA, rank 6468.2 +/- 7.8 %195.2 M60.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 27 GB number is not the number you will hit

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.

The AY-Robots policies comparison table listing GR00T N1.7, GR00T N1.5, Pi0.5, SmolVLA and ACT with parameter counts, required GPU, inference latency and minimum episode counts
For contrast, the five policies AY-Robots actually trains. Every one of them reads a LeRobot dataset directly, which is exactly the step OpenVLA makes you do by hand.

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.

text
# 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
Six absolute joint targets and two cameras against seven end-effector deltas and one camera.
AxisLeRobot SO-100OpenVLACan you bridge it?
Action dimension67No. You change the action space and retrain the mapping.
Action spaceAbsolute joint positionsEnd-effector deltasOnly via inverse kinematics you write and calibrate yourself.
CamerasTypically two, including a wrist viewExactly one, third-personYou drop the wrist camera, a real loss on gripper-critical tasks.
Dataset formatLeRobot v2.1 or v3.0 parquetRLDS / TFDSYes, via a converter plus two files you edit in the repo.
Frameworklerobotopenvla repo, Prismatic lineageSeparate 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.

7.4 V, not 12 V

Unrelated to OpenVLA, but it ends a project faster than any VRAM error: the Feetech STS3215 bus servos in an SO-100 or SO-101 run at 7.4 V. Feeding them 12 V destroys them. Check the supply before powering the bus.

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.

  1. 1
    Build 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.

    bash
    conda 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"
  2. 2
    Get 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.

    bash
    cd <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
  3. 3
    Register 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.

    text
    prismatic/vla/datasets/rlds/oxe/configs.py     # add your dataset config
    prismatic/vla/datasets/rlds/oxe/transforms.py  # add your transform fn
  4. 4
    Launch 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.

    bash
    torchrun --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
  5. 5
    Serve 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.

    bash
    python vla-scripts/deploy.py \
      --openvla_path openvla/openvla-7b \
      --host 0.0.0.0 \
      --port 8000
  6. 6
    Un-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.

    python
    from 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.
When this is the right call

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.

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 7BGR00T N1.7SmolVLAACT
Parameters7 B~3 B, ~40 M trained~450 M~80 M
Per-step latency~167 ms (6 Hz, RTX 4090, bf16)152 ms245 ms20 ms
Fine-tuning hardware~72 GB at batch 16 (README), ~27 GB stated floorA100 or H100 80 GBRTX 4090 or any 24 GBRTX 4090 or any 24 GB
Reads LeRobot dataNo, RLDS onlyYes, v2.0 or v2.1Yes, v3.0Yes, v3.0
Native action space7 EE deltasjoint spacejoint spacejoint space
CamerasOnemultiplemultiplemultiple
Trainable on AY-RobotsNoYesYesYes
Read the latency row carefully

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.

The AY-Robots head to head comparison page for GR00T N1.7 against Pi0.5, showing parameter counts, latency, GPU tier and dataset format side by side
The same head-to-head framing applied to two models the platform trains, GR00T N1.7 against Pi0.5.
OpenVLA on a low-cost arm
Advantages
  • 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.
Trade-offs
  • 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 suiteDiffusion Policy from scratchOcto fine-tunedOpenVLA LoRA r32
Spatial78.3 +/- 1.1 %78.9 +/- 1.0 %84.7 +/- 0.9 %
Object92.5 +/- 0.7 %85.7 +/- 0.9 %88.4 +/- 0.8 %
Goal68.3 +/- 1.2 %84.6 +/- 0.9 %79.2 +/- 1.0 %
Long50.5 +/- 1.3 %51.1 +/- 1.3 %53.7 +/- 1.3 %
Average72.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 AY-Robots Arena leaderboard, a sortable table of 85 vision-language-action models with 332 benchmark results, each value linked to the paper or model card it came from
OpenVLA and OpenVLA-OFT both have entries in the Arena, where each benchmark number links back to its source.

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 Arena
Can 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.

Ready for high-quality robotics data?

AY-Robots connects your robots to skilled operators worldwide.

Get Started