The AY-Robots arena leaderboard showing 85 vision-language-action models with 332 benchmark results in a sortable table, including RDT-1B
RDT-1Bdiffusion policybimanual manipulationVLA modelsrobot learning

RDT-1B: the 1.2B Diffusion Foundation Model for Bimanual Robots

AY-Robots ResearchAugust 23, 202622 min read

RDT-1B is a 1.2B diffusion transformer for bimanual manipulation. Its 128-dim unified action space, the real fine-tuning commands, hardware needs and honest limits.

What you need to know

  • RDT-1B is a 1.2 billion parameter Diffusion Transformer for bimanual manipulation, arXiv 2410.07864 by Liu et al. of the TSAIL group at Tsinghua, an ICLR 2025 poster.
  • It predicts 64 future actions at once from a language instruction, up to three RGB views with two frames of history, proprioception and the control frequency.
  • Its core idea is a 128-dimensional physically interpretable unified action space: every robot writes joint angles, gripper width, end effector pose and base velocity into fixed slots. That is what let 46 datasets train one model.
  • Pre-training took 1M+ trajectories and 21 TB on 48 H100 80 GB GPUs for a month. You are not repeating that; fine-tuning is the realistic path.
  • The checkpoint is 2.46 GB and MIT licensed, but T5-XXL rides along with it. On a 24 GB card you must precompute language embeddings or the text encoder alone will not fit.
  • RDT-1B is not one of the five policies AY-Robots trains. It is in the comparison arena, not the trainer.

What RDT-1B actually is

RDT-1B stands for Robotics Diffusion Transformer. It is a vision-language-action model from the TSAIL group at Tsinghua University, released in October 2024 and presented as a poster at ICLR 2025. The goal is narrower than the phrase foundation model suggests. The paper puts it directly: multi-robot data is there to improve generalisation in bimanual manipulation, not to build a cross-embodiment model. Multi-robot pre-training is the means, a dual-arm policy is the end.

The design choice worth reading about is not the parameter count. It is how the model handles the fact that a Franka arm, an ALOHA rig and a wheeled manipulator all describe motion differently. RDT does not learn a head per robot, and it does not discretise actions into text tokens the way RT-2 does. It writes every robot into one fixed 128-slot vector where each slot has a physical meaning, then trains a diffusion model on that vector.

PropertyValueWhere it is stated
Parameters1.2 Bpaper, Table 9
Layers / hidden size / heads28 / 2048 / 32paper Table 9 and configs/base.yaml
Action chunk size64 future actionsconfigs/base.yaml (action_chunk_size)
Camera views3 (exterior, right wrist, left wrist)configs/base.yaml (num_cameras)
Image history2 framesconfigs/base.yaml (img_history_size)
Vision encodergoogle/siglip-so400m-patch14-384, frozenpaper Table 8 and README
Language encodergoogle/t5-v1_1-xxl, frozenpaper Table 8 and README
Action / state vector128 dimensionsconfigs/base.yaml (state_dim), configs/state_vec.py
Released checkpointpytorch_model.bin, 2,456,755,578 bytes (about 2.46 GB)Hugging Face file listing
LicenceMIT for code, weights and datarepo README
Smaller siblingRDT-170M: hidden 1024, depth 14, 332,520,250 bytesRDT-170M model card and config.json

RDT-170M is the paper's ablation model, released two weeks later as a lower-VRAM option. Expect one discrepancy across sources: the paper calls it RDT (small) at 166 M parameters, the model card calls it RDT-170M. Same model. Both sizes have entries in the model arena: RDT-1B and RDT-170M.

The architecture: three modifications to a Diffusion Transformer

