The AY-Robots try page showing three ways to start without owning a robot: drive a real arm in the browser, compare models, or rent a GPU by the hour
VLA inferenceRTX 4090GPU memoryrobot policiesquantisation

Running a VLA Policy on a 4090: What Fits in 24 GB

AY-Robots ResearchAugust 23, 202619 min read

Which vision-language-action policies fit on a 24 GB RTX 4090 at inference, measured latency per action step, what quantisation really buys, and which models stay out of reach.

What actually fits in 24 GB

  • Inference is mostly solved on a 4090. openpi names the RTX 4090 as its example card for Pi0 and Pi0.5 at over 8 GB. NVIDIA lists it as a valid GR00T N1.7 inference GPU at 16 GB or more. OpenVLA 7B needs about 15 GB in bfloat16.
  • Fine-tuning is where 24 GB runs out: GR00T N1.7 wants 40 GB or more, a full Pi0 fine-tune over 70 GB, OpenVLA LoRA roughly 27 GB.
  • The best public measurement on this card is Table I of the Pi0 paper: 73 ms per action chunk on-board with three cameras, 86 ms off-board.
  • OpenVLA runs at about 6 Hz on a 4090 in bfloat16. 4-bit cuts it to 7.0 GB with no measured loss. 8-bit is a trap: slower, and the slowness alone cost 13 points of success rate.
  • Out of reach: RT-2-PaLI-X-55B and any full fine-tune of a 3B-class VLA. On AY-Robots, SmolVLA and ACT are the 24 GB tier; GR00T N1.7 and Pi0.5 are cloud-only.

What 24 GB actually buys you

The RTX 4090 is the card most people mean when they say consumer GPU. For anyone running a vision-language-action model next to a robot arm on their own desk, the only spec that decides anything is the 24. Compute headroom is generous. Memory is the wall.

SpecGeForce RTX 4090Why it matters here
Memory24 GB GDDR6XThe hard ceiling. Weights, activations and CUDA context must all fit.
Memory interface384-bitWide enough that a 3B model is compute-bound, not starved.
CUDA cores16384Rarely the limiting factor for a single-robot control loop.
Total graphics power450 WSustained inference next to an arm means sustained heat and fan noise.
Required system PSU850 WNVIDIA's own minimum, before the rest of the build.

Those figures are NVIDIA's own, from the RTX 4090 product page. Three things compete for the 24 GB during inference: model weights, activations for the forward pass, and whatever else your machine already has on that GPU. The last is not a rounding error. A CUDA context costs a few hundred megabytes before you load anything, and a desktop with a browser open can hold a gigabyte or two.

Weights are not the footprint

The OpenVLA paper shows the gap cleanly. The text says the model requires 15 GB of GPU memory when loaded in bfloat16; Table 2 reports a measured 16.8 GB for the same configuration. That 1.8 GB is activations, image-encoder buffers and runtime overhead. A model card that says 16 GB leaves you headroom on a 24 GB card. One that says 22 GB does not.

Model by model: what fits at inference

Every figure below comes from a model card, a repository README or a paper read for this article in August 2026, and the source column says which. Nothing is extrapolated from parameter counts.

ModelParamsStated inference footprintSource24 GB?
ACT~80 MNot separately published; trained in ~5 h on an 11 GB 2080 TiALOHA/ACT paperTrivially
SmolVLA450 M~2 GBLeRobot async guideTrivially
Pi03.3 B (3 B PaliGemma + 300 M expert)14 GB (LeRobot); >8 GB (openpi)LeRobot docs, openpiYes
Pi0.5~3 B, PaliGemma backbone>8 GB, RTX 4090 named as the example cardopenpi READMEYes
GR00T N1.7~3 B (Cosmos-Reason2-2B backbone)16 GB+ minimum, RTX 4090 listed by nameIsaac-GR00T READMEYes, less headroom
OpenVLA7 B (Llama 2 based)15 GB weights / 16.8 GB measured bf16; 10.2 GB int8; 7.0 GB int4OpenVLA paper, Table 2Yes in bf16
RT-2-PaLI-X55 BNot released; served on a multi-TPU cloud service at 1-3 HzRT-2 paperNo

