Skip to main content

A toolbox for tracking and visualizing the real-world deployment process of VLA models

Project description

๐Ÿงช VLA-Lab

The Missing Toolkit for Vision-Language-Action Model Deployment

Python 3.8+ License: MIT PyPI version PRs Welcome

Debug โ€ข Visualize โ€ข Analyze your VLA deployments in the real world

๐Ÿš€ Quick Start ยท ๐Ÿ“– Documentation ยท ๐ŸŽฏ Features ยท ๐Ÿ”ง Installation


๐ŸŽฏ Why VLA-Lab?

Deploying VLA models to real robots is hard. You face:

  • ๐Ÿ•ต๏ธ Black-box inference โ€” Can't see what the model "sees" or why it fails
  • โฑ๏ธ Hidden latencies โ€” Transport delays, inference bottlenecks, control loop timing issues
  • ๐Ÿ“Š No unified logging โ€” Every framework logs differently, making cross-model comparison painful
  • ๐Ÿ”„ Tedious debugging โ€” Replaying failures requires manual log parsing and visualization

VLA-Lab solves this. One unified toolkit for all your VLA deployment needs.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                              VLA-Lab Architecture                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                             โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚   Robot      โ”‚    โ”‚   Inference Server   โ”‚    โ”‚    VLA-Lab         โ”‚   โ”‚
โ”‚   โ”‚   Client     โ”‚โ”€โ”€โ”€โ–ถโ”‚   (DP / GR00T / ...) โ”‚โ”€โ”€โ”€โ–ถโ”‚    RunLogger       โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                             โ”‚              โ”‚
โ”‚                                                             โ–ผ              โ”‚
โ”‚                          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
โ”‚                          โ”‚            Unified Run Storage            โ”‚      โ”‚
โ”‚                          โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚      โ”‚
โ”‚                          โ”‚   โ”‚meta.json โ”‚ steps.jsonlโ”‚ artifacts/โ”‚  โ”‚      โ”‚
โ”‚                          โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚      โ”‚
โ”‚                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
โ”‚                                             โ”‚                              โ”‚
โ”‚                                             โ–ผ                              โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚   โ”‚                        Visualization Suite                           โ”‚  โ”‚
โ”‚   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚  โ”‚
โ”‚   โ”‚  โ”‚  Inference  โ”‚  โ”‚     Latency      โ”‚  โ”‚       Dataset           โ”‚ โ”‚  โ”‚
โ”‚   โ”‚  โ”‚   Viewer    โ”‚  โ”‚     Analyzer     โ”‚  โ”‚       Browser           โ”‚ โ”‚  โ”‚
โ”‚   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚  โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โœจ Features

๐Ÿ“Š Unified Logging Format

Standardized run structure with JSONL + image artifacts. Works across all VLA frameworks.

๐Ÿ”ฌ Inference Replay

Step-by-step playback with multi-camera views, 3D trajectory visualization, and action overlays.

๐Ÿ“ˆ Deep Latency Analysis

Profile transport delays, inference time, control loop frequency. Find your bottlenecks.

๐Ÿ—‚๏ธ Dataset Browser

Explore Zarr-format training/evaluation datasets with intuitive UI.

๐Ÿ”Œ Framework Support

Framework Status Integration
Diffusion Policy โœ… Supported Drop-in logger
NVIDIA GR00T โœ… Supported Native adapter
OpenVLA-OFT ๐Ÿšง Coming Soon โ€”
Pi0.5 ๐Ÿšง Coming Soon โ€”

๐Ÿ”ง Installation

# Basic installation
pip install vlalab

# Full installation (with Zarr dataset support)
pip install "vlalab[full]"

# Development installation
git clone https://github.com/VLA-Lab/VLA-Lab.git
cd VLA-Lab
pip install -e ".[dev]"

๐Ÿš€ Quick Start

Minimal Example (3 Lines!)

import vlalab

# Initialize a run
run = vlalab.init(project="pick_and_place", config={"model": "diffusion_policy"})

# Log during inference
vlalab.log({"state": obs["state"], "action": action, "images": {"front": obs["image"]}})

Full Example

import vlalab

# Initialize with detailed config
run = vlalab.init(
    project="pick_and_place",
    config={
        "model": "diffusion_policy",
        "action_horizon": 8,
        "inference_freq": 10,
    },
)

# Access config anywhere
print(f"Action horizon: {run.config.action_horizon}")

# Inference loop
for step in range(100):
    obs = get_observation()
    
    t_start = time.time()
    action = model.predict(obs)
    latency = (time.time() - t_start) * 1000
    
    # Log everything in one call
    vlalab.log({
        "state": obs["state"],
        "action": action,
        "images": {"front": obs["front_cam"], "wrist": obs["wrist_cam"]},
        "inference_latency_ms": latency,
    })
    
    robot.execute(action)

# Auto-finishes on exit, or call manually
vlalab.finish()

Launch Visualization

# One command to view all your runs
vlalab view
๐Ÿ“ธ Screenshots (Click to expand)

Coming soon: Inference Viewer, Latency Analyzer, Dataset Browser screenshots


๐Ÿ“– Documentation

Core Concepts

Run โ€” A single deployment session (one experiment, one episode, one evaluation)

Step โ€” A single inference timestep with observations, actions, and timing

Artifacts โ€” Images, point clouds, and other media saved alongside logs

API Reference