The backbone is a DiT with cross-attention, the same family as the image diffusion transformers, adapted for a time series of joint commands rather than a pixel grid. The paper lists exactly three key modifications to the standard block, each with a stated reason and an ablation behind it.

  • QKNorm and RMSNorm together. Robot physical quantities arrive in an unstable numerical range, so query-key normalisation goes into every attention layer. LayerNorm becomes RMSNorm because its centering step causes token shift and attention shift, which the authors argue destroys the symmetry of a time series. Figure 4 shows the loss curve going unstable without these.
  • MLP decoder instead of a linear head. The projection from latent space back to physical action space is a nonlinear MLP, because robot dynamics are nonlinear and a linear readout loses the dexterity that depends on them.
  • Alternating condition injection. Image tokens vastly outnumber language tokens, so injecting both into one cross-attention layer lets the images overshadow the instruction. The blocks alternate instead: one layer attends to language, the next to images.
yaml
# configs/base.yaml (excerpt, thu-ml/RoboticsDiffusionTransformer)
common:
  img_history_size: 2
  action_chunk_size: 64
  num_cameras: 3
  state_dim: 128

model:
  lang_adaptor: mlp2x_gelu
  img_adaptor: mlp2x_gelu
  state_adaptor: mlp3x_gelu
  lang_token_dim: 4096      # T5-XXL
  img_token_dim: 1152       # SigLIP so400m
  state_token_dim: 128
  rdt:
    # 1B: num_head 32 hidden_size 2048
    hidden_size: 2048
    depth: 28
    num_heads: 32
    cond_pos_embed_type: multimodal
  noise_scheduler:
    type: ddpm
    num_train_timesteps: 1000
    num_inference_timesteps: 5
    beta_schedule: squaredcos_cap_v2  # Critical choice
    prediction_type: sample
    clip_sample: False
The shipped configuration. The README warns that modifying anything under model breaks loading of the pre-trained checkpoint. The one time you must edit it is switching to RDT-170M, whose own config.json carries hidden_size 1024 and depth 14.

The low-dimensional inputs, proprioception, the noisy action chunk, the control frequency and the diffusion timestep, are each encoded by MLPs with Fourier features and concatenated along the sequence axis, giving a token sequence of length 1 + Ta + 1 + 1 that the paper calls in-context conditioning. Language and images are cross-attention conditions, outside that sequence.

Why the control frequency is an input

RDT trains on datasets recorded at very different rates, from 3 Hz for RT-1 to 15 Hz for DROID. Feeding the control frequency c in as a conditioning variable tells the model how far apart in time the 64 actions in a chunk are meant to be. Every dataset declares its rate in configs/dataset_control_freq.json; the agilex placeholder sits at 25, which is why the example deployment script passes --ctrl_freq=25. Fine-tune at one rate and deploy at another and that mismatch is yours, not the model's.

Training uses a DDPM scheduler with 1000 timesteps and a squared-cosine beta schedule. At sampling time the paper reports DPM-Solver++ cutting the denoising loop from 100 steps to 5, and the shipped config sets num_inference_timesteps to 5 to match. On the robot's onboard RTX 4090 24 GB that gave 6 Hz of action chunks and 381 Hz of individual actions, since each chunk holds 64. During training each input modality is independently masked with probability 0.1, which is what buys tolerance for a missing camera.

The 128-dimensional unified action space

This is the part worth stealing even if you never run the model. Instead of normalising every dataset into an anonymous [-1, 1] box, RDT defines one 128-slot vector where slot 30 always means right end effector x in metres and slot 10 always means right gripper opening. A robot fills the slots it has and pads the rest. The mapping is in configs/state_vec.py and in Table 4 of the paper.

Index rangePhysical quantity
0 to 9Right arm joint positions (arm_joint_0_pos and up)
10 to 14Right gripper joint positions (index 10 is also the alias gripper_open)
15 to 24Right arm joint velocities
25 to 29Right gripper joint velocities
30 to 32Right end effector position, x y z
33 to 38Right end effector 6D pose, the six rotation components eef_angle_0 to eef_angle_5
39 to 41Right end effector linear velocities
42 to 44Right end effector angular velocities, roll pitch yaw
45 to 49Reserved
50 to 99The same eight blocks again for the left arm
100 to 101Base linear velocities
102Base angular velocity
103 to 127Reserved