The pattern runs against the intuition people bring from LLM work. The current generation of open robot policies is small. A 3B VLA in bfloat16 is roughly 6 GB of weights. The 7B autoregressive generation, of which OpenVLA is the reference, is the largest thing you can realistically serve, and even that fits. If a policy does not fit on a 4090 today, it is usually because it was never released.

The AY-Robots policies page showing a comparison table of five trainable policies with parameter counts, required GPU, inference latency and minimum episode counts
The five policies AY-Robots can train, with the GPU tier and per-step latency each needs. SmolVLA and ACT are the 24 GB tier.

Measured latency on a real 4090

Most VRAM tables stop at whether a model loads. What decides whether your arm moves smoothly is how long a forward pass takes, and there is one published measurement on exactly this card. Appendix D of the Pi0 paper gives the per-component breakdown in Table I, timed with three camera images on a GeForce RTX 4090.

Model partInference time
Image encoders14 ms
Observation forward pass32 ms
10x action forward pass (flow matching)27 ms
Network latency, if off-board13 ms
Total on-board inference73 ms
Total off-board inference86 ms

73 ms is roughly 13.7 replans per second, which sounds far too slow for a 50 Hz arm. It would be, except that a flow matching policy emits a chunk, not one action. The Pi0 authors run inference every 0.5 seconds on their 50 Hz robots, after executing 25 actions, and every 0.8 seconds on the 20 Hz UR5e and Franka setups. They tried temporal ensembling of overlapping chunks, found it hurt, and execute chunks open-loop instead.

Chunking is what makes 73 ms usable

A policy that predicts a chunk of actions decouples the model rate from the robot rate. NVIDIA says the same in the Isaac-GR00T guide: a ~10 Hz inference rate can sustain ~30 FPS execution via action chunking. A policy that emits one action per forward pass, like OpenVLA, gets no such discount.

OpenVLA is the counter-example. The paper states it runs at approximately 6 Hz on one NVIDIA RTX 4090 without compilation or speculative decoding, and the repository's data-collection advice follows directly: collect at 5 to 10 Hz, and if your robot uses a 50 Hz controller, downsample to 5 Hz first and check the task is still solvable. That is a constraint on which tasks you can attempt.

For GR00T N1.7, NVIDIA publishes an end-to-end inference frequency table measured with four denoising steps and one camera. There is no RTX 4090 row in it, which is worth stating plainly rather than interpolating. The nearest workstation-class datapoints:

PlatformVRAMPyTorch eagerWith TensorRT
H100 80GB HBM380 GB11.7 Hz35.9 Hz
RTX Pro 6000 Blackwell96 GB12.8 Hz35.9 Hz
RTX Pro 500072 GB7.9 Hz24.7 Hz
L4048 GB7.8 Hz26.0 Hz
DGX Spark128 GB shared7.9 Hz10.1 Hz
Jetson AGX Thor128 GB shared8.9 Hz12.4 Hz
Jetson Orin64 GB shared2.9 Hz6.6 Hz

The interesting part is not the top row. An H100 in plain PyTorch eager mode manages only 11.7 Hz, because the action head dominates: NVIDIA's H100 breakdown splits 85.8 ms into 6.2 ms of data processing, 31.3 ms of backbone and 48.2 ms of action head. torch.compile takes the action head to 12.0 ms and the total to 48.6 ms; a full TensorRT pipeline reaches 27.9 ms. NVIDIA puts torch.compile at 1.1 to 1.9x and a full TensorRT pipeline at 1.5 to 3.3x over eager across every platform it tested, so serving GR00T without compiling leaves a large part of the speed on the floor whatever the card.

