RynnVLA-Latent-2B

Stage-1 latent-action pretraining checkpoint of RynnVLA-Latent, a Mixture-of-Transformers vision-language-action model. Given a language instruction and up to six camera views, it generates a chunk of latent actions by flow matching.

  • Parameters: 2,510,917,041 (2.511 B), 1,186 tensors, all bfloat16
  • Weights: EMA snapshot at the final training step 236,442
  • Frozen during Stage 1: the vision tower and the language model (parameter regexes visual\., language_model\.)
  • Text backbone: hidden 2048, 28 layers, 16 attention heads / 8 KV heads, intermediate 6,144
  • Exported: 2026-09-28

Code, data format and training scripts: github.com/alibaba-damo-academy/RynnVLA-Latent


Read this first: what this checkpoint is not

This is a Stage-1 checkpoint. Its flow-matching target is the latent action, not a robot action, so Stage 1 consumes no action labels at all.

As shipped, processor_config.json carries an empty action/state schema ("schema": {"action": {}, "state": {}}, "use_state": false), and the eval adapters in the repository explicitly refuse a Stage-1 checkpoint for closed-loop control — validate_libero_schema raises "Use a Stage2 action checkpoint, not a Stage1 latent-only checkpoint" whenever use_latent_actions is true.

So: do not point LIBERO / RoboTwin / VLABench evaluation at this repo. Use it as the initialization for Stage 2, which keeps the same flow-matching objective and retargets it from latent actions to a robot-specific action space. action_dim = 81 and action_chunk_size = 30 are declared in the config and carried in the architecture, but Stage-1 training does not use them.

Latent-action protocol (608-dim ktoken_zcam)

Stage 1 trains against latent actions produced by RynnLAM, which labels raw RGB frame pairs and needs no action space — that is what lets real-robot trajectories, simulation rollouts and human egocentric video share one target representation.

Field Value
latent_action_dim 608 = 8×64 k-tokens (512) + 64 z + 32 camera-pose
latent_action_chunk_size 6
latent_action_stride 5
Labeling cadence gap = 4, pair_stride = 4 — one latent action per 4 RGB frames

Architecture

Config Value
model_type rynn_brain_vla
architectures Qwen3VLForConditionalGeneration
action_head_type expert
expert_backbone qwen3_vl
expert_hidden_size 768
time_conditioning adaln
num_view_slots 6 (head, left_wrist, right_wrist, front_third, side_left, side_right)
use_view_cond_slots true
Vision encoder qwen3_vl, depth 24, hidden 1024, patch 16, spatial merge 2, deepstack layers [5, 11, 17]
Tokenizer Qwen3 BPE, 151,936 embedding rows; vocabulary identical to the public Qwen3-VL tokenizer (151,643 tokens / 151,387 merges) plus one extra special token `<
transformers_version 5.2.0

Up to 6 camera roles are carried per sample with a slot_mask marking the valid ones, so a source with one camera and a source with four train in the same batch.

Images are normalized with image_mean = image_std = [0.5, 0.5, 0.5], i.e. rescaled to [-1, 1] (processor_class = RynnBrainVLAProcessor). The separate action_norm_type field is mean_std; it governs action/state normalization and is inert at Stage 1, where schema.action and schema.state are both empty.

Loading

The custom model_type is resolved by the rynnvla package, so import it first:

import torch
from rynnvla.models.rynn_brain_vla import RynnBrainVLAModel, RynnBrainVLAProcessor

path = "./RynnVLA-Latent-2B"   # a local directory, e.g. from snapshot_download below
model = RynnBrainVLAModel.from_pretrained(
    path, dtype=torch.bfloat16, attn_implementation="flash_attention_2",
)
processor = RynnBrainVLAProcessor.from_pretrained(path)

Verified on transformers==5.2.0 / torch==2.7.1 with both attn_implementation="eager" and "flash_attention_2": the checkpoint materializes with zero missing and zero unexpected keys, the parameter count equals the safetensors header count exactly (2,510,917,041), and no tensor contains a non-finite value. The only exactly-zero tensors are the three action-head biases (state_proj.bias, action_in_proj.bias, action_out_proj.bias), which Stage 1 does not train; their weights are non-zero.

Download from ModelScope:

from modelscope import snapshot_download
model_dir = snapshot_download("DAMO_Academy/RynnVLA-Latent-2B")

Files

File Bytes SHA-256
LICENSE 11,358 cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30
chat_template.jinja 5,292 3636d0f0bd6bef02654cdffdc447b79cb2cef8ab02cc75267345946291a489e4
config.json 3,208 8ff25f9a6a5c12661da19c270f8a6e4ba4a766e83820acde648ea59730496fd3
export_provenance.json 594 8c314bd7eab7a1bb4f5f2b71a858f684b38478be72c3fa388aefc52f0f54221d
model.safetensors 5,021,978,274 e3e7155dda69b38aa05fc6a107353d8fe3a7499bd755ea80db16ec3299992784
processor_config.json 1,501 2d3f06f58b85154a00da0905c853e92fe760e2e3a6b066935812707024a95e58
tokenizer.json 11,422,840 f9c0d33d111cb70baf6140ce788268a980ad8b6f70981c35b76193bfa5fb45aa
tokenizer_config.json 492 e6ee285337a50ab8c6572ac8967fd02fc3da292bc50bc2835b0d873c4fbe61b7

export_provenance.json records the source step, the EMA selection, the frozen-parameter regexes, the source weight digest and the tensor count. Internal absolute paths were removed from it before release, which changes only that file's own digest.

Training

Stage-1 latent-action pretraining on the full latent-action corpus, global batch size 512, run to completion at step 236,442. The released weights are the EMA snapshot of that final step.

License

Apache License 2.0.

Links

Downloads last month
19
Safetensors
Model size
3B params
Tensor type
BF16
·
Video Preview
loading

Collection including Alibaba-DAMO-Academy/RynnVLA-Latent-2B