The consequences are practical. An arm with fewer than ten joints fills only the leading slots of its block: a six degree of freedom arm fills the first six. A single-arm follower fills the right arm block, never the left, because that is how the single-arm pre-training data was mapped. Units are SI units, which the README notes keeps most values inside [-1, 1] anyway. The one quantity that gets normalised is gripper width, min-max scaled to [0, 1], because gripper travel is arbitrary across hardware.

The three traps in the action vector

1. Do not normalise. No physical quantity except gripper width is normalised during pre-training. Z-score your joint angles first and you hand the model numbers whose physical meaning no longer matches any of the 46 pre-training datasets, so the prior stops helping. 2. Zero is not padding. A velocity of 0 means standing still. RDT concatenates a 0/1 vector marking padded dimensions onto the action and proprioception vectors before encoding, giving a 256-dimensional input. Write your own loader and you must keep that mask honest. 3. Single-arm goes right. A single arm in the left block silently costs you most of the pre-training benefit.

python
# data/hdf5_vla_dataset.py, the part you actually write (around L180-194).
# See configs/state_vec.py for the full name -> index mapping.
from configs.state_vec import STATE_VEC_IDX_MAPPING
import numpy as np

def fill_in_state(values):
    # values: (T, n_joints) joint angles in radians, gripper last
    n_arm = values.shape[1] - 1
    uni_vec = np.zeros((values.shape[0], 128), dtype=np.float32)

    idx = [STATE_VEC_IDX_MAPPING[f"arm_joint_{i}_pos"] for i in range(n_arm)]
    uni_vec[:, idx] = values[:, :n_arm]

    # gripper width, min-max normalised to [0, 1] - the one exception
    uni_vec[:, STATE_VEC_IDX_MAPPING["gripper_open"]] = values[:, -1]
    return uni_vec
A single-arm follower writes into the right-arm slots. arm_joint_i_pos and gripper_open are aliases of the right-arm names, so this is already the right block. Everything else stays padded and is flagged by the availability mask.

If your action space carries end effector rotation, the repo requires the 6D representation from Zhou et al. rather than Euler angles or quaternions, and ships docs/test_6drot.py to convert. The README notes the mapping is not reversible: different Euler angles can be equivalent and land on the same 6D vector.

What went into pre-training, and why you will not repeat it

The pre-training collection is 46 datasets, more than 1 million trajectories and 21 TB on disk. Each dataset starts at a sampling weight of the square root of its size, so the RT-1 dataset with its 130K trajectories does not swamp a 1K-trajectory bimanual set, and the authors then raised the weights of datasets whose intermediate loss converged slowly. Familiar names include Open X-Embodiment, DROID, BridgeData V2, RH20T and RoboSet.

StageDataComputeSteps
Pre-training46 datasets, 1M+ trajectories, 21 TB48 x H100 80 GB, about one month1,000,000
Fine-tuning (paper)6K+ self-collected bimanual trajectories, 300+ tasks, 3M+ framesthe same 48 GPUs, about three days130,000
Fine-tuning (your run)your own recorded episodesone GPU is enough to start150,000 recommended minimum

One appendix detail is worth flagging because papers usually bury it: the reported fine-tune did not start from the 1M-step pre-trained checkpoint. Scheduling forced the authors to branch from the 500K-step one. The published RDT-1B weights are nonetheless the 1M-step checkpoint, while RDT-170M is a 500K-step checkpoint.

Their fine-tuning dataset is instructive: 300+ tasks, 100+ rigid and non-rigid objects, 15+ rooms with different lighting, and GPT-4-Turbo generating 100 expanded instructions plus one simplified one per task, so the language side sees many phrasings of the same job. That last trick is nearly free and worth copying when you build your own LeRobot dataset, as argued in how to collect high-quality VLA training data.

What it takes to run RDT-1B

The checkpoint is small by 2026 standards. The problem is the frozen encoder riding along with it: T5-XXL is by a wide margin the largest component in the pipeline, and the README says outright that on an RTX 4090 or lower it may not fit. That is the most common reason a first RDT run dies.

