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. Guided Action Flow for SmolVLA
wholebody-vlaguided-action-flowsmolvlaq-guided-flowliberovlarobot-manipulation

Guided Action Flow for SmolVLA

A beginner guide to GAF: improve frozen SmolVLA on LIBERO with a Q-guided critic, without policy fine-tuning.

Nguyễn Anh TuấnSeptember 2, 202615 min read
Guided Action Flow for SmolVLA

Guided Action Flow, or GAF, is a practical idea for robot manipulation: keep the base Vision-Language-Action policy frozen, then add a small action-chunk critic at inference time. The critic does not replace the policy, does not rerank a finite set of completed action samples, and does not backpropagate through the full VLA. It only provides gradients with respect to the action chunk so the flow sampler is nudged toward higher-value actions.

This article is based on the paper Guided Action Flow: Q-Guided Inference for Flow-Matching Vision-Language-Action Policies, arXiv 2607.02092, and the official repository ylhaichen/guided-action-flow. The goal is to make the method followable for a beginner: the paper idea, architecture, installation, rollout collection, critic training, Q-guided inference, and how to interpret the LIBERO results. If you are new to VLA policies, start with VLA Models in robotics and then read a LeRobot hands-on guide from the AI robotics series.

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 →

Why GAF Exists

Modern VLA policies such as OpenVLA, pi0, GR00T, and SmolVLA are often trained with imitation learning on demonstrations. That is powerful when the deployment task is close to the training data. But when a policy fails in a subset of states, improving it usually means collecting more demonstrations, fine-tuning, or running reinforcement learning. For larger models, policy fine-tuning is expensive, can overfit, and changes behavior that may already have been validated.

GAF asks a narrower question: if the frozen policy already has useful competence, can a small critic improve the action sampler during inference? This question is natural for SmolVLA because SmolVLA is a flow-matching policy. It does not output the final action chunk in a single step. It iteratively transports noise into a clean action chunk. That iterative process gives the critic a place to intervene.

Intuitively, imagine SmolVLA generating a 50-step action chunk for a LIBERO task. At every denoising step, the sampler has an intermediate action x_t and a velocity v_t. If a critic can score which action chunks are more likely to succeed, we can differentiate that score with respect to the estimated clean action a_hat, then slightly adjust the velocity. If the critic is right, the final action can improve. If the critic is wrong or overconfident out of distribution, guidance can create regressions. That is why the paper emphasizes critic ensembles, gradient clipping, and uncertainty gates.

Official Sources

Resource Link
GAF paper arXiv:2607.02092
GAF repo github.com/ylhaichen/guided-action-flow
SmolVLA model card HuggingFaceVLA/smolvla_libero
LeRobot github.com/huggingface/lerobot
LIBERO benchmark github.com/Lifelong-Robot-Learning/LIBERO

The paper is explicit about its scope. GAF is an early empirical study, not a claim that Q-guided inference has solved VLA adaptation. The strongest evidence is that critic gradients can improve a frozen SmolVLA policy in real LIBERO rollouts, while critic generalization remains the central bottleneck. The repository also describes itself as project glue: it does not vendor LeRobot, SmolVLA, or LIBERO into the main package. Upstream repositories live under third_party/, checkpoints under checkpoints/, and rollout artifacts under runs/.

SmolVLA architecture used as the frozen base policy for Guided Action Flow - source: SmolVLA paper on arXiv
SmolVLA architecture used as the frozen base policy for Guided Action Flow - source: SmolVLA paper on arXiv

Architecture Overview

GAF has three main components.

Component Role
Frozen SmolVLA Takes images, proprioception, and language, then generates an action chunk with a flow sampler
Action-chunk critic Predicts a scalar value Q(obs_features, action_chunk, task_feature)
QGF hook Computes a gradient with respect to the estimated clean action and adjusts sampler velocity

The key constraint is that the policy is not updated. SmolVLA still runs normally: observations pass through the vision-language pathway, the action expert predicts flow velocity, and the sampler integrates from noise toward action. GAF installs a hook inside the denoising loop. The hook receives x_t, v_t, timestep t, observation features, and task features; it estimates the clean action, queries the critic, and returns a guided velocity.