The 8-bit trap, and why it is a latency story

OpenVLA's quantisation table looks wrong at first glance: bfloat16 scores 71.3 +/- 4.8% on BridgeData V2, int8 58.1 +/- 5.1%, int4 71.9 +/- 4.7%. Worse at 8 bits than at 4. The paper's explanation is the lesson of this whole article: 8-bit slowed inference down, to 1.2 Hz on the evaluation GPU against a 5 Hz non-blocking controller, while 4-bit ran at 3 Hz. Offline token accuracy was comparable across all three, so the 13-point drop came from system dynamics, not numerical error.

Quantisation: what it buys, what it costs

A 3B VLA already fits in 24 GB, so quantisation on a 4090 is a narrow tool: serving the 7B autoregressive class with room left over, or squeezing a policy onto a smaller card. Here is what OpenVLA measured.

PrecisionVRAMBridgeData V2 successVerdict on a 4090
bfloat1616.8 GB71.3 +/- 4.8%Fits with ~7 GB spare. The default.
int810.2 GB58.1 +/- 5.1%Avoid. Slower than bf16, and the slowness costs success.
int47.0 GB71.9 +/- 4.7%Useful if you need the memory back.

The mechanics are ordinary Hugging Face. The flags live in BitsAndBytesConfig, and for a robot policy you want NF4 with a bfloat16 compute dtype so the matmuls stay fast.

python
import torch
from transformers import AutoModelForVision2Seq, AutoProcessor, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

processor = AutoProcessor.from_pretrained("openvla/openvla-7b", trust_remote_code=True)
vla = AutoModelForVision2Seq.from_pretrained(
    "openvla/openvla-7b",
    quantization_config=quantization_config,
    low_cpu_mem_usage=True,
    trust_remote_code=True,
)

print(vla.get_memory_footprint())
4-bit NF4 loading, from the Transformers bitsandbytes documentation. Verify the numbers on your own card before trusting them on a robot.
Quantising a VLA for a 24 GB card
Advantages
  • 4-bit more than halves a 7B policy, 16.8 GB to 7.0 GB, with no measured success-rate loss in the OpenVLA evaluation.
  • On Ada Lovelace cards, reduced memory traffic partly pays back the dequantisation overhead, so int4 throughput beats int8.
  • Frees VRAM for a second camera pipeline, a vision model or a simulator on the same card. Double quantisation saves a further ~0.4 bits per parameter.
Trade-offs
  • int8 is slower than bfloat16 on most GPUs, which is what the OpenVLA authors measured. In a control loop that is a regression, not a saving.
  • Quantisation changes numerics, so a policy you validated in bfloat16 is a different policy afterwards. Re-run your evaluation episodes.
  • It does nothing for the models that actually strain a 4090, because those strain it during training.

What is genuinely out of reach on 24 GB

Almost nothing in the current open ecosystem is too large to serve on a 4090. Plenty is too large to train on one. That is where the disappointment comes from: people read a model card that says 16 GB and assume it covers fine-tuning too.

TaskVRAM neededSourceOn a 24 GB card
ACT from scratch, batch 8, AdamW~2 to 6 GBLeRobot hardware guideComfortable
SmolVLA fine-tune, batch 8, AdamW~10 to 16 GBLeRobot hardware guideComfortable
Pi0 / Pi0.5 LoRA>22.5 GB; RTX 4090 is the example cardopenpi READMEInside the envelope, practically miserable
Pi0 / Pi0.5 full fine-tune>70 GBopenpi READMENo
OpenVLA LoRA, rank 32~27 GB minimumOpenVLA repoNot without cutting batch size
GR00T N1.7 default fine-tune (projector + DiT head)Peak under ~35 GB, 40 GB+ minimumIsaac-GR00T guideNo
GR00T N1.7 with --tune-llm or --tune-visual80 GB+ per GPUIsaac-GR00T guideNo
RT-2-PaLI-X-55B, anythingWeights not public, multi-TPU serviceRT-2 paperNo, and not for VRAM reasons