What you needDetail
Python3.10.0, conda env named rdt in the README
PyTorch2.1.0 with torchvision 0.16.0, CUDA 12.1 wheels
Pinned in requirements.txtdeepspeed 0.14.2, accelerate 0.30.1, diffusers 0.27.2, transformers 4.41.0, timm 1.0.3, h5py 3.11.0, wandb 0.17.0
flash-attninstalled with --no-build-isolation, after packaging 24.0
Weights to downloadrdt-1b (2.46 GB), google/t5-v1_1-xxl, google/siglip-so400m-patch14-384
Disk bufferbuf_path of at least 400 GB, used during pre-training only
Distributed launcherDeepSpeed, ZeRO-2 by default via configs/zero2.json
Under 24 GB VRAMprecompute language embeddings, drop to RDT-170M, or move to ZeRO-3 with offload
RDT-1B as a choice of policy
What it buys you
  • A physical action representation. Joint angles stay in radians, positions stay in metres, so the pre-training prior transfers instead of being rescaled away.
  • Native bimanual support: a left block and a right block from the start, unlike policies retrofitted from single-arm setups.
  • Diffusion handles multi-modal action distributions, the actual failure mode when two arms could each reasonably do the task.
  • MIT licence on code, weights and data, which is rare in this space.
  • A 170M sibling with the same interfaces and the same 128-slot action space, so you can prototype the pipeline on a small card.
What it costs you
  • T5-XXL is a heavy dependency for a 1.2 B action model, and it is the component that will not fit on 24 GB.
  • No LeRobot integration and no generic adapter: only an HDF5 example you edit into a loader yourself.
  • The repo publishes no single-GPU wall-clock figure to plan a 150,000 step run against.
  • Swapping to RDT-170M is not just a checkpoint id. You must edit hidden_size and depth in configs/base.yaml, the same file the README tells you not to touch.
  • Upstream attention has moved to RDT2. The RDT-1B repo was last pushed on 21 January 2026.

Fine-tuning RDT-1B on your own data