vlalab.init() โ€” Initialize a run
run = vlalab.init(
    project: str = "default",     # Project name (creates subdirectory)
    name: str = None,             # Run name (auto-generated if None)
    config: dict = None,          # Config accessible via run.config.key
    dir: str = "./vlalab_runs",   # Base directory (or $VLALAB_DIR)
    tags: list = None,            # Optional tags
    notes: str = None,            # Optional notes
)
vlalab.log() โ€” Log a step
vlalab.log({
    # Robot state
    "state": [...],                    # Full state vector
    "pose": [x, y, z, qx, qy, qz, qw], # Position + quaternion
    "gripper": 0.5,                    # Gripper opening (0-1)
    
    # Actions
    "action": [...],                   # Single action or action chunk
    
    # Images (multi-camera support)
    "images": {
        "front": np.ndarray,           # HWC numpy array
        "wrist": np.ndarray,
    },
    
    # Timing (any *_ms field auto-captured)
    "inference_latency_ms": 32.1,
    "transport_latency_ms": 5.2,
    "custom_metric_ms": 10.0,
})
RunLogger โ€” Advanced API

For fine-grained control over logging:

from vlalab import RunLogger

logger = RunLogger(
    run_dir="runs/experiment_001",
    model_name="diffusion_policy",
    model_path="/path/to/checkpoint.pt",
    task_name="pick_and_place",
    robot_name="franka",
    cameras=[
        {"name": "front", "resolution": [640, 480]},
        {"name": "wrist", "resolution": [320, 240]},
    ],
    inference_freq=10.0,
)

logger.log_step(
    step_idx=0,
    state=[0.5, 0.2, 0.3, 0, 0, 0, 1, 1.0],
    action=[[0.51, 0.21, 0.31, 0, 0, 0, 1, 1.0]],
    images={"front": image_rgb},
    timing={
        "client_send": t1,
        "server_recv": t2,
        "infer_start": t3,
        "infer_end": t4,
    },
)

logger.close()

CLI Commands

# Launch visualization dashboard
vlalab view [--port 8501]

# Convert legacy logs (auto-detects format)
vlalab convert /path/to/old_log.json -o /path/to/output

# Inspect a run
vlalab info /path/to/run_dir

๐Ÿ“ Run Directory Structure

vlalab_runs/
โ””โ”€โ”€ pick_and_place/                 # Project
    โ””โ”€โ”€ run_20240115_103000/        # Run
        โ”œโ”€โ”€ meta.json               # Metadata (model, task, robot, cameras)
        โ”œโ”€โ”€ steps.jsonl             # Step records (one JSON per line)
        โ””โ”€โ”€ artifacts/
            โ””โ”€โ”€ images/             # Saved images
                โ”œโ”€โ”€ step_000000_front.jpg
                โ”œโ”€โ”€ step_000000_wrist.jpg
                โ””โ”€โ”€ ...

๐Ÿ”— Framework Integration

Diffusion Policy

# In your inference_server.py
from vlalab import RunLogger

class DPInferenceServer:
    def __init__(self, checkpoint_path):
        self.logger = RunLogger(
            run_dir=f"runs/{datetime.now():%Y%m%d_%H%M%S}",
            model_name="diffusion_policy",
            model_path=str(checkpoint_path),
        )
    
    def infer(self, obs):
        action = self.model(obs)
        self.logger.log_step(step_idx=self.step, ...)
        return action

NVIDIA GR00T

# In your inference_server_groot.py
from vlalab import RunLogger

class GrootInferenceServer:
    def __init__(self, model_path, task_prompt):
        self.logger = RunLogger(
            run_dir=f"runs/{datetime.now():%Y%m%d_%H%M%S}",
            model_name="groot",
            model_path=str(model_path),
            task_prompt=task_prompt,
        )

๐Ÿ—บ๏ธ Roadmap

  • Core logging API
  • Streamlit visualization suite
  • Diffusion Policy adapter
  • GR00T adapter
  • OpenVLA adapter
  • Cloud sync & team collaboration
  • Real-time streaming dashboard
  • Automatic failure detection
  • Integration with robot simulators

๐Ÿค Contributing

We welcome contributions! See our Contributing Guide for details.

# Setup development environment
git clone https://github.com/VLA-Lab/VLA-Lab.git
cd VLA-Lab
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black src/
ruff check src/ --fix

๐Ÿ“„ License

MIT License โ€” see LICENSE for details.


โญ Star us on GitHub if VLA-Lab helps your research!

Built with โค๏ธ for the robotics community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vlalab-0.1.0.tar.gz (40.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vlalab-0.1.0-py3-none-any.whl (45.7 kB view details)

Uploaded Python 3

File details

Details for the file vlalab-0.1.0.tar.gz.

File metadata

  • Download URL: vlalab-0.1.0.tar.gz
  • Upload date:
  • Size: 40.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for vlalab-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ebb4a7581ce40ac3b5c72da2c1551794fdc0bb72a8a9832e2c5ebe2ebbdb5fa6
MD5 c63b51f07dfa0a7665dad07c5c3d1e7d
BLAKE2b-256 d56f9499969fd9e3f517ac51a20d5c8a3e00ef9c262c9ee6fca3ae9bef2ce4f2

See more details on using hashes here.

File details

Details for the file vlalab-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: vlalab-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 45.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for vlalab-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dadae68255f94e6139aad2e8fc6f860fe64bb025d4498d1252615fda41d4ecfe
MD5 7b1d151f51f91391fe7d254eba63dc5d
BLAKE2b-256 46fc4e2670d976d6ccb7d77dd8715975fcb244deaba84f0d418350de0a73e89b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page