VnRobo
AboutPricingBlogContact
🇻🇳VISign InStart Free Trial
🇻🇳VI
VnRobo logo

AI infrastructure for next-generation industrial robots.

Product

  • Features
  • Pricing
  • Knowledge Base
  • Services

Company

  • About Us
  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 VnRobo. All rights reserved.

Made with♥in Vietnam
VnRobo
AboutPricingBlogContact
🇻🇳VISign InStart Free Trial
🇻🇳VI
  1. Home
  2. Blog
  3. FlashVLA: Speed Up π0.5/SmolVLA
wholebody-vlaFlashVLAπ0.5SmolVLAstreaming action decodingLeRobot

FlashVLA: Speed Up π0.5/SmolVLA

A practical FlashVLA guide for π0.5 and SmolVLA: streaming action decoding, setup, training, async inference, and benchmark results.

Nguyễn Anh TuấnSeptember 4, 202613 min read
FlashVLA: Speed Up π0.5/SmolVLA

FlashVLA is a method for making flow-matching VLA policies faster in robot manipulation. Instead of treating the policy as a heavy blocking function that must finish all denoising before the robot can move, FlashVLA turns action decoding into a streaming pipeline. The robot executes the current action chunk while the GPU prepares the next one. After warm-up, each forward pass does not solve a full trajectory from scratch; it updates an action buffer containing multiple slots at different denoising stages.

This matters for π0.5 and SmolVLA because modern vision-language-action policies are powerful but not automatically real-time. Multiple camera views, large vision-language backbones, and iterative denoising can push inference beyond the budget of a manipulation control loop. In the official results, FlashVLA reduces π0.5 LIBERO time/step from 53.8 ms to 22.1 ms with async d=1, and to 20.6 ms with d=2. On RoboTwin 2.0, average π0.5 success rises from 86.0% to about 90.6%. For SmolVLA, FlashVLA keeps success essentially unchanged while reducing per-step time from 41.2 ms to 29.7 ms or 28.7 ms depending on the overlap setting.

If you have read our LeRobot hands-on guide, OpenVLA deep dive, or EXPO-FT for π0.5, FlashVLA is the next deployment-focused piece. It is not primarily about collecting a better dataset or adding a reward. It is about latency engineering for VLA policies that must run on a real robot.

Tool recommendations

VLA train/deploy stack

Train on cloud/workstation, then deploy optimized models to Jetson or the robot computer.

Cloud GPU for VLA / policy training Use for imitation learning, diffusion policies, RL, and robotics model fine-tuning. View cloud GPU → NVIDIA Jetson Orin NX / Orin Nano Edge deployment hardware for perception, logging, and optimized inference. View Jetson → Hugging Face / robotics dataset hosting Host datasets, checkpoints, and model cards for cleaner LeRobot/VLA workflows. View platform →

This article is based on the FlashVLA: Streaming Action Decoding for Fast and Asynchronous VLA Inference arXiv paper, the official z-lab/flashvla repository, and the z-lab/flashvla Hugging Face model collection. As of this writing, the repository includes training code, latency benchmarks, LIBERO evaluation, RoboTwin 2.0 adapters, π0/π0.5/SmolVLA/LingBot-VLA policy implementations, and released π0.5 checkpoints for LIBERO and RoboTwin. The guide below is written for practitioners: first understand the idea, then install, train, evaluate, and reason about deployment.

FlashVLA overview with parallel action buffers - source: FlashVLA paper on arXiv
FlashVLA overview with parallel action buffers - source: FlashVLA paper on arXiv

The Problem FlashVLA Solves

A VLA manipulation policy usually consumes three kinds of input. The first is visual observation: external cameras, wrist cameras, or multiple views at once. The second is language: “pick up the cup”, “put the block in the bowl”, or “clean the table”. The third is robot state: joint positions, gripper state, end-effector pose, or normalized proprioception. The output is a short sequence of actions for the next few control steps.