This is the real path. Nobody outside a large lab pre-trains this model. What follows is the upstream fine-tuning flow as documented in the repo README at the state of the main branch on 23 August 2026.

  1. 1
    Install the environment

    Python 3.10, CUDA 12.1 wheels, flash-attn last because it compiles against the installed torch.

    bash
    git clone git@github.com:thu-ml/RoboticsDiffusionTransformer.git
    cd RoboticsDiffusionTransformer
    
    conda create -n rdt python=3.10.0
    conda activate rdt
    
    pip install torch==2.1.0 torchvision==0.16.0 --index-url https://download.pytorch.org/whl/cu121
    pip install packaging==24.0
    pip install flash-attn --no-build-isolation
    pip install -r requirements.txt
  2. 2
    Link the two frozen encoders

    The repo expects them under a google/ directory at the root. Symlinks keep the weights out of your git tree.

    bash
    mkdir -p google
    ln -s /path/to/t5-v1_1-xxl google/t5-v1_1-xxl
    ln -s /path/to/siglip-so400m-patch14-384 google/siglip-so400m-patch14-384
  3. 3
    Register your dataset

    Three JSON files carry the registration, with an agilex placeholder in all three. Replace it with your dataset name and give the control frequency in Hz. The sampling weight is irrelevant while you have one dataset.

    bash
    cd data && mkdir -p datasets
    ln -s /path/to/my_cool_dataset datasets/my_cool_dataset
    
    # then edit, replacing the agilex placeholder:
    #   configs/dataset_control_freq.json    "agilex": 25  -> {"my_cool_dataset": 30}
    #   configs/finetune_datasets.json       ["agilex"]    -> ["my_cool_dataset"]
    #   configs/finetune_sample_weights.json {"agilex":100}-> {"my_cool_dataset": 100}
  4. 4
    Write the loader

    Edit HDF5_DIR and DATASET_NAME at lines 21 and 22 of data/hdf5_vla_dataset.py, then implement parse_hdf5_file() and parse_hdf5_file_state_only(). Despite the name you need not use HDF5; only the class contract matters. Lines 180 to 194 hold the 128-slot mapping.

    bash
    $EDITOR data/hdf5_vla_dataset.py     # L21 HDF5_DIR, L22 DATASET_NAME
                                         # L148 path to precomputed lang embeddings
                                         # L180-194 fill the unified action vector
  5. 5
    Compute dataset statistics

    One command from the repo root. It writes the per-dimension statistics the trainer needs.

    bash
    python -m data.compute_dataset_stat_hdf5
  6. 6
    Precompute language embeddings if you are under 24 GB

    Set TASK_NAME and INSTRUCTION in scripts/encode_lang.py, and point OFFLOAD_DIR at a real directory if T5-XXL still does not fit. Then add --precomp_lang_embed to the training script.

    bash
    # scripts/encode_lang.py
    #   MODEL_PATH  = "google/t5-v1_1-xxl"
    #   CONFIG_PATH = "configs/base.yaml"
    #   SAVE_DIR    = "outs/"
    #   OFFLOAD_DIR = None      # set an existing path if VRAM < 24GB
    
    python -m scripts.encode_lang
    # batch version for a whole dataset: scripts/encode_lang_batch.py
  7. 7
    Launch the fine-tune

    finetune.sh is the shipped example and the flags below are its values on main. Point pretrained_model_name_or_path at the Hugging Face id and it pulls the 1M-step checkpoint.

    bash
    deepspeed --hostfile=hostfile.txt main.py \
        --deepspeed="./configs/zero2.json" \
        --pretrained_model_name_or_path="robotics-diffusion-transformer/rdt-1b" \
        --pretrained_text_encoder_name_or_path="google/t5-v1_1-xxl" \
        --pretrained_vision_encoder_name_or_path="google/siglip-so400m-patch14-384" \
        --output_dir="./checkpoints/rdt-finetune-1b" \
        --train_batch_size=32 \
        --sample_batch_size=64 \
        --max_train_steps=200000 \
        --checkpointing_period=1000 \
        --sample_period=500 \
        --checkpoints_total_limit=40 \
        --lr_scheduler="constant" \
        --learning_rate=1e-4 \
        --mixed_precision="bf16" \
        --dataloader_num_workers=8 \
        --image_aug \
        --dataset_type="finetune" \
        --state_noise_snr=40 \
        --load_from_hdf5 \
        --report_to=wandb
The trap that eats a day: T5-XXL and your VRAM

The README says it in plain words: on an RTX 4090 or lower, GPU memory may be too low to load the t5-v1_1-xxl encoder. The failure lands as an out-of-memory while that encoder loads, after the job has queued and pulled gigabytes of weights, so it feels like a training bug rather than a configuration one. Fix it before you launch: precompute the embeddings with scripts/encode_lang_batch.py, point HDF5VLADataset at the embedding path instead of the raw instruction, and add --precomp_lang_embed. The repo FAQ lists further options in its own order: RDT-170M, a more memory-efficient ZeRO stage, use_8bit_adam=True, 4-bit or 8-bit quantisation, XFormers, hand-implemented gradient checkpointing, and a larger --gradient_accumulation_steps, which costs running time in exact proportion. The same symptom on our trainer is at out of memory during training.

Monitor two numbers: a long-window moving average of loss and overall_avg_sample_mse. The README reports that empirically the lower this sample MSE the better the model performs, and that fine-tuning is over when it converges. The paper's appendix carries the reasoning, a positive correlation between that MSE and deployment performance on the robot, with the caveat that an unusually low value can mean overfitting. The repo FAQ asks for at least 150,000 steps regardless of batch size; the example script sets max_train_steps to 200,000.

Deploying the fine-tuned checkpoint

Inference is wrapped in a class called RoboticDiffusionTransformerModel in scripts/agilex_model.py, and you call its step() method. Two functions must be rewritten for your hardware: _format_joint_to_state() at line 164, which packs joint readings into the 128-slot vector, and _unformat_action_to_joint() at line 196, which unpacks the output into servo commands. The control frequency defaults in the same file and is passed on the command line.

