The AY-Robots /try page showing three ways to start without owning a robot: drive a real arm, compare models, rent a GPU
QuantisationEdge InferenceTensorRTVLA DeploymentJetson

Quantisation for On-Robot Inference: INT8, FP8 and What It Costs

AY-Robots ResearchAugust 23, 202617 min read

INT8 and FP8 next to the servos: what quantisation saves in memory, what it costs in success rate, which runtimes support it, and why 8-bit VLA inference is often slower than 16-bit.

Quantisation is the first thing people reach for when a vision-language-action model is too slow on the robot, and the thing most often misread. Cutting weights from 16 bits to 8 does halve the memory. It does not reliably halve the latency, and on the best-measured VLA in public it cost thirteen points of task success while the arithmetic stayed accurate. The failure was not numerical. The policy got slower and stopped matching the control rate it was trained at.

What follows is what INT8 and FP8 cost and save next to the servos: which formats need which silicon, which runtimes will build a quantised engine for a VLA today, and where quantisation is simply the wrong lever. Search note: the American spelling is quantization, and every flag name below uses it.

What you need to know

  • Quantisation buys memory first, throughput second. OpenVLA-7B measures 16.8 GB in bfloat16, 10.2 GB in int8, 7.0 GB in int4.
  • 8-bit is the trap. In the OpenVLA paper the BridgeData V2 success rate fell from 71.3 to 58.1 percent at int8, while int4 held at 71.9 percent. The cause was speed, not rounding.
  • FP8 needs compute capability 8.9 or newer. Jetson Orin is Ampere: INT8 yes, FP8 no. Jetson Thor is Blackwell: FP8 and FP4.
  • NVIDIA's own TensorRT path for GR00T N1.7 is bf16 only. Its 2.35x speedup on Orin comes from graph compilation, not lower precision.
  • On AY-Robots the policy is served from a rented cloud GPU with headroom, so quantisation is not the lever that fixes control latency. Distance to the arm is.

The formats, and what silicon each one needs

A quantised tensor is a low-precision value plus a scale. TensorRT's scheme is symmetric: values are stored as signed INT8, FP8E4M3, signed INT4 or FP4E2M1, converting back is one multiply, and rounding is round-to-nearest ties-to-even with a clamp. The two FP8 encodings come from the FP8 Formats for Deep Learning paper: E4M3 spends four exponent bits and three mantissa bits, E5M2 the reverse. Inference uses E4M3; E5M2 is mainly for gradients.

FormatBitsClamp range (TensorRT)Hardware floorRole in a VLA stack
FP3232n/aanythingstatistics, action un-normalisation
BF16 / FP1616n/aPascal and newerwhat nearly every VLA checkpoint ships as
FP8 (E4M3)8-448 to 448compute capability 8.9+weights and activations via TensorRT
INT88-128 to 127Turing+ for LLM.int8()classic PTQ with a calibration pass
INT44-8 to 7Ampere and newerweight-only compression of the backbone
NF44codebook, not a clampPascal and newerQLoRA-style low-VRAM loading
FP4 (E2M1)4native on BlackwellBlackwell, Jetson ThorTransformer Engine switches FP4/FP8
Weight-only and weight-plus-activation are different products

Weight-only (NF4, int4 weight-only) shrinks the checkpoint, but the matmul still runs in bf16 after an on-the-fly dequantise, so it can be slower per step. Weight-plus-activation (INT8 PTQ, FP8 in TensorRT) issues real low-precision Tensor Core instructions, but needs calibration data and the right silicon. Confusing the two is the commonest reason a quantisation project produces no speedup.

The measurement that should change your plan

The cleanest published numbers on quantised VLAs are in the OpenVLA paper. OpenVLA is a 7B model on a Prismatic VLM with a Llama 2 backbone, evaluated on real-robot BridgeData V2 tasks at three precisions on the same hardware.