In a flow-matching policy, the initial action is represented as noise. The model learns a velocity field that transforms noise into a clean action as a synthetic denoising time t moves from noisy to clean. At inference time, the policy runs several denoising steps. The baseline schedule is synchronous: predict one chunk, execute it, then block again to predict the next chunk. If inference takes 50 ms but the control loop wants a 20 ms step, the robot either runs slowly or suffers jitter.

FlashVLA reframes the problem. During an episode, the robot does not need an infinite future trajectory. It needs the nearest chunk to be good enough now, while later chunks can keep denoising in the background. FlashVLA therefore maintains a buffer with N slots, where each slot is an action chunk of length C. The first slot is closest to execution. Later slots represent further future actions. Each forward pass updates the whole buffer by one denoising step. Once the buffer is full, the policy emits the first slot, shifts the remaining slots left, and appends fresh noise to the last slot.

In plain terms, the baseline spends multiple forward passes to produce one chunk. FlashVLA pipelines multiple chunks across buffer slots. After the cold start period, every forward pass can return a chunk that has already received enough denoising updates. This is why the paper calls the method streaming action decoding.

Architecture: Shared Observation, Multi-Buffer Actions

FlashVLA does not require throwing away π0.5 or SmolVLA and building a new policy from scratch. The repository implements policy types such as pi05-flashvla, smolvla-flashvla, pi0-flashvla, and lingbot-flashvla. The common pattern is to keep the vision-language prefix and replace the action suffix with a multi-slot action buffer.

For π0.5, the input prefix contains image tokens, language tokens, and state embeddings. The action suffix contains N * C action tokens. In the LIBERO config shipped by the repository, num_buffer_slots: 4 and chunk_size: 10, so the buffer contains 40 action tokens. During training, one observation is shared across several buffer configurations. Each slot receives a different time level t: the slot nearest execution is cleaner, while later slots remain noisier. The model learns the velocity field for all slots in one pass.

FlashVLA training diagram with shared observation and multi-buffer action slots - source: FlashVLA paper on arXiv
FlashVLA training diagram with shared observation and multi-buffer action slots - source: FlashVLA paper on arXiv

At inference time, the main logic lives in sample_actions and the _cold_start and _steady_streaming branches. At the beginning of an episode, the buffer has not accumulated enough denoising history, so the policy goes through cold start. During this phase, predict_action_chunk may return None; the runtime wrapper falls back to a hold-pose or current-state action depending on configuration. When the step counter reaches N - 1, the buffer is mature. From that point onward, each policy call:

  1. Builds the prefix from images, language, and state.
  2. Denoises the entire action buffer by one step with dt = 1 / N.
  3. Uses the first slot, buffer[:, :C, :], as the executable chunk.
  4. Shifts the remaining slots left.
  5. Samples fresh noise for the last slot.

FlashVLA inference diagram: denoise, execute, shift, append noise - source: FlashVLA paper on arXiv
FlashVLA inference diagram: denoise, execute, shift, append noise - source: FlashVLA paper on arXiv

Two implementation details are worth noting. First, FlashVLA uses block-causal attention over action tokens: tokens within the same slot can attend fully, while slots only attend in a causal direction so the model does not leak future information. Second, for SmolVLA, the repository supports use_adarms_time_cond: true, which injects denoising time through AdaRMS-style modulation in the action expert branch. This gives the expert a clean signal about each token's denoising stage without cluttering the observation prefix.

Installation

The FlashVLA repository uses Python 3.12, PyTorch CUDA 12.8, TorchVision, and TorchCodec. The basic setup is:

git clone https://github.com/z-lab/flashvla.git
cd flashvla
conda env create -f environment.yml
conda activate flashvla