LeRobot's own compute guide is blunt about where a consumer card sits: RTX 3090 and 4090 are comfortable for light behaviour cloning, diffusion policies and SmolVLA, and tight for VLAs at batch 1. A Pi0.5 LoRA run at over 22.5 GB on a 24 GB card leaves under 1.5 GB for the dataloader, the CUDA context and fragmentation. It runs until one image batch is slightly larger than usual. The out-of-memory during training page covers the escape routes.

GR00T needs a gated Hugging Face repo before it loads anything

This one eats a day. GR00T N1.7's VLM backbone is nvidia/Cosmos-Reason2-2B, and the Isaac-GR00T README states it is a gated model that every GR00T checkpoint, including the base nvidia/GR00T-N1.7-3B, loads on first use. Without access, loading fails with a GatedRepoError or a bare 401 Client Error. Request access and run huggingface-cli login before you debug your CUDA install.

The manual path: SmolVLA on a 4090 next to an SO-100

This is the configuration that makes sense on a 24 GB card in 2026: a small SmolVLA policy served from the GPU box, driving an SO-100 over USB. SmolVLA is 450 M parameters on SmolVLM-2, limited to 64 visual tokens per frame with no image tiling, and skipping half the VLM layers (the action expert reads features up to layer N = L/2). That is why it lands at ~2 GB instead of 14.

  1. 1
    Install LeRobot with the async extras

    The async inference stack is an optional dependency group. Install it now, not after your first server refuses to start.

    bash
    pip install lerobot
    lerobot-info
    
    # from a clone, for the async inference server and client:
    pip install -e ".[async]"
    pip install -e ".[smolvla]"
  2. 2
    Fine-tune smolvla_base on your own episodes

    SmolVLA is a base model, so it needs your task. The LeRobot docs recommend ~50 episodes and note that 25 was not enough in their own experiments. Twenty thousand steps takes roughly 4 hours on an A100, so budget longer on a 4090 and lower the batch size until it fits.

    bash
    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 \
      --wandb.enable=true
  3. 3
    Start the policy server on the 4090 box

    The server starts empty and learns which policy to load during the first handshake, so there is no model path here.

    bash
    python -m lerobot.async_inference.policy_server \
      --host=127.0.0.1 \
      --port=8080
  4. 4
    Start the robot client next to the arm

    The client owns the serial port, the cameras and the action queue. It streams observations over gRPC and executes chunks as they arrive.

    bash
    python -m lerobot.async_inference.robot_client \
      --server_address=127.0.0.1:8080 \
      --robot.type=so100_follower \
      --robot.port=/dev/ttyACM0 \
      --robot.id=follower_so100 \
      --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30} }" \
      --task="Grasp a lego block and put it in the bin." \
      --policy_type=smolvla \
      --pretrained_name_or_path=${HF_USER}/my_smolvla \
      --policy_device=cuda \
      --actions_per_chunk=50 \
      --chunk_size_threshold=0.5 \
      --aggregate_fn_name=weighted_average \
      --debug_visualize_queue_size=True
  5. 5
    Tune the queue until it never empties

    chunk_size_threshold decides when the client sends a fresh observation. Near 0.0 it collapses to synchronous inference and the arm stalls at every chunk boundary; near 1.0 it saturates the GPU. The LeRobot blog reports g ~ 0.7, the tutorial suggests 0.5 to 0.6. Watch the plotted queue and keep it above zero.

    bash
    # rerun the client with the queue plot on, and vary one number:
    --chunk_size_threshold=0.5   # more sequential, lower GPU load
    --chunk_size_threshold=0.7   # LeRobot's reported sweet spot
    --chunk_size_threshold=0.9   # near-continuous replanning, high load
  6. 6
    Run the policy without the async stack, if you prefer

    For a first smoke test, lerobot-rollout drives the arm directly. The commented RTC flags switch on real-time chunking, for when the inference machine is weaker than a 4090.

    bash
    lerobot-rollout \
      --strategy.type=base \
      --robot.type=so101_follower \
      --robot.port=/dev/ttyACM0 \
      --robot.id=my_blue_follower_arm \
      --robot.cameras="{ front: {type: opencv, index_or_path: 8, width: 640, height: 480, fps: 30}}" \
      --task="Grasp a lego block and put it in the bin." \
      --policy.path=${HF_USER}/my_smolvla
      # --inference.type=rtc
      # --inference.rtc.execution_horizon=10