PrecisionGPU memoryBridge success rateRate on their A5000
bfloat1616.8 GB71.3 +/- 4.8 %reference
int810.2 GB58.1 +/- 5.1 %1.2 Hz
int47.0 GB71.9 +/- 4.7 %3 Hz

Read the middle row twice. 8-bit cost 13.2 points of success rate; 4-bit cost nothing measurable, though it discards twice as much information. The paper is explicit: "8-bit quantization slows down inference across most GPUs, due to the overhead of the added quantization operations", and at 1.2 Hz against a controller recorded at 5 Hz this "significantly changes the system dynamics compared to the training dataset". The model was not wrong. It was late.

Loop rate is a training-distribution variable

A policy trained at one control rate has that rate baked into its action distribution. Halve the step rate and every predicted action covers twice the distance it was trained for. The symptom is overshoot, hesitation, the arm stopping mid-reach. Before touching precision, read policy freezes mid-motion and policy only works in one setup.

Why 8-bit can be slower than 16-bit

  • bitsandbytes LLM.int8() is not a plain INT8 matmul. Per the LLM.int8() paper it quantises vector-wise, then splits outlier feature dimensions into a separate 16-bit matmul. Over 99.9 percent of values go through INT8, but you run two matmuls plus a scatter instead of one.
  • Weight-only 4-bit skips that: dequantise to bf16, one matmul, fewer kernels, less memory traffic.
  • Quantise and dequantise nodes are not free. Unfused, each is an extra full pass over the tensor.
  • Batch size 1 is the robot's only batch size, and a 7B model at batch 1 is memory-bandwidth bound. Halving arithmetic width buys far less than the FLOP count suggests.
  • None of this shows up at batch 32, which is how most quantisation results are reported.
The AY-Robots policy comparison table listing GR00T N1.7, GR00T N1.5, Pi0.5, SmolVLA and ACT with parameters, GPU tier, inference latency and minimum episodes
Per-step latency for the five trainable policies. ACT at 20 ms and Pi0.5 at 485 ms are different problems, and only one is a quantisation problem.

What the runtimes actually support, August 2026

Support is not the same as a working VLA path. A runtime can advertise FP8 and still offer no route from a diffusion-head robot policy to a quantised engine.

RuntimeFormatsCalibrationJetsonRealistic VLA status
TensorRT 11.2INT8, FP8, INT4, FP4 via Q/DQyes, for activationsyesengines build; placing Q/DQ in a VLA graph is your job
TensorRT Model OptimizerINT8, SmoothQuant, FP8, NVFP4128 to 512 samplesaarch64 builds existthe practical PTQ front end
TensorRT-LLMFP8 weights, FP8 KV cache512 calib batches in the examplenoLLM-shaped models only, no diffusion head
bitsandbytesLLM.int8(), NF4, FP4none, data-freesource build requiredeasiest to try, weakest speed guarantee
torchaoint8 dynamic, float8, int4 weight-only, QATconfig-dependentyes, with a matching wheelclosest to a general PyTorch answer
Isaac-GR00T scriptsbf16 onlyn/ayes, Orin and Thorno quantisation offered
LeRobotnonen/an/ano quantisation path for policies

Two rows contradict the marketing. TensorRT-LLM's FP8 guide states FP8 is supported only above compute capability 8.9: Ada, Hopper, Blackwell and later. An AGX Orin 64GB is Ampere, quoted at 275 sparse INT8 TOPS, with no FP8 path. Jetson Thor (25 August 2025) is Blackwell: 2070 sparse FP4 TFLOPS, 517 dense FP8 TFLOPS, 128 GB LPDDR5X at 273 GB/s, 130 W. If your plan says FP8 and your board says Orin, the plan is wrong.

NVIDIA's own GR00T path is bf16, and still 2.35x faster

The Isaac-GR00T deployment guide documents a full TensorRT pipeline for GR00T N1.7: export to ONNX, build engines, verify against PyTorch, benchmark. The precision flag exists and accepts exactly one value.