The environment.yml installs torch==2.9.1+cu128, torchvision==0.24.1+cu128, torchcodec==0.9.1+cu128, and then installs the local package with -e .. This is the cleanest path for a recent CUDA workstation, especially RTX 4090/5090-class machines. If you use Jetson, an older driver, or a cluster with a managed CUDA module, do not copy these versions blindly. Keep FlashVLA's policy logic, but choose the PyTorch wheel that matches your actual driver stack.

LIBERO evaluation requires extra simulator dependencies:

conda install -y cxx-compiler make
CMAKE_POLICY_VERSION_MINIMUM=3.5 pip install --no-build-isolation -e ".[libero]"
export MUJOCO_GL=egl
export __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/10_nvidia.json

The --no-build-isolation flag matters. Some dependencies pull cmake through pip as a Python entry script; isolated build environments can fail to see the expected build tools. On a headless server, MUJOCO_GL=egl lets MuJoCo render through GPU/EGL without a desktop.

Training π0.5 FlashVLA on LIBERO

The repository ships a ready-to-run training config:

bash train/train.sh train/configs/pi05/libero/pi05_flashvla.yaml

The key settings are:

policy:
  type: pi05-flashvla
  pretrained_path: lerobot/pi05_base
  dtype: bfloat16
  device: cuda
  state_cond: false
  num_buffer_slots: 4
  chunk_size: 10
  freeze_vision_encoder: false
  normalization_mapping:
    VISUAL: IDENTITY
    STATE: MEAN_STD
    ACTION: MEAN_STD

dataset:
  repo_id: HuggingfaceVLA/libero
  video_backend: torchcodec

batch_size: 8
grad_accum_steps: 4
steps: 50000

A beginner should read this config in four layers. The model layer says the backbone is lerobot/pi05_base, the policy type is pi05-flashvla, inference/training uses bfloat16, and the vision encoder is not frozen. The buffer layer says the policy learns streaming with 4 slots, each 10 actions long. The normalization layer keeps visual inputs as identity while state and action use mean-std statistics. The optimization layer uses AdamW, a peak learning rate of 1e-4, 1000 warm-up steps, and cosine decay to 2.5e-6.

If GPU memory is tight, reduce batch_size first and use grad_accum_steps to keep the effective batch size reasonable. If you only want to debug the pipeline, you can reduce steps to a few hundred or a few thousand. Do not use that checkpoint to judge the method, though. FlashVLA must learn the multi-buffer pattern; a short debug run mainly checks wiring, shapes, and dataset loading.

Training SmolVLA FlashVLA

SmolVLA has its own config:

bash train/train.sh train/configs/smolvla/libero/smolvla_flashvla.yaml

The main differences are:

policy:
  type: smolvla-flashvla
  pretrained_path: lerobot/smolvla_base
  num_buffer_slots: 5
  chunk_size: 10
  use_adarms_time_cond: true
  attention_mode: cross_attn

batch_size: 64
steps: 20000

SmolVLA is smaller than π0.5, so the config uses a larger batch size and fewer steps. num_buffer_slots: 5 means the action buffer contains 50 action tokens. use_adarms_time_cond feeds denoising time into the expert branch through modulation, and attention_mode: cross_attn preserves the architecture expected by SmolVLA. The cross-architecture results in the README show that FlashVLA is not just a π0.5-specific trick: for SmolVLA, average success is reported as 80.1% for the baseline and 80.1% for FlashVLA sync, while inference latency drops from 19.7 ms to 10.1 ms.

Synchronous and Asynchronous Inference

The deployment component to understand is AsyncStreamingActionManager. This wrapper maintains current_chunk, next_chunk, chunk_index, and overlap_steps. If overlap_steps = 0, the robot runs synchronously: consume the current chunk, then block to produce the next one. If overlap_steps = 1 or 2, the wrapper launches inference before the current chunk ends. The GPU computes the next chunk while the CPU, simulator, or real robot continues executing existing actions.

The control loop looks like this:

manager = AsyncStreamingActionManager(policy, overlap_steps=1)
manager.reset()

obs = env.reset()
while not done:
    if manager.needs_observation():
        batch = preprocessor(obs).to(policy.device)
        action = manager.act(batch)
    else:
        action = manager.pop_cached_action()

    action = postprocessor({"action": action})["action"]
    obs, reward, done, info = env.step(action.numpy())

needs_observation() is a practical optimization. If the next action is already cached on CPU, the simulator can skip rendering and transferring images for the policy at that step. On a real robot, this means the control thread does not necessarily wait for the camera pipeline at every tick. You still need to define policy update rate and low-level control rate clearly. FlashVLA does not replace the controller; it makes high-level action chunks arrive more consistently.

CUDA graph warm-up is another important detail. The runtime has a warmup(processed_obs) method that runs num_buffer_slots + 1 inferences, captures the graph, and resets the streaming state. Without warm-up, the first transition into _steady_streaming can trigger torch.compile and CUDA graph capture, blocking the rollout for 10-30 seconds. That ruins latency measurements and can make the first real-robot episode appear frozen.

Running Evaluation

For LIBERO, the repository provides:

bash sim_eval/libero/eval.sh
GPUS="0 1 2 3" bash sim_eval/libero/eval.sh

For a smaller debugging run:

python sim_eval/libero/eval.py --policy.path=z-lab/flashvla-pi05-libero \
  --env.type=libero --env.task=libero_spatial --eval.n_episodes=50 \
  --policy.n_action_steps=5 --inference_overlap_steps=1 \
  --policy.compile_model=true

RoboTwin 2.0 is more involved because SAPIEN and RoboTwin require a separate simulator environment. FlashVLA runs the policy server in the flashvla environment, while RoboTwin runs the simulator client in its own environment. After copying the FlashVLA adapters into the RoboTwin tree, run two terminals:

# terminal 1 - flashvla env
bash eval_server.sh /path/to/flashvla_robotwin_ckpt 9999 0 current_state 1 16 true

# terminal 2 - RoboTwin env
EVAL_STEP_LIM_OFFSET=48 ROBOTWIN_VENV=/path/to/robotwin_venv \
  bash eval_client.sh beat_block_hammer demo_clean

The current_state cold-start mode matters for RoboTwin because the action is absolute qpos; a zero action can crash the arm. EVAL_STEP_LIM_OFFSET=48 compensates for cold start in the 4-slot, 16-actions-per-call setting: (4 - 1) * 16 = 48.

How to Read the Results

FlashVLA compared with other VLA acceleration strategies - source: FlashVLA paper on arXiv
FlashVLA compared with other VLA acceleration strategies - source: FlashVLA paper on arXiv

On LIBERO, the π0.5 baseline reaches 96.9% average success with 53.8 ms per step. FlashVLA sync d=0 reaches 97.9%. FlashVLA async d=1 reaches 97.8% and 22.1 ms per step, a 2.43x speedup. With d=2, success reaches 98.3% and time/step falls to 20.6 ms, a 2.62x speedup. The important point is that throughput improves without a success-rate collapse; on the Long suite, success rises from 92.4% to 97.4% at d=2.

On RoboTwin 2.0, baseline π0.5 reaches 86.0% average success across 50 tasks. FlashVLA sync reaches 90.5%, while async d=1 and d=2 both land around 90.6%. This suggests that multi-buffer training may also act as a regularizer: the model learns nearby future chunks at different noise levels instead of overfitting to one synchronous decoding path.

The standalone latency benchmark is also useful. On an RTX 4090 with two camera views, π0.5 takes 45.8 ms, Realtime-VLA takes 29.2 ms, and FlashVLA takes 26.7 ms. On an RTX 5090 with three views, π0.5 takes 44.8 ms, Realtime-VLA takes 34.2 ms, and FlashVLA takes 27.1 ms. The paper reports that π0.5 and FlashVLA use the same CUDA Graph and kernel-fusion optimizations in this measurement, so the difference comes from the decoding schedule, not just implementation tricks.

When Should You Use FlashVLA?

FlashVLA is a good fit when a flow-matching VLA policy is bottlenecked by inference latency: the robot needs a faster loop, extra camera views make each forward pass heavier, or action chunks cause visible pauses at boundaries. It is also a good fit if you already use LeRobot, π0.5, or SmolVLA-style training and want a concrete recipe rather than a custom scheduler.

It is not a cure for unrelated robotics problems. If demonstrations are poor, camera calibration is wrong, action normalization is off, or the low-level controller is unstable, streaming decoding only makes the wrong behavior arrive faster. Before real-robot deployment, test in order: offline latency benchmark, LIBERO/RoboTwin or your own simulator, action replay in a safety cage, then object interaction on hardware.

A practical checklist:

Area What to check
Dataset Observation keys, action dimension, fps, chunk length, normalization
Policy num_buffer_slots, chunk_size, n_action_steps, checkpoint path
Runtime CUDA version, torch.compile, CUDA graph warm-up, camera transfer
Async overlap_steps, stale-action handling, cold-start action mode
Robot Low-level control rate, action limits, emergency stop, reset behavior

Conclusion

FlashVLA is a useful lesson for robotics engineers: sometimes the largest deployment win does not come from scaling the model, but from organizing inference around the robot's timing constraints. With streaming action decoding, π0.5 and SmolVLA can reuse the observation prefix, maintain multiple action-buffer slots, overlap GPU inference with robot execution, and reduce latency substantially without sacrificing success rate.

If you are building a VLA manipulation stack, treat FlashVLA as a training and deployment recipe for the action decoder. Start with LIBERO to understand the buffer and cold start, then move to your own LeRobot-format dataset. Once the synchronous path is stable, enable async overlap gradually: d=0, then d=1, then d=2. Measure stability before chasing speed; on a real robot, a fast bad chunk is still a bad chunk.

Related Posts

  • FineVLA: dual-arm VLA tutorial
  • DexVerse: Benchmark OpenVLA and π0.5
  • EXPO-FT: fine-tune π0.5 with online RL
NT

Nguyễn Anh Tuấn

Robotics & AI Engineer. Building VnRobo — sharing knowledge about robot learning, VLA models, and automation.

Khám phá VnRobo

Fleet MonitoringROS 2 IntegrationAMR Solutions

Related Posts

Tutorial
PoseVLA: pretrain 3D pose cho π0.5
PoseVLApi0.5RoboTwin
wholebody-vla

PoseVLA: pretrain 3D pose cho π0.5

Hướng dẫn PoseVLA open-source: cài đặt, pretrain 3D pose, post-train RoboTwin, inference và vì sao scaled training đạt gần 89%.

8/24/202615 min read
NT
Tutorial
DexVerse: Benchmark OpenVLA và π0.5
DexVerseOpenVLAπ0.5
wholebody-vla

DexVerse: Benchmark OpenVLA và π0.5

Hướng dẫn DexVerse, benchmark open-source mới để test OpenVLA, π0.5 và diffusion policy trên 100 task dexterous manipulation.

7/13/202615 min read
NT
Tutorial
Chạy Hy-Embodied-0.5-VLA với UMI
Hy-EmbodiedVLAUMI
wholebody-vla

Chạy Hy-Embodied-0.5-VLA với UMI

Hướng dẫn cài đặt, chạy inference, đọc dữ liệu UMI và fine-tune Hy-Embodied-0.5-VLA cho thao tác song thủ.

6/17/202615 min read
NT
VnRobo logo

AI infrastructure for next-generation industrial robots.

Product

  • Features
  • Pricing
  • Knowledge Base
  • Services

Company

  • About Us
  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 VnRobo. All rights reserved.

Made with♥in Vietnam