Before you plug anything in: 7.4 V, not 12 V

The GPU is the expensive part of this bench; the servos are the fragile part. The SO-100 and SO-101 use Feetech STS3215 bus servos at 7.4 V, and 12 V destroys them. The Koch v1.1 uses Dynamixel servos on 5 V and 12 V rails and the LeKiwi runs a 7.4 V arm on a 12 V base, so two arms on one bench means two supply voltages. Label the bricks.

Two ways to get a policy running

You can own the whole stack or rent the annoying parts. The difference is whether you want to spend your evenings on CUDA versions or on episodes.

You buy a 4090, install LeRobot, and everything above runs on your own hardware. Training an ACT policy on ~45k frames takes roughly 30 to 60 minutes on a 4090 by LeRobot's own guide. Inference is then free forever and the control loop never leaves the room.

  • One RTX 4090 or 3090 plus the 850 W system power NVIDIA asks for, bought once instead of rented by the hour.
  • You handle CUDA 12.x, PyTorch, flash-attn builds, driver mismatches and gated Hugging Face repos yourself.
  • GR00T N1.7 and Pi0.5 serve on your card but cannot be fine-tuned on it. Those runs need 40 GB or more.
  • Zero marginal cost per run, which matters once you iterate on twenty variants of a dataset.
The realistic local ceiling

On one 24 GB card you can train ACT and SmolVLA, and serve ACT, SmolVLA, Pi0, Pi0.5 and GR00T N1.7. You cannot train the 3B-class models, and no amount of gradient checkpointing moves that line far.

Where a 4090 stops helping

A fast card does not fix a slow link. On this platform the control loop runs at 20 to 485 ms per action step depending on the model, and that is the budget the whole system fits inside. Adding a public-internet round trip to a 245 ms SmolVLA step or a 485 ms Pi0.5 step turns a working policy into a hesitant one. Remote inference is viable for slow pick-and-place, not for fast reactive motion.

PolicyInference per action step (AY-Robots)GPU tier hereMinimum episodes
ACT20 msRTX 4090 or any 24 GB card50
GR00T N1.7152 msA100 80 GB or H100 80 GB50
GR00T N1.5165 msA100 80 GB or H100 80 GB50
SmolVLA245 msRTX 4090 or any 24 GB card30
Pi0.5485 msA100 80 GB or H100 80 GB50

The LeRobot team measured sub-100 ms round-trip latency hosting SmolVLA on an RTX 4090 over their own local network, with roughly a 2x speedup in task completion from async inference at comparable success. Both halves matter: the 2x comes from never idling, the sub-100 ms from the network being a switch away.

Put the inference next to the servos

A cloud pod adds a wide-area round trip on top of the model's own step time, and for a 20 ms ACT policy that round trip is the dominant term by an order of magnitude. If the arm hesitates, stutters or overshoots, look at the link before you blame the checkpoint. The policy freezes mid-motion page covers the symptoms.

The AY-Robots CLI page showing the install command and the run commands for training and inference from a terminal
The CLI exposes the same operations as the web forms, which is what you want when scripting a sweep over batch sizes on a local 4090.

If you script this, the CLI and the MCP server expose the same operations, so an agent can start a run, poll it and fetch a checkpoint without a browser. Useful for launching five variants of the same LeRobot dataset rather than clicking through five forms.

