OpenVLA-7B β€” LIBERO-Spatial LoRA (20k steps, with gradient clipping)

Fine-tuned from openvla/openvla-7b on the libero_spatial_no_noops task suite using LoRA (rank=32) for 20,000 gradient steps across two sequential runs on an NVIDIA GH200 (ARM64/aarch64).

Key contribution: includes a gradient clipping fix missing from the upstream OpenVLA training script β€” without it, training collapses at ~6k steps due to an unclamped gradient spike.


Evaluation Results

Evaluated on LIBERO-Spatial (10 tasks, 5 trials per task = 50 episodes total).

Setup Steps Score
Official paper (x86, flash-attn) 10k 84.7%
Official openvla-7b-finetuned-libero-spatial (ARM64 eval) 10k 37/50 = 74%
Our run 1 β€” no gradient clipping 10k 20/50 = 39%
Our run 2 β€” with gradient clipping 10k 28/50 = 56%
This checkpoint β€” grad clipping, 20k steps (ARM64 eval) 20k 36/50 = 72%

Our 20k checkpoint matches the official published 10k checkpoint (74% vs 72%, within statistical noise at 5 trials/task) on the same ARM64 hardware, confirming the gradient clipping fix is sufficient to recover training stability.

The ~12pp gap vs. the paper (84.7%) is a hardware effect: the official paper used x86 with native flash attention; on ARM64 the pre-built flash-attn binary is x86-only. Flash-attn 2.5.8 was built from source for run 3 but not run 2, so training used eager attention for most of the run. The official checkpoint evaluated at 74% on the same ARM64 setup, confirming this gap is hardware-driven, not a model quality issue.

Per-task breakdown (this checkpoint, 5 trials each)

Task Successes Rate
Task 1 3/5 60%
Task 2 4/5 80%
Task 3 4/5 80%
Task 4 5/5 100%
Task 5 3/5 60%
Task 6 2/5 40%
Task 7 5/5 100%
Task 8 5/5 100%
Task 9 3/5 60%
Task 10 2/5 40%
Total 36/50 72%

Training Curves (20k steps)

Stitched training curves β€” run 2 + run 3

  • Green = Run 2 (steps 0–10k, starting from base openvla/openvla-7b)
  • Blue = Run 3 (steps 10k–20k, starting from the run 2 merged checkpoint)

Loss descends steadily from ~2.4 β†’ ~0.68. Action token accuracy rises from ~0.05 β†’ ~0.82. No loss spikes β€” contrast with run 1 (no gradient clipping) which spiked at step ~6k and never recovered.


Training Details

Setting Value
Base model openvla/openvla-7b
Dataset libero_spatial_no_noops
Total steps 20,000 (2 Γ— 10k sequential runs)
Batch size 16
Learning rate 5e-4
LoRA rank 32
LoRA dropout 0.0
Quantization false
Image augmentation true
Shuffle buffer 10,000
Hardware NVIDIA GH200 (ARM64/aarch64, 480GB HBM3)

Resuming from a checkpoint

finetune.py has no native resume support. We resumed by setting VLA_PATH to the merged run 2 checkpoint. The model starts from those weights (all learned knowledge preserved); only the step counter and optimizer state reset. This is equivalent to a warm-start.


Key Fix: Gradient Clipping

The upstream vla-scripts/finetune.py in the OpenVLA repo is missing gradient norm clipping before optimizer.step(). A single batch with an outlier action can produce an unclamped gradient large enough to permanently corrupt the model weights.

What we saw: In run 1 (no clipping), loss jumped from 2.2 β†’ 5.2 at step ~6k and action accuracy collapsed from 0.35 β†’ 0.0 and never recovered. Final score: 39%.

The fix:

# Add before optimizer.step() in the training loop:
torch.nn.utils.clip_grad_norm_(trainable_params, max_norm=1.0)
optimizer.step()

With clipping, both runs (2 and 3) converged cleanly. See openvla/openvla#333 for the full analysis with loss curves.


Usage

This is a merged checkpoint β€” LoRA adapter weights are already merged into the base model. No PEFT library needed.

import torch
from transformers import AutoModelForVision2Seq, AutoProcessor

processor = AutoProcessor.from_pretrained(
    "shant0602/openvla-7b-libero-spatial-lora-20k",
    trust_remote_code=True,
)
model = AutoModelForVision2Seq.from_pretrained(
    "shant0602/openvla-7b-libero-spatial-lora-20k",
    torch_dtype=torch.bfloat16,
    trust_remote_code=True,
).cuda()

# Inference
inputs = processor(image, instruction, return_tensors="pt").to("cuda")
action = model.predict_action(**inputs, unnorm_key="libero_spatial", do_sample=False)

The unnorm_key="libero_spatial" is required β€” it selects the action normalization statistics from dataset_statistics.json that were computed from the LIBERO-Spatial training data.

Downloads last month
4
Safetensors
Model size
8B params
Tensor type
BF16
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for shant0602/openvla-7b-libero-spatial-lora-20k

Adapter
(32)
this model

Dataset used to train shant0602/openvla-7b-libero-spatial-lora-20k