Vision-Action Policy   2025-2026

PRANA
Three iterations.
One robot that grasps.

I started with a deterministic baseline that barely reached the screwdriver. I ended with a flow matching policy that uses correlated noise to pick it up and place it in the box. I built all of it on a $300 arm with one laptop GPU.

3
Architectures
123
Episodes
10 Hz
Control rate
8 GB
Single GPU
Evolution

From L1 regression
to flow matching

Each version fixed the failures of the last one. v1 taught me what does not work. v2 added the right inductive biases. v3 upgraded the eyes.

Version 1
Self-attention + L1 loss
All tokens sat in one self-attention pool. Deterministic regression learned the average of the demos, so it produced a trajectory that matched none of them. A dead language encoder wasted 262MB. The unfrozen ViT overfitted on 83 episodes.
Version 2
Flow matching + cross-attention
I split it into an encoder and a decoder. Action queries cross-attend to visual context instead of competing with it. Flow matching with correlated noise handles multimodal actions. I used a frozen ViT-Tiny and rolling inpainting for smooth chunk transitions.
Version 3
DINOv2 self-supervised vision
I kept the same flow matching decoder as v2, but DINOv2 ViT-S/14 replaces ViT-Tiny. Self-supervised spatial features encode where objects are, not only what they are. 384d embeddings and 256 tokens per camera. The result is smoother and generalizes better.
Version 1: Baseline
PRANA v1

The one that
almost worked

I trained this on 83 teleoperation episodes. It used a ViT-Tiny vision encoder, a PaliGemma tokenizer (which received zeros), a 4 layer self-attention transformer, and 50 step action chunking with L1 loss. It reached for the screwdriver but could not grasp it consistently.

The failures taught me a lot. Self-attention let the action queries contaminate each other before they saw the scene. Deterministic regression averaged out the multimodal demonstrations. The unfrozen backbone overfitted in 2000 steps.

v1: reaches but struggles to grasp
Version 2: Flow Matching
PRANA v2

Iterative denoising with
correlated noise

Instead of predicting one average trajectory, the model starts from noise shaped like real robot motions and refines it step by step into precise actions. I added cross-attention so the decoder looks at the scene before it decides what to do.

PRANA v2 Architecture
v2 architecture: context encoder plus cross-attention action decoder with flow matching
  • Frozen ViT-Tiny with camera ID embeddings
  • 4 layer context encoder (self-attention over vision plus state)
  • 7 layer action decoder (cross-attention to context)
  • Flow matching: 10 Euler denoising steps at inference
  • Correlated noise from Cholesky decomposition of action covariance
  • Rolling inpainting: execute 40, save 10 for smooth transitions
  • ~11M trainable params, 100K training steps
  • 22ms per chunk inference on RTX 5060
v2: picks up screwdriver and places in box
Version 3: DINOv2 Vision
PRANA v3

Same decoder.
Better eyes.

DINOv2 ViT-S/14 replaces ViT-Tiny. Its self-supervised pretraining on 142M images means the backbone encodes where objects are in space, not only what class they are. It gives 384 dimensional embeddings and 256 tokens per camera, which is 2.6x more visual information.

PRANA v3 Architecture
v3 architecture: DINOv2 backbone with 512 visual tokens feeding the same flow matching decoder
  • DINOv2 ViT-S/14 frozen backbone (22M params)
  • 384d embeddings → 256 tokens per camera (vs 192d, 197 tokens)
  • 512 total visual tokens (vs 394 in v2)
  • Same flow matching decoder, same correlated noise
  • Smoother trajectories, better generalization to object placement
  • ~30M trainable params
  • Less jittery than v2, reduced position error at grasp point
v3: smoother grasp, better generalization with DINOv2
Comparison

Side by side

Component
v1
v2
v3
Vision
ViT-Tiny (unfrozen)
ViT-Tiny (frozen)
DINOv2 ViT-S/14 (frozen)
Attention
Self-attention only
Cross-attention decoder
Cross-attention decoder
Action head
L1 regression
Flow matching (10 steps)
Flow matching (10 steps)
Noise
N/A
Correlated (β=0.5)
Correlated (β=0.5)
Visual tokens
394
394
512
Inference
~5ms
~22ms
~30ms
Grasps
With assistance
Yes
Yes, smoother
Places in box
No
With assistance
With assistance
v2: ViT-Tiny plus flow matching
v3: DINOv2 plus flow matching
Links

Open source.
Everything.

I released the architecture, the training scripts, the deployment code, the model weights, the dataset, and the mistakes along the way.