The AY-Robots MCP server page listing the operations exposed to AI agents, the same ones available through the web interface and the CLI
The MCP page. The same train, inference and dataset operations, addressable by an agent.

A decision rule that survives contact

Pick the smallest policy that solves your task. On a 24 GB card the cost of being wrong about size is paid at training time, not serving time.

  1. One task, fixed cameras, no language: ACT. 80 M parameters, 20 ms per step here, trains locally in under an hour. No base model, so it only exists after you train it.
  2. Language instructions and some generalisation: SmolVLA. 450 M parameters, ~2 GB at inference, 30 episodes minimum, still comfortably local.
  3. Pretrained world knowledge of a 3B foundation model: GR00T N1.7 or Pi0.5. Both serve on a 4090; neither fine-tunes on one.
  4. Compare first: ACT against SmolVLA, GR00T N1.7 against Pi0.5, or the Arena with 85 VLA models and 332 benchmark results.

If you do not own an arm yet, the ordering flips: record data first, worry about the GPU second. The data collection guide is a better use of a weekend than a driver upgrade, the desktop client records LeRobot-format datasets from a teleop session, and the dataset directory has material to test the pipeline against first.

No 4090, no arm, no problem

Drive a real SO-100 in the browser with no signup, compare the five trainable policies on real numbers, or rent a GPU by the hour instead of buying one.

Start without hardware
Can I run GR00T N1.7 inference on an RTX 4090?

Yes. The Isaac-GR00T docs list the RTX 4090 by name against the minimum inference requirement of one GPU with 16 GB or more of VRAM and CUDA 12.6+. NVIDIA publishes no RTX 4090 row in its inference frequency table, so there is no official Hz figure for that card; the nearest workstation datapoints are the RTX Pro 5000 at 7.9 Hz eager and the L40 at 7.8 Hz. Fine-tuning is the part you cannot do on a 4090, which needs 40 GB or more.

How much VRAM does Pi0.5 need at inference?

The openpi requirements table gives over 8 GB for inference and names the RTX 4090 as the example GPU. LeRobot's async guide reports 14 GB for Pi0 at inference, the safer number to budget against. Both fit in 24 GB. LoRA fine-tuning is listed at over 22.5 GB, again with the RTX 4090 as the example card, which is inside the envelope with almost no headroom.

Is 4-bit quantisation safe for a robot policy?

In the one published controlled comparison, yes. OpenVLA's int4 scored 71.9 +/- 4.7% on BridgeData V2 against 71.3 +/- 4.8% for bfloat16, at 7.0 GB instead of 16.8 GB. int8 is the one to avoid at 58.1 +/- 5.1%, with the authors attributing the drop to inference slowing to 1.2 Hz against a 5 Hz controller rather than to numerical error.

What is the fastest VLA I can actually run on a 4090?

Among the VLAs proper, the Pi0 paper's RTX 4090 measurement gives 73 ms per chunk on-board with three cameras. SmolVLA is 450 M parameters and about 2 GB, and the LeRobot team measured sub-100 ms round trips serving it from a 4090 on a local network. ACT at around 80 M parameters is in a different class again: the ALOHA work ran teleoperation and recording at 50 Hz, and AY-Robots lists 20 ms per action step.

Does quantisation help me fine-tune a 3B VLA on 24 GB?

Not enough to change the answer. The Isaac-GR00T guide puts default fine-tuning, which tunes only the projector and diffusion action head, at a peak under about 35 GB per GPU against a stated 40 GB+ minimum, and 80 GB or more once --tune-llm or --tune-visual is on. openpi puts a full Pi0 fine-tune above 70 GB. Rent an A100 or H100 instead: on AY-Robots that tier runs 1.20 to 2.00 USD per hour, about 4 to 12 USD per run.

Ready for high-quality robotics data?

AY-Robots connects your robots to skilled operators worldwide.

Get Started