LeRobot documentation
LingBot-VLA 2.0
LingBot-VLA 2.0
LingBot-VLA 2.0 は Robbyant によるビジョン・言語・アクションモデルであり、LingBot-VLA 1.0 の後継です。Qwen3-VL-4B バックボーンと、スパースな Mixture-of-Experts 構成の Qwen2 アクションエキスパート(32 エキスパート、top-4 ルーティング)を組み合わせ、エンボディメント間で共有される 55 次元の正規化された状態/アクション空間上でフローマッチングを用いてアクションチャンクを生成します。
LeRobotポートはlingbot_vla_v2ポリシーです。標準的なLeRobotデータセット、プロセッサ、lerobot-train、lerobot-eval、lerobot-rolloutを使用し、アップストリームのデュアルクエリ深度および動画蒸留も含まれます。
モデルの詳細については、アップストリームリポジトリおよび技術レポートを参照してください。
インストール
pip install -e ".[training,lingbot_vla_v2]"プロセッサが構築される際、Qwen3-VLのトークナイザーと画像プロセッサはQwen/Qwen3-VL-4B-Instruct(--policy.tokenizer_path)から読み込まれます。flash-attnは不要であり、アテンションにはPyTorch SDPAが使用されます。
チェックポイント
| チェックポイント | ソース | 使用 |
|---|---|---|
lerobot/lingbot_vla_v2_base | robbyant/lingbot-vla-v2-6b、フォーマット変換のみ | ファインチューニングの開始点です。特徴量は55次元の正規化レイアウト全体です。ロボット用のスロットマッピングを渡してください。 |
lerobot/lingbot_vla_v2_robotwin | robbyant/lingbot-vla-v2-6b-robotwin、ステップ 50000 | RoboTwin 2.0の評価。14次元の状態/アクション、カメラcam_high、cam_left_wrist、cam_right_wrist、QUANTILES(q01/q99)正規化。 |
どちらか一方を--policy.pathで読み込みます。ポリシーのタイプは、チェックポイントのconfig.jsonから読み取られます。
ロボットを正規レイアウトにマッピングする
モデルは55次元の状態を入力として受け取り、55次元のアクションを予測します。レイアウトは設定内のcanonical_jointsによって定義されます。
| スロット | 次元 | コンテンツ |
|---|---|---|
arm.position | 14 | アームの関節位置 |
end.position | 14 | エンドエフェクタの姿勢 |
effector.position | 2 | gripperの位置 |
hand.position | 12 | 器用な手の関節 |
waist.position | 4 | 腰の関節 |
head.position | 2 | ヘッドジョイント |
base.velocity | 3 | モバイルベース速度 |
reserved.slots | 4 | 予約済み |
--policy.state_slots と --policy.action_slots は、JSON として、データセットの observation.state と action のスパンをこれらのスロットにマッピングします。
{
"observation.state.arm.position": {
"origin_keys": [{ "observation.state": { "start": 0, "end": 5 } }]
}
}- スロット名は、上記の正規名に、必要に応じて
observation.state.またはaction.をプレフィックスとして付加したものです。不明な名前はエラーを発生させます。 - 各スロットは、
observation.state(状態スロット)またはaction(アクションスロット)から、1つ以上の{start, end}スパンを読み取ります。 スパンはスロットの先頭から連結・パッキングされ、スロットの残りはゼロパディングされ、損失から除外されます。 - スロットマッピングがない場合、生の特徴量は、ベースチェックポイントと同様に、55次元の正規レイアウトとして扱われます。
- 相対アクションはデフォルトで無効です。
--policy.use_relative_actions=trueを設定すると、現在の状態をアクションから引き算しますが、--policy.relative_exclude_joints(デフォルトは["gripper"])のリストに該当する名前を含む次元は除外されます。
Postprocessor はマッピングを逆変換するため、select_action はロボットの生アクション空間でのアクションを返します。
ファインチューニングされたチェックポイントは、スロットのマッピングとデータセットの統計情報をプロセッサーとともに保存します。
カメラ
画像ステップは、チェックポイントのinput_featuresに列挙されたカメラを、その順序で読み取ります。ベースのチェックポイントでは、camera_top、camera_wrist_left、camera_wrist_rightです。ロボットに存在しないビューはマスクされます。データセットのカメラをこれらにマッピングするには、--rename_mapを使用してください。
ファインチューニング
maximellerbach/omx_multicubes の例です。1つのアームに5つの関節とグリップ、2つのカメラ(top、wrist)が搭載されています。
lerobot-train \
--dataset.repo_id=maximellerbach/omx_multicubes \
--policy.path=lerobot/lingbot_vla_v2_base \
--policy.state_slots='{"observation.state.arm.position": {"origin_keys": [{"observation.state": {"start": 0, "end": 5}}]}, "observation.state.effector.position": {"origin_keys": [{"observation.state": {"start": 5, "end": 6}}]}}' \
--policy.action_slots='{"action.arm.position": {"origin_keys": [{"action": {"start": 0, "end": 5}}]}, "action.effector.position": {"origin_keys": [{"action": {"start": 5, "end": 6}}]}}' \
--rename_map='{"observation.images.top": "observation.images.camera_top", "observation.images.wrist": "observation.images.camera_wrist_left"}' \
--policy.dtype=float32 \
--accelerator.mixed_precision=bf16 \
--policy.repo_id=your_repo_id \
--batch_size=1 \
--steps=30000 \
--save_freq=5000 \
--output_dir=outputs/train/lingbot_vla_v2_omx重みを fp32 で保持し、計算は bf16 で行います(--policy.dtype=float32 --accelerator.mixed_precision=bf16)。これはアップストリームの実装と同じです。--policy.dtype=bfloat16 を使用すると、オプティマイザーが bf16 の重みを直接更新しますが、ほとんどの更新量が小さすぎて重みを変更できません。このデータセットでは、ベースのチェックポイントとビット単位で完全に一致した重みが 66% に達し、ファインチューニング後のポリシーははるかにぎこちなくなりました。推論も fp32 で実行してください(この方法で学習したチェックポイントのデフォルトです)。bf16 での推論では、アクションチャンクが明らかに滑らかさを失います。
正規化の統計量はデータセットから取得されます。マルチGPUでの学習には、--parallelism.*および--accelerator.*フラグを指定して、標準的なtorchrunランチャーを使用します。fp32の重み、勾配、オプティマイザの状態は約96 GBを占めるため、1つのGPUの容量が不足する場合は、--parallelism.dp_shard=<num_gpus>でシャード化してください。
デュアルクエリ蒸留
LingBot-VLA 2.0 は、言語トークンの後に学習済みクエリトークン(現在の深度/動画と将来の深度/動画)を付加し、アクションエキスパートがそれらにアテンションを向けます。両方のチェックポイントは align_params にアップストリームのレシピを保持しているため、推論時には常にクエリトークンが使用されます。学習中は、小さなヘッドがこれらのトークンを読み取り、凍結された教師モデル(MoGe-2 を備えた LingBot-Depth と DINO-Video)から蒸留されます。この際、アップストリームの損失重数が使用され、追加の損失は depth_loss、future_depth_loss、current_video_loss および future_video_loss として記録されます。
教師モデルは最初の学習ステップでダウンロードされます(robbyant/lingbot-vla-v2-6b と Ruicheng/moge-2-vitb-normal から約 3 GB)。GPU メモリを約 2 GB 消費し、各ステップでサンプルあたり約 130 ms 追加されます。
各サンプルは、将来のターゲットに必要となるフレームを chunk_size - 1 ステップ先読みします。推論時には追加の処理は実行されません。
主要な学習パラメータ
| パラメータ | デフォルト | 説明 |
|---|---|---|
state_slots / action_slots | null | 生スパンを正規化されたスロットに変換します(上記を参照)。 |
use_relative_actions | false | 現在の状態に対する相対的なアクションで学習します。 |
loss_type | L1_fm | 速度に対するFlow-matching損失。 |
normalization_mapping | MEAN_STDの状態とアクション | RoboTwinのチェックポイントはQUANTILESを使用しています。 |
train_expert_only | false | Qwen3-VLのバックボーンをフリーズし、アクションエキスパートのみを学習します。 |
freeze_vision_encoder | false | ビジョンタワーをフリーズします。 |
gradient_checkpointing | false | ステップ時間の増加を代償に、バックワードパスでアクティベーションを再計算してメモリを節約します。 |
use_moe_expert_lr | true | Routed expertsは、アップストリームと同様にlr * sqrt(num_experts / top_k)の学習率で学習します。 |
optimizer_lr / scheduler_decay_lr | 1e-5 / 1e-5 | AdamWのピーク学習率と最終学習率。 |
resize_imgs_with_padding | [256, 256] | Qwen3-VLの画像プロセッサ処理前のフレームサイズ(アップストリームでの値)。 |
image_max_pixels / image_min_pixels | 65536 / 65536 | Qwen3-VLのピクセル予算: カメラごとに64トークン(アップストリームと同様)。 |
chunk_size / n_action_steps | 50 / 50 | 予測されるホライズンと、チャンクごとに実行されるアクションの数。 |
num_steps | 10 | 推論時のデノイジングステップ。 |
tokenizer_path | Qwen/Qwen3-VL-4B-Instruct | Qwen3-VLのトークナイザーと画像プロセッサ。オフラインではローカルパスを使用します。 |
より小さいGPUに収めるには、--policy.train_expert_only=trueと--policy.gradient_checkpointing=trueを、小さい--batch_sizeと組み合わせて使用してください。
評価
LeRobotのRoboTwin環境でRoboTwinのチェックポイントを評価します(セットアップについてはRoboTwinを参照)。リネームマップは、環境のカメラ名をチェックポイントのカメラ名と一致させます。
lerobot-eval \
--policy.path=lerobot/lingbot_vla_v2_robotwin \
--env.type=robotwin \
--env.task=beat_block_hammer \
--eval.batch_size=1 \
--eval.n_episodes=100 \
--rename_map='{"observation.images.head_camera": "observation.images.cam_high", "observation.images.left_camera": "observation.images.cam_left_wrist", "observation.images.right_camera": "observation.images.cam_right_wrist"}'50のRoboTwin 2.0タスク(各100エピソード)における平均成功率は、公開されているRoboTwinチェックポイント(クリーンデータおよびランダム化データでのMuonによるポストトレーニング、アップストリームのRoboTwinランチャーによるFP32推論)のアップストリームのREADMEに報告されているものです。これらの数値は、この移植版で測定されたものではなく、アップストリームの数値です。
| 設定 | π0.5 | LingBot-VLA 1.0 | LingBot-VLA 2.0 |
|---|---|---|---|
| クリーン | 82.74% | 88.56% | 93.52% |
| ランダム化 | 76.76% | 86.68% | 92.80% |
推論の高速化
デフォルトではすべてオフの4つのフラグが、select_actionを高速化します。これらはCUDAと固定された入力形状を必要とし、追加の依存関係はありません:
--policy.use_cudagraph_denoise=true: デノイジングループを1つのCUDAグラフとしてキャプチャします。--policy.use_cudagraph_prefix=true: ビジョン言語プレフィックスのKVフィルをキャプチャします。--policy.use_cudagraph_prefix_full=true: プレフィックスグラフにビジョンタワーもキャプチャします。--policy.compile_predict_velocity=true: ステップごとの速度予測をtorch.compileします。最初の呼び出し時に約1分間コンパイルが行われます。
50ステップのアクションチャンク(デノイジングステップ10回)の所要時間、RoboTwinチェックポイント、RTX PRO 6000 1台:
| フラグ | bf16 | fp32 |
|---|---|---|
| なし | ~756 ms | ~614 ms |
| すべての3つのCUDAグラフフラグ | 約180 ms | ~203 ms |
| すべての3つのCUDAグラフフラグ + compile | 約120 ms | ~156 ms |
bf16では、CUDA graphsはeagerと同一の出力を生成しますが、torch.compileは数値をわずかに変更します。
デプロイ
lerobot-rollout を使用してロボット上でファインチューニング済みのチェックポイントを実行し、学習時と同じ --rename_map を渡します:
lerobot-rollout \
--strategy.type=base \
--policy.path=outputs/train/lingbot_vla_v2_omx/checkpoints/last/pretrained_model \
--robot.type=<your_robot_type> \
--robot.port=<port> \
--task="pick up the cube" \
--fps=30 \
--device=cudaReal-Time Chunking は、他の flow-matching ポリシーと同様に、--inference.type=rtc を使用して利用できます。
引用
@article{lingbotvla2,
title={From Foundation to Application: Improving VLA Models in Practice},
author={Wei Wu and Fangjing Wang and Fan Lu and He Sun and Shi Liu and Yunnan Wang and Yibin Yan and Yong Wang and Shuailei Ma and Xinyang Wang and Yibin Liu and Shuai Yang and Tianxiang Zhou and Kejia Zhang and Lei Zhou and Cheng Su and Nan Xue and Bin Tan and Han Zhang and Youchao Zhang and Fei Liao and Xing Zhu and Yujun Shen and Kecheng Zheng},
journal={arXiv preprint arXiv:2607.06403},
year={2026}
}ライセンス
コードと変換されたチェックポイントは、アップストリームのLingBot-VLA 2.0およびQwen3-VLのリリースと同様に、Apache-2.0ライセンスです。
蒸留学習では、3つの凍結済み教師モデルが、それぞれのライセンスの下でダウンロードされます(推論時にはこれらは読み込まれません):
| 教師 | 重み | ライセンス |
|---|---|---|
| MoGe-2 | Ruicheng/moge-2-vitb-normal | MIT |
| LingBot-Depth | robbyant/lingbot-vla-v2-6b (depth/) | Apache-2.0 |
| DINO-Video | robbyant/lingbot-vla-v2-6b (dino_video/) | DINOv3 ライセンス |
DINO-Videoの重みはMetaのDINOv3から派生しているため、蒸留を用いたトレーニングはDINOv3ライセンスの下でこれらを使用することを意味します。このライセンスには、論文でのDINOv3への言及や、一部の最終用途の制限などが含まれます。
Update on GitHub