The repository is organized around these boundaries:

src/guided_action_flow/
  benchmarks/      adapters for LIBERO, LIBERO-plus, LIBERO-PRO
  critics/         action-chunk critic, ensemble, checkpoint loading
  guidance/        QGF update rule
  policies/        SmolVLA/LeRobot wrapper and QGF hook
  rewards/         reward and success extraction
  training/        rollout dataset, returns, task features
  evaluation/      rollout and metrics

If you have used diffusion guidance in image generation, the pattern will feel familiar: a base generative model produces a sample, and an external signal steers the sampling trajectory. Robotics makes the problem stricter. The generated sample is not an image; it is an action chunk that must obey action scale, gripper semantics, robot kinematics, and closed-loop execution.

SmolVLA Flow Convention

The easiest technical detail to get wrong is the guidance sign. According to the repository docs, the pinned SmolVLA implementation uses this reverse-time convention:

x_t = t * noise + (1 - t) * action
v_t = noise - action

Inference starts from noise at t = 1 and moves toward action at t = 0:

dt = -1 / num_steps
x_t = x_t + dt * v_t

Therefore the estimated clean action at an intermediate step is:

a_hat = x_t - t * v_t

If you copy a Q-guided flow update from a paper that uses the opposite time convention, you can move the sampler in the wrong direction. For the pinned SmolVLA code path used by GAF, increasing the clean action along the critic gradient +g requires decreasing the velocity:

g = grad_a Q(obs_features, proprio, a_hat)
v_guided = v_t - g / beta

The fuller version uses an ensemble, gradient clipping, and a disagreement gate:

q_mean = mean(Q_k(obs_features, a_hat, task_feature))
g = grad_a q_mean
g = clip_by_norm(g, c)
gate = max(m_min, exp(-alpha * std(Q_k)))
v_guided = v_t - gate * g / beta

Smaller beta means stronger guidance. grad_clip_norm prevents unstable critic gradients from dominating the action sampler. std(Q_k) measures disagreement across ensemble members; when critics disagree, the gate reduces the guidance strength.

What the Critic Learns

The GAF critic does not predict actions. It predicts a scalar value for an action chunk. The basic inputs are policy-side observation features, proprioception when used, the 7D LIBERO action chunk, and an optional task feature. The target is sparse success-to-go from real rollouts of the frozen SmolVLA policy.

Consider an 80-step episode. If success first appears at step 60, chunks starting before that step receive discounted targets, and chunks after success receive targets near 1. If the episode never succeeds, the target is 0. This target is cheap and easy to debug, but it is also blunt. It may not distinguish a near-success trajectory from a completely bad one if both fail before the success checker fires.

The repository emphasizes that train/validation splits must happen at the episode level, not the chunk level. If you randomly split overlapping chunks, adjacent chunks from the same trajectory can leak into both train and validation. The validation loss will look better than the critic actually is. For beginners, this is one of the most important robotics data lessons in the project.

The strongest task-conditioned critic in the paper uses hidden states from the frozen SmolVLA language pathway. The task description is processed by SmolVLA's VLM text path, then non-padding token hidden states are mean-pooled into a task feature. This is stronger than task IDs because task IDs are not portable across LIBERO families. It also avoids training a separate text encoder.

SmolVLA asynchronous inference, the chunked-action runtime design that GAF wraps around - source: SmolVLA paper on arXiv
SmolVLA asynchronous inference, the chunked-action runtime design that GAF wraps around - source: SmolVLA paper on arXiv

Installation

Linux is strongly preferred because LIBERO depends on MuJoCo and robosuite. The repository notes that the current runs were produced on a laptop RTX 4070 with 8GB VRAM. Official SmolVLA 0.45B LIBERO evaluation and QGF evaluation with K=3 critics both fit on that machine. That makes GAF attractive for smaller labs: you do not need a large cluster to reproduce the first ablations.