bash
python -m scripts.agilex_inference \
    --use_actions_interpolation \
    --pretrained_model_name_or_path=checkpoints/rdt-finetune-1b/checkpoint-<STEP> \
    --lang_embeddings_path=outs/lang_embeddings/your_instr.pt \
    --ctrl_freq=25
inference.sh from the repo. The example targets Mobile ALOHA; the class is what you reuse.
Camera order is not a detail

The README puts this in bold, and it is the second most common way a working checkpoint produces nonsense on hardware. When you feed images into step(), the order MUST be [ext_{t-1}, right_wrist_{t-1}, left_wrist_{t-1}, ext_{t}, right_wrist_{t}, left_wrist_{t}]. History first, then current, and within each timestep exterior, right wrist, left wrist. Swap two and the model still runs, still produces smooth trajectories, and reaches for the wrong place. The general version is at policy only works in one setup.

The AY-Robots fix index page listing common robot policy failure modes such as out of memory during training, policy freezes mid-motion and policy only works in one setup
The /fix index. Camera-order and out-of-memory failures are model-agnostic, so these pages apply whether the policy is RDT or one of the five the platform trains.

Two ways to get a policy onto an arm

You clone thu-ml/RoboticsDiffusionTransformer, download three sets of weights, write a loader that maps your robot into the 128-slot vector, and rent or own a machine big enough for a 150,000 step run. Everything is MIT licensed, and you own the data pipeline, the GPU, the checkpoint storage and the deployment glue.

  • Full control over the action mapping, which matters if your robot has an unusual gripper or an extra wrist joint.
  • Debug the loader on RDT-170M first, as long as you also set hidden_size to 1024 and depth to 14 in configs/base.yaml to match its config.json.
  • Pre-train from scratch with pretrain.sh and a 400 GB disk buffer, if you really want to.
bash
# the three things that must be true before you launch
python -c "import torch, flash_attn; print(torch.__version__)"
ls google/t5-v1_1-xxl google/siglip-so400m-patch14-384
python -m data.compute_dataset_stat_hdf5
Environment, encoders, statistics. In that order.

Where RDT-1B sits against the policies you can actually train here

The comparison below mixes two kinds of number. The five AY-Robots rows are platform figures for the per-action-step latency of a served policy; the RDT row is the paper's own throughput measurement on the robot's onboard RTX 4090. Different metrics, not a ranking.

The AY-Robots policies comparison page showing five trainable policies side by side with parameter counts, required GPU, inference latency per action step and minimum episode count
The five policies the platform trains, with the numbers that decide which one fits your task. RDT-1B is not among them.
ModelParamsAction representationReported speedTrainable on AY-Robots
RDT-1B1.2 BDiffusion over a 64-step chunk in a 128-dim unified space6 chunks/s and 381 actions/s on an onboard RTX 4090 (paper)no
RDT-170M170 Mthe same, at half depth and half widthnot publishedno
GR00T N1.7~3 B, ~40 M trained during fine-tuningVLA with a diffusion action head152 ms per action stepyes, A100 or H100
GR00T N1.5~3 BVLA, the predecessor165 ms per action stepyes, A100 or H100
Pi0.5~3 B, PaliGemma backboneflow matching485 ms per action stepyes, A100 or H100
SmolVLA~450 Mcompact VLA245 ms per action stepyes, 24 GB card
ACT~80 Maction chunking transformer, trained from scratch20 ms per action stepyes, 24 GB card

Two structural similarities are worth naming. RDT's chunk of 64 actions is the same idea as action chunking in ACT, unsurprising since the paper devotes an appendix to the technique and cites ACT for it. And RDT's diffusion head addresses the same multi-modality problem that flow matching addresses in Pi0.5, by a different route, compared in our Pi-Zero flow matching article.

The head-to-head comparison page for GR00T N1.7 against Pi0.5 on AY-Robots, showing a table of parameters, GPU tier, latency and dataset format
If RDT is off the table for your hardware, this is the decision you actually face. GR00T N1.7 against Pi0.5, side by side.