bash
# Isaac-GR00T, scripts/deployment/build_trt_pipeline.py
# --precision   default: bf16   "Precision for ONNX export and TRT engine build (bf16 only)"

uv run python scripts/deployment/build_trt_pipeline.py \
  --model-path checkpoints/GR00T-N1.7-LIBERO/libero_10 \
  --dataset-path demo_data/libero_demo \
  --embodiment-tag LIBERO_PANDA \
  --export-mode full_pipeline \
  --batch-size 1 \
  --workspace 8192 \
  --steps export,build,verify,benchmark
The entire quantisation surface of NVIDIA's GR00T deployment path: one flag, one legal value.

The speedups are real anyway. NVIDIA's table, measured at 4 denoising steps with 1 camera, shows what compilation alone does.

DevicePyTorch eagerTensorRT full pipelineSpeedup
H100 80GB HBM385.8 ms (11.7 Hz)27.9 ms (35.9 Hz)3.08x
RTX Pro 6000 Blackwell78.4 ms (12.8 Hz)27.9 ms (35.9 Hz)2.81x
L40128.3 ms (7.8 Hz)38.4 ms (26.0 Hz)3.34x
DGX Spark126.4 ms (7.9 Hz)98.6 ms (10.1 Hz)1.28x
AGX Thor112.8 ms (8.9 Hz)80.4 ms (12.4 Hz)1.40x
Jetson Orin354.0 ms (2.8 Hz)150.9 ms (6.6 Hz)2.35x

Note the ordering. Orin gains 2.35x with no precision reduction at all, beating the 1.49x that QVLA reports for mixed-precision quantisation of OpenVLA-OFT and the 1.52x in Mix-QVLA. Kernel fusion, static shapes and removing Python from the loop are cheaper than bit width and do not touch the weights. Do them first.

Compilation ships with an accuracy gate

The GR00T pipeline has a verify step that compares TensorRT output against PyTorch and expects cosine similarity of 0.999 or better. In its LIBERO closed-loop check over 20 episodes, PyTorch scored 20/20 and TensorRT 19/20, inside simulation noise. That is what a safe optimisation looks like: a gate you can run. Hold your quantisation to the same standard.

Do it yourself: the two paths that work

bitsandbytes if you are VRAM-bound and want an answer in ten minutes. TensorRT Model Optimizer if you want throughput and will build a calibration loop.

Path A: bitsandbytes, data-free, memory-first

  1. 1
    Check compute capability first

    LLM.int8() needs capability 7.5 or newer (Turing); NF4 and FP4 need 6.0 or newer (Pascal). The library itself needs Python 3.10+ and PyTorch 2.4+.

    bash
    python -c "import torch; print(torch.cuda.get_device_capability())"
    # (8, 9) = Ada, FP8-capable
    # (8, 7) = Jetson Orin, INT8 only
    # (7, 5) = Turing, the LLM.int8() floor
    
    pip install --upgrade transformers accelerate bitsandbytes
  2. 2
    Load the backbone in 4-bit NF4

    This is the config the OpenVLA repository uses for quantised LoRA fine-tuning in vla-scripts/finetune.py, gated behind --use_quantization, which asserts LoRA is also on.

    python
    import torch
    from transformers import AutoModelForVision2Seq, 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,   # a further ~0.4 bits per parameter
    )
    
    model = AutoModelForVision2Seq.from_pretrained(
        "openvla/openvla-7b",
        quantization_config=quantization_config,
        low_cpu_mem_usage=True,
        trust_remote_code=True,
        device_map="auto",
    )
    print(model.get_memory_footprint())
  3. 3
    If you insist on 8-bit, learn the threshold knob

    llm_int8_threshold decides which hidden-state values count as outliers and stay in fp16. The documented default is 6. Setting it to 0.0 speeds inference up at some accuracy cost, which is exactly the trade the OpenVLA numbers warn about.

    python
    quantization_config = BitsAndBytesConfig(
        load_in_8bit=True,
        llm_int8_threshold=6.0,
        llm_int8_skip_modules=["lm_head"],
    )
  4. 4
    Measure at batch 1, on the board, with the cameras attached

    Not throughput. Wall-clock milliseconds from observation to action at batch 1, including preprocessing, on the machine that holds the arm. Then compare against the rate your episodes were recorded at.

    python
    import time, torch
    
    for _ in range(5):            # warmup: engines, caches, autotune
        _ = policy.select_action(obs)
    
    torch.cuda.synchronize()
    t0 = time.perf_counter()
    for _ in range(50):
        _ = policy.select_action(obs)
    torch.cuda.synchronize()
    print(f"{(time.perf_counter() - t0) / 50 * 1000:.1f} ms per action step")