Create the Python environment:

conda create -n gaf-libero python=3.12 -y
conda activate gaf-libero
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev,torch]"

Bootstrap upstream repositories:

bash scripts/bootstrap_third_party.sh
git clone https://github.com/sylvestf/LIBERO-plus.git third_party/LIBERO-plus
git clone https://github.com/Zxy-MLlab/LIBERO-PRO.git third_party/LIBERO-PRO

Install LeRobot from the pinned checkout:

cd third_party/lerobot
python -m pip install -e ".[smolvla,libero]"
cd ../..

Set up headless MuJoCo:

export MUJOCO_GL=egl
export WANDB_MODE=disabled
export PYTHONPATH="$PWD/src:$PWD/third_party/lerobot/src${PYTHONPATH:+:$PYTHONPATH}"

Create local LIBERO config directories:

mkdir -p .libero_configs/vanilla .libero_configs/plus .libero_configs/pro
export LIBERO_CONFIG_PATH="$PWD/.libero_configs/vanilla"

The .libero_configs/* files contain absolute paths to assets, BDDL files, benchmark root, datasets, and init states. They are machine-specific and should not be committed. If the simulator fails before the policy is called, check LIBERO_CONFIG_PATH, MuJoCo EGL, asset paths, robosuite version, and the installed LIBERO package before tuning the critic.

Download Checkpoints and Run Baseline

GAF uses the official SmolVLA checkpoint for LIBERO:

python scripts/download_models.py \
  --repo-id lerobot/smolvla_libero \
  --local-dir checkpoints/smolvla_libero

Run a one-episode smoke test:

PYTHON_BIN="$CONDA_PREFIX/bin/python" \
POLICY_PATH="$PWD/checkpoints/smolvla_libero" \
OUTPUT_DIR="$PWD/runs/smolvla_libero_smoke" \
TASK=libero_spatial \
TASK_IDS='[0]' \
N_EPISODES=1 \
bash scripts/eval_smolvla_libero.sh

Run the baseline with the general evaluator:

python scripts/eval_policy.py \
  --policy-path checkpoints/smolvla_libero \
  --output-dir runs/baseline_spatial3_ep50_seed3000 \
  --env-type libero \
  --task libero_spatial \
  --task-ids '[3]' \
  --n-episodes 50 \
  --seed 3000 \
  --device cuda \
  --max-videos 0

Do not skip the baseline. If your baseline is much lower than the repository report, do not tune QGF yet. Check checkpoint paths, action normalization, camera keys, task IDs, seed handling, maximum episode length, LeRobot version, and LIBERO version. GAF is a small guidance layer; it will not repair a broken evaluation pipeline.

Collect Rollouts for the Critic

The critic must learn from real rollouts of the frozen SmolVLA policy, not dummy actions. For a single-task trial:

python scripts/collect_rollouts.py \
  --policy-path checkpoints/smolvla_libero \
  --output-dir runs/qgf_single_task_spatial3_train50 \
  --env-type libero \
  --task libero_spatial \
  --task-ids '[3]' \
  --n-episodes 50 \
  --seed 2000 \
  --device cuda

The output under runs/ contains episode trajectories, action sequences, success flags, and metadata. The dataset builder converts these trajectories into overlapping action chunks. With horizon 50, an 80-step episode can produce many chunks starting at different steps. The observation feature is taken from the start of the chunk, the action input is the following action sequence, and the target is success-to-go.

Before training, check:

Check Why it matters
The rollout set contains successes and failures The critic needs contrastive value signal
Action shape is 7D for LIBERO SmolVLA internally pads to a larger max action dimension
Success flags are correct A broken reward wrapper corrupts critic targets
Splits are episode-level Prevents leakage between train and validation

Train a Single-Task Critic

The basic critic training command is:

python scripts/train_critic.py \
  --data-dir runs/qgf_single_task_spatial3_train50 \
  --output-dir runs/qgf_single_task_spatial3_critic_train50 \
  --action-horizon 50 \
  --hidden-dim 512 \
  --depth 3 \
  --epochs 20 \
  --seed 0 \
  --device cuda

The paper and README also describe stronger variants: a K=3 critic ensemble, hidden dimension 768, depth 4, 30 epochs, and task-description features from SmolVLA VLM hidden states. For a first run, however, the single-task critic is the right debugging step. It verifies the entire path: rollout recording, success-to-go targets, action chunk extraction, checkpoint saving, and autograd through the action input.

A common runtime issue is that the outer evaluator may call policy.select_action() under torch.inference_mode(), while GAF needs autograd.grad for the critic path. The repository handles this by using torch.inference_mode(False) and torch.enable_grad() only around critic differentiation. The denoiser output is detached before the critic query, so gradients do not flow into SmolVLA.

Enable Q-Guided Inference

After training a critic:

python scripts/eval_policy.py \
  --policy-path checkpoints/smolvla_libero \
  --output-dir runs/qgf_single_task_spatial3_eval50_qgf_beta2_seed3000 \
  --env-type libero \
  --task libero_spatial \
  --task-ids '[3]' \
  --n-episodes 50 \
  --seed 3000 \
  --device cuda \
  --max-videos 0 \
  --critic-path runs/qgf_single_task_spatial3_critic_train50/critic.pt \
  --qgf-beta 2 \
  --qgf-grad-clip-norm 1.0

For ensemble guidance with an adaptive gate:

python scripts/eval_policy.py \
  --policy-path checkpoints/smolvla_libero \
  --output-dir runs/qgf_vlm_hidden_val_spatial_5_7_8_beta2_gate20_seed8000 \
  --env-type libero \
  --task libero_spatial \
  --task-ids '[5, 7, 8]' \
  --n-episodes 10 \
  --seed 8000 \
  --device cuda \
  --max-videos 0 \
  --critic-paths \
    runs/qgf_multitask_spatial0to4_critic_vlm_hidden_seed0/critic.pt \
    runs/qgf_multitask_spatial0to4_critic_vlm_hidden_seed1/critic.pt \
    runs/qgf_multitask_spatial0to4_critic_vlm_hidden_seed2/critic.pt \
  --qgf-beta 2 \
  --qgf-grad-clip-norm 1.0 \
  --qgf-uncertainty-scale 20 \
  --qgf-min-gate 0.1

When reading logs, look beyond success rate. Inspect q_guidance_norm_mean, the number of guided denoising steps, gains and regressions per episode, and critic disagreement. A setting can match baseline success while changing which episodes succeed. That still matters because it proves the guidance path is active; the critic is just not reliable enough yet.

Robot tasks used in SmolVLA evaluation across simulation and real robots - source: SmolVLA paper on arXiv
Robot tasks used in SmolVLA evaluation across simulation and real robots - source: SmolVLA paper on arXiv

Results

The main GAF numbers are:

Setting Baseline QGF/GAF Gain
Single-task, seed window 3000 34/50 = 68.0% 41/50 = 82.0% +14.0 pp
Single-task, seed window 4000 41/50 = 82.0% 43/50 = 86.0% +4.0 pp
Multi-family validation 46.0% 56.0% +10.0 pp
Locked held-out test 65.0% 67.5% +2.5 pp

The repository also reports baseline anchors:

Setting Success
LIBERO vanilla, 100 episodes 65/100 = 65.0%
LIBERO-plus spatial subset, 50 episodes 39/50 = 78.0%
LIBERO-PRO zero-shot with vanilla checkpoint, 100 episodes 1/100 = 1.0%

The correct interpretation is cautious. Single-task guidance shows a strong signal. Multi-family validation improves clearly. But the locked held-out gain is modest. This is not evidence that "adding a critic always wins." The paper shows that critic generalization is the main problem. A spatial-only critic may not transfer to object tasks. Overly strong guidance can create regressions. A weak uncertainty gate may fail to protect the sampler outside the critic's training distribution.

When to Use GAF

GAF makes sense when you already have a frozen flow-matching policy with nontrivial task competence, a simulator or robot setup for collecting success/failure rollouts, and a narrow task family you want to improve without full policy fine-tuning. It is especially attractive for SmolVLA and LeRobot users because the cost is much lower than RL fine-tuning a large VLA.

Do not use GAF as a patch for a policy that has not learned the task at all. If baseline success is near zero, the critic will not have enough successful rollouts to learn from. If the observation pipeline is wrong, the critic will learn noise. If the deployment task is far from LIBERO, you need stronger OOD detection and real deployment data.

Minimum checklist:

[ ] SmolVLA baseline runs correctly on the target task
[ ] Rollout dataset contains both successes and failures
[ ] Critic inputs are available at inference time
[ ] Train/validation split is episode-level
[ ] QGF sign is verified against the actual sampler
[ ] Beta, clip norm, and gate are chosen on validation
[ ] Held-out test is opened only after hyperparameters are frozen

Relation to Other VLA Directions

GAF sits between imitation learning and reinforcement learning. It does not require additional expert demonstrations like supervised fine-tuning. It also does not update the policy with RL gradients. The critic learns from rollouts, then intervenes only while actions are sampled. Compared with fine-tuning VLA on LIBERO with Embodied-R1.5, Embodied-R1.5 changes the policy checkpoint, while GAF keeps SmolVLA frozen. Compared with SLIM-0.5B on LIBERO, GAF does not propose a new backbone; it wraps a guidance layer around an existing sampler.

The method is also related to value-guided generation in diffusion and flow models. But robot actions are not images. They are constrained by kinematics, gripper state, action normalization, control frequency, and closed-loop execution. That is why the paper is careful: critic gradients can help, but they must be clipped, gated, and evaluated with real rollouts.

Conclusion

Guided Action Flow is interesting because the workflow is compact: freeze SmolVLA, collect LIBERO rollouts, train an action-chunk critic, then use critic gradients to guide the reverse-time flow sampler. The core idea is simple: instead of making the policy learn again, use a value signal to steer action generation during inference.

The strength of the method is that it is modular, affordable, and easy to disable. Turning off the critic returns you to the SmolVLA baseline. The weakness is critic generalization. The single-task improvement from 68.0% to 82.0% is meaningful, but the locked held-out test moves only from 65.0% to 67.5%. Deployment should therefore be experimental and disciplined: validate carefully, use ensemble gating, avoid tuning on test tasks, and do not expect a small critic to solve every distribution shift.

For beginners, the main lesson is bigger than v_guided = v_t - g / beta. GAF is a clean pattern for robot learning adaptation: frozen base policy, small critic, rollout-derived data, simple targets, and separated validation/test evaluation. That pattern is worth learning even if future versions replace the critic target or improve the OOD gate.

Related Posts

  • VLA Models in robotics
  • LeRobot hands-on guide
  • SLIM-0.5B: Lightweight VLA on LIBERO
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
SLIM-0.5B: VLA gọn nhẹ trên LIBERO
slim-0.5bvlalibero
wholebody-vla

SLIM-0.5B: VLA gọn nhẹ trên LIBERO

Hướng dẫn SLIM-0.5B, mô hình VLA manipulation gọn nhẹ với action-grounded predictive latents trên LIBERO.

8/14/202616 min read
NT
Tutorial
MiniVLA V3 MuJoCo: Robust VLA
minivlavlamujoco
wholebody-vla

MiniVLA V3 MuJoCo: Robust VLA

Hướng dẫn chạy MiniVLA trên LIBERO/MuJoCo, thêm perturbation để đo robustness và hiểu mốc 97,92% success rate.

8/10/202614 min read
NT
Tutorial
Chạy Embodied-R1.5-VLA trên LIBERO
embodied-r1.5vlalibero
wholebody-vla

Chạy Embodied-R1.5-VLA trên LIBERO

Hướng dẫn cài đặt, đánh giá LIBERO và fine-tune Embodied-R1.5-VLA cho robot manipulation từ checkpoint open-source.

6/11/202614 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