What the reported numbers say

The 56 percent improvement in success rate that gets quoted everywhere comes from the paper's introduction, not its abstract, and is measured on a Cobot Mobile ALOHA with two 7 degree of freedom arms against ACT, OpenVLA and Octo. The ManiSkill simulation results, added to the repo in December 2024, are easier to read because the protocol is fixed: 250 trials per task, 10 seeds with 25 trials each, RDT fine-tuned from the released checkpoint for 300K iterations.

MethodPegInsertionSidePickCubeStackCubePlugChargerPushCubeMean
RDT13.2%77.2%74.0%1.2%100%53.6%
Diffusion Policy0.0%40.0%80.0%0.0%88.0%30.2%
OpenVLA0.0%8.0%8.0%0.0%8.0%4.8%
Octo0.0%0.0%0.0%0.0%0.0%0.0%

Read the PlugCharger column before the mean. 1.2 percent is a failure, and PegInsertionSide at 13.2 percent is not a working policy either: contact-rich insertion is unsolved for all four methods, and the mean is carried by the easy tasks. The ablation is more useful to practitioners: removing pre-training dropped unseen-object success from 50 percent to 0, while the 166 M small variant dropped it to 37.5 percent. Pre-training scale mattered more than model size.

The RoboTwin ranking needs a date on it

The repo points at the RoboTwin 2.0 leaderboard, a 50-task dual-arm benchmark on an Aloha-AgileX, and says RDT ranks second only to Pi0, excluding DP3 because DP3 uses ground-truth point clouds. That held for the five single-task baselines listed there in August 2025, and the repo has not been touched since January 2026. At the board's 18 August 2026 update it carries 18 entries: RDT sits eleventh on the hard clean2random ranking at 13.72 percent, behind pi0 at 16.34 percent, which is still the best of the original single-task group, and behind a row of 2026 co-trained models led by GigaBrain-0.7 at 67.9 percent. Most of those newer entries are co-trained across all 50 tasks while RDT and pi0 are single-task fine-tunes, so it is no longer a like-for-like board. Either way, read the README claim as a 2025 snapshot, not a current standing.

The honest limits

Three things about RDT-1B are routinely overstated when the paper gets cited, and one thing about running any policy over a network applies here too.

  • It is not a zero-shot cross-embodiment model. The model card says it plainly: because of the embodiment gap, RDT cannot yet generalise to robot platforms absent from the pre-training data, and the recommendation is to collect a small target-robot dataset and fine-tune. The unified action space makes multi-robot training possible; it does not make a new arm free.
  • The bimanual results are one robot. All real-robot evaluation is on a Cobot Mobile ALOHA, and the appendix states the mobile base was used only to move between rooms, never during training or inference. These are static bimanual tasks.
  • The pre-training scale is the contribution. The ablation shows the from-scratch variant collapsing to 0 percent on unseen objects. If you fine-tune on a handful of episodes and it works, that is the 21 TB doing the work.
  • Latency is local or it is nothing. The paper's 6 Hz chunk rate is measured on a GPU bolted to the robot. A public-internet round trip between the cameras and the policy adds tens to hundreds of milliseconds per decision, turning a working policy into a hesitant one. Remote inference suits slow pick-and-place, not fast reactive motion. That is true of our inference pods too, and we would rather say it than sell around it.

One practical limit has nothing to do with the model: RDT does not read LeRobot datasets natively. Checked on 23 August 2026, the lerobot policies directory holds act, diffusion, pi0, pi05, pi0_fast, smolvla, groot, xvla and about a dozen more, and no rdt. If your episodes came from the LeRobot toolchain, you write that conversion yourself. Recording is where the platform helps: see record your first dataset and teleoperation.

RDT2, and what it means for RDT-1B

The same group released RDT2 in September 2025, with the paper following in February 2026. It is a different bet: instead of scaling robot teleoperation data, RDT2 scales UMI-style handheld gripper data, more than 10,000 hours of human manipulation video in over 100 indoor scenes, collected with redesigned higher-strength UMI hardware. Two variants shipped. RDT2-VQ is a VLA adapted from Qwen2.5-VL-7B-Instruct that uses residual vector quantisation as its action tokenizer; RDT2-FM is an improved RDT used as a flow-matching action expert, with much lower inference latency.

Which one should you read about

RDT2 claims zero-shot deployment on unseen embodiments for simple open-vocabulary tasks such as picking, placing, shaking and wiping, verified on bimanual UR5e and bimanual Franka Research 3. That is precisely the claim RDT-1B declined to make. RDT-1B is still the better paper for understanding the unified action space, which RDT2 builds on rather than replaces, and it is still MIT licensed and still runs. But its last push was 21 January 2026 and new work happens in the RDT2 repository, which ships under Apache-2.0 rather than MIT. Plan accordingly.

For a broader map of how these families relate, our overview of vision-language-action models covers the lineage, and the policies page covers what is trainable here today. If you are choosing hardware rather than a model, start at the SO-100 page or the SO-100 complete guide.

Can I fine-tune RDT-1B on a single RTX 4090?

Yes, but not naively. The README states that on an RTX 4090 or lower the GPU memory may be too low to load T5-XXL, so precompute language embeddings with scripts/encode_lang_batch.py and pass --precomp_lang_embed. Beyond that the repo FAQ offers RDT-170M, a more memory-efficient ZeRO stage, use_8bit_adam, 4-bit or 8-bit quantisation, XFormers, gradient checkpointing and a larger --gradient_accumulation_steps. The repo asks for at least 150,000 steps and publishes no single-GPU wall-clock time, so plan for a long run.

Does RDT-1B work with a single-arm robot like an SO-100?

Architecturally yes. The unified action vector reserves ten slots for right-arm joint positions and five for the right gripper, and the README instructs you to fill a single arm into the right-arm portion so it matches the mostly single-arm pre-training data; a six-joint arm fills the first six slots. Practically, you write the loader yourself, there is no LeRobot integration, and the released evaluation is entirely on a dual-arm ALOHA. For a policy you can train and serve today on an SO-100 class arm, the five trainer options are documented on the policies page.

What is the difference between RDT-1B and RDT-170M?

RDT-170M has a hidden size of 1024 and a depth of 14, exactly half of RDT-1B's 2048 and 28, with the same 32 heads and the same 128-dimensional action space. It is the RDT (small) ablation from the paper, which counts it as 166 M parameters. It is a 500K-step checkpoint of 332,520,250 bytes against RDT-1B's 1M-step 2,456,755,578 bytes. In the ablation it scored 37.5 percent on unseen objects against 50 percent for the full model, and 25 percent on instruction following against 100 percent. Use it to debug your data pipeline, and change hidden_size and depth in configs/base.yaml when you load it.

Is RDT-1B available on the AY-Robots trainer?

No. The trainer supports GR00T N1.7, GR00T N1.5, Pi0.5, SmolVLA and ACT. RDT-1B and RDT-170M appear in the arena for comparison, alongside RDT2-VQ and RDT2-FM, but are not trainable here. To run RDT, the upstream repo is the path and the fine-tuning section above applies.

How many demonstrations do I need to fine-tune RDT-1B?

The paper's fine-tune used more than 6,000 trajectories across 300+ tasks, and the few-shot claim of 1 to 5 demonstrations applies to new skills learned on top of that fine-tune, not to the raw pre-trained checkpoint. For a single task from the released weights, treat a few thousand demonstrations as the reference point rather than five. On the AY-Robots trainer the minimums are 30 episodes for SmolVLA and 50 for the others, a different regime because those assume one narrow task.

85 VLA models, 332 benchmark results, every number linked to its source

RDT-1B, RDT-170M, RDT2-VQ, RDT2-FM, GR00T, Pi0.5, OpenVLA, Octo and the rest in one sortable table. No marketing numbers, just what the papers and model cards report, with a link back to each claim.

Open the arena

Ready for high-quality robotics data?

AY-Robots connects your robots to skilled operators worldwide.

Get Started