The Jetson trap that eats a day

The bitsandbytes aarch64 wheels on PyPI target aarch64-sbsa, server ARM with the standard CUDA Toolkit. The installation guide states they are not compatible with the L4T runtime on Jetson (Orin Nano / NX / AGX, Xavier, Thor on CUDA 12), even though both are aarch64. It installs cleanly, then fails on the first CUDA op with Error named symbol not found in /src/csrc/ops.cu. The documented fixes: an on-device source build with the capability passed explicitly, cmake -DCOMPUTE_BACKEND=cuda -DCOMPUTE_CAPABILITY=87 . && make -j4 && pip install . for Orin (72 for Xavier), or a prebuilt wheel from the Jetson AI Lab index.

Path B: TensorRT Model Optimizer, calibration-first

ModelOpt produces a quantised checkpoint TensorRT can compile, and simulates quantisation in PyTorch first, so you can measure the accuracy hit before committing to an engine build.

python
# pip install -U nvidia-modelopt[all]
import modelopt.torch.quantization as mtq

# Named configs shipped by the library:
#   mtq.INT8_DEFAULT_CFG        per-tensor activations, per-channel weights
#   mtq.INT8_SMOOTHQUANT_CFG    shifts activation outliers into the weights first
#   mtq.FP8_DEFAULT_CFG         compute capability 8.9 or newer
#   mtq.NVFP4_DEFAULT_CFG       Blackwell only

def forward_loop(model):
    # 128 to 512 real observations is the documented range.
    # Use frames from YOUR episodes, in the lighting you will deploy in.
    for batch in calib_loader:
        model(batch)

model = mtq.quantize(model, mtq.INT8_DEFAULT_CFG, forward_loop)
PTQ with ModelOpt. The forward_loop is where quantisation succeeds or fails.

The calibration set is what people get wrong. It sets the scale factors, and therefore the clamp points. Calibrate on bright tidy frames, deploy under a different lamp, and real activations clip. Draw calibration frames from your own LeRobot dataset: same scene, same cameras, same exposure. If the dataset is thin, fix that first; the guide on collecting high-quality VLA training data is the prerequisite.

If PTQ costs too much, quantisation-aware training is the escalation. torchao ships a QAT recipe (prepare, fine-tune, convert) and reports recovering 96 percent of the accuracy degradation on hellaswag and 68 percent of the perplexity degradation on wikitext for Llama 3 against plain PTQ. For a robot policy that means folding QAT into the fine-tuning run rather than bolting it on afterwards.

Two ways to get a fast policy onto an SO-100

  1. Record with LeRobot and convert to the format the policy needs. GR00T wants v2.0 or v2.1; a v3.0 dataset crashes its loader.
  2. Rent or buy a GPU and fine-tune. openpi documents more than 70 GB for a full Pi0.5 fine-tune, more than 22.5 GB for LoRA.
  3. Pick a board. Orin means INT8 is your ceiling; Thor adds FP8 and FP4.
  4. Export to ONNX, build a TensorRT engine per GPU architecture (they are not portable), verify cosine similarity against PyTorch.
  5. Build a calibration loader from 128 to 512 of your own frames, run PTQ, re-verify.
  6. Benchmark at batch 1 on the board, then run a closed-loop success-rate evaluation. Quantisation you have not evaluated on the robot is a guess.
  7. Rebuild when the GPU, batch size or camera count changes.
Where the week goes

Steps 4 to 6. Engines are GPU-architecture-specific and batch size is baked in as a static dimension, so every hardware change means a rebuild and a re-verify.

The AY-Robots /try page showing three ways to start without owning a robot: drive a real arm, compare models, rent a GPU
Drive a real SO-100 remotely and feel what a round trip does to a control loop, before buying a board to avoid one.

Is it worth it

Quantising a VLA for on-robot inference
Advantages
  • Memory is the hard constraint on an embedded board, and quantisation attacks it directly: 16.8 GB down to 7.0 GB at int4.
  • It turns an impossible deployment into a possible one. A model that does not fit has a success rate of zero.
  • Weight-only 4-bit is data-free: no calibration set, no extra training run.
  • Mix-QVLA reports 15.4 GB down to 4.1 GB with 96.3 percent average LIBERO success against a 97.1 percent BF16 baseline.
  • Native low precision is where the silicon is going: Thor quotes 517 dense FP8 TFLOPS in 130 W.
Trade-offs
  • 8-bit frequently costs latency instead of saving it, and on OpenVLA that meant 13.2 points of success rate.
  • Every gain is hardware-conditional, and TensorRT engines do not move across architectures.
  • Calibration is a data problem in engineering clothes. A mismatched set silently clips activations.
  • The tooling does not meet VLAs halfway: Isaac-GR00T is bf16 only, LeRobot has no quantisation path, TensorRT-LLM ignores diffusion action heads.
  • Knowing whether it worked needs a closed-loop success-rate evaluation, which costs robot hours most projects have not budgeted.

Where quantisation is the wrong lever

SymptomWhat people tryWhat is usually true
Policy is jerky or overshootsquantise to go fasterthe loop rate no longer matches the recording rate
Out of memory during trainingquantise the modeltraining memory is optimiser state and batch size, not inference precision
Remote inference feels laggyquantise the served modelthe GPU is not the bottleneck, the network round trip is
ACT is too slowquantise ACTACT is ~80 M parameters at 20 ms per step; nothing to reclaim
Model will not fit on the boardcompile harderthe genuine case: weight-only 4-bit first, then PTQ

That last row deserves a positive statement. When the model genuinely does not fit, quantisation is the enabling step. BitVLA trains a VLA natively in 1-bit, every parameter ternary, on top of BitNet b1.58 2B4T, and reports 11.0x lower memory and 4.4x lower end-to-end latency than OpenVLA-OFT at comparable performance. That is co-designing the policy for the precision rather than squeezing a bf16 checkpoint afterwards. The overview of VLA models and the Pi0 flow-matching write-up sit one layer below this page.

The smaller policies here make the same point without exotic arithmetic. SmolVLA is around 450 M parameters at 245 ms per step, ACT around 80 M at 20 ms, and both run locally on a 24 GB card. Choosing a smaller architecture is a cleaner route to a latency target than quantising a 3 B model into a shape its authors never validated. See ACT against SmolVLA, or the arena with 85 VLA models and 332 benchmark results.

The AY-Robots CLI page showing the install command and the run commands for training and inference from a terminal
The same train and inference operations from a terminal, which is where latency benchmarking scripts belong.

An order of operations that does not waste a week

  1. Measure per-step latency at batch 1 on the target board with the cameras attached.
  2. Write down the control rate your episodes were recorded at. If the two disagree, that is the bug, and precision will not fix it.
  3. Remove Python from the hot loop. On Orin, NVIDIA measured 1.56x from torch.compile alone before any TensorRT work.
  4. Compile to TensorRT at bf16 and verify cosine similarity against PyTorch: 2.35x on Orin with zero precision loss.
  5. Only now consider precision: weight-only 4-bit if VRAM-bound, INT8 PTQ with real calibration data if compute-bound.
  6. Re-run the closed-loop success rate. A throughput number without a success rate is not evidence.
  7. If PTQ costs too much, move to QAT inside the fine-tuning run rather than accepting the loss.
Which policy you optimise matters more than the technique

The five trainable policies here span a 24x range in per-step latency: ACT 20 ms, GR00T N1.7 152 ms, GR00T N1.5 165 ms, SmolVLA 245 ms, Pi0.5 485 ms. Before spending a week on quantisation, spend an hour on the model comparison and the GR00T N1.7 against Pi0.5 head-to-head. Swapping architecture is usually the bigger and safer lever.

The AY-Robots MCP server page listing training, dataset and inference operations exposed to AI agents
The MCP server exposes the same operations to an agent, which helps when sweeping configurations rather than clicking through them.

Frequently asked questions

Does INT8 always make a VLA faster?

No. In the OpenVLA paper 8-bit ran at 1.2 Hz on the authors' A5000, against a 5 Hz recorded controller, and the Bridge success rate fell from 71.3 to 58.1 percent. At batch size 1, the only batch size a robot uses, a 7B model is bandwidth-bound, so halving arithmetic width buys little.

Can I use FP8 on a Jetson Orin?

No. TensorRT-LLM documents FP8 as requiring compute capability above 8.9: Ada, Hopper, Blackwell. Orin is Ampere; the AGX Orin 64GB is quoted at 275 sparse INT8 TOPS with no FP8 path. Jetson Thor is Blackwell and quotes 517 dense FP8 TFLOPS plus native FP4.

Why does the Isaac-GR00T TensorRT pipeline not offer INT8?

Its build_trt_pipeline.py exposes --precision with bf16 as the only legal value. The speedups come from compiling every component to TensorRT engines and removing Python overhead: 3.08x on H100, 2.35x on Orin, 1.40x on AGX Thor. If NVIDIA has not validated an INT8 GR00T engine, treat a homemade one as an experiment needing its own closed-loop evaluation.

How much calibration data does PTQ need?

TensorRT Model Optimizer documents 128 to 512 samples as typical, and the TensorRT-LLM FP8 example uses 512 calibration batches. The count matters less than the match: frames must come from the same scene, cameras and lighting you will deploy in, because they set the clamp points.

Does quantisation help on AY-Robots?

Not directly. Training runs on rented A100/H100 or RTX 4090 class GPUs and inference is served from an auto-provisioned pod sized for the model, so VRAM is not the binding constraint. Distance is: the control loop is 20 to 485 ms per step, and internet round trips on top make fast reactive tasks unreliable. Quantisation matters once you move the compute onto the robot.

Is 4-bit really safe when 8-bit was not?

It was in that one measurement, and because of speed rather than numerical robustness, so do not generalise. QVLA reports 98.9 percent of original performance at 29.2 percent of the VRAM with a 1.49x speedup, and Mix-QVLA 96.3 percent average LIBERO success against 97.1 percent for BF16. All were measured on OpenVLA-OFT, not on GR00T or Pi0.5.

The short version

Quantisation is a memory tool that sometimes pays out as a speed tool. Treated as the default answer to "the policy is too slow", it costs a week and produces a model that is smaller, no faster and worse at the task. The order that works: measure at batch 1, match the control rate, compile, verify, then reach for bit width. To test the latency question before buying a board, drive a real SO-100 over the internet. The SO-100 setup guide covers the hardware, the training docs cover what the platform sends to the trainer, and pricing covers what a run costs.

Test the latency question before you buy a Jetson

Drive a real SO-100 from your browser with no signup, compare five policies on measured per-step latency, and rent a GPU for a training run from about 1 USD.

Try it without a robot

Ready for high-quality robotics data?

AY-Robots connects your robots to skilled operators worldwide.

Get Started