LeRobot documentation

LingBot-VLA 2.0

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

LingBot-VLA 2.0

LingBot-VLA 2.0은 Robbyant의 비전-언어-액션 모델로, LingBot-VLA 1.0의 후속 버전입니다. Qwen3-VL-4B 백본과 희소 Mixture-of-Experts Qwen2 액션 전문가(32개 전문가, top-4 라우팅)를 결합하여, 다양한 embodiments에서 공유되는 55-D 정규 상태/액션 공간에서 flow matching을 통해 액션 청크를 생성합니다.

LeRobot 포트는 lingbot_vla_v2 정책입니다. 표준 LeRobot 데이터셋, 프로세서, lerobot-train, lerobot-eval, lerobot-rollout를 사용하며, 업스트림의 듀얼 쿼리 깊이 및 비디오 증류도 포함합니다.

모델 세부 사항은 업스트림 저장소와 기술 보고서를 참고하세요.

설치

pip install -e ".[training,lingbot_vla_v2]"

Qwen/Qwen3-VL-4B-Instruct에서 Qwen3-VL 토크나이저와 이미지 프로세서가 로드되며(--policy.tokenizer_path), 프로세서가 빌드될 때 적용됩니다. flash-attn는 필요하지 않으며, 어텐션은 PyTorch SDPA를 사용합니다.

체크포인트

체크포인트소스사용
lerobot/lingbot_vla_v2_baserobbyant/lingbot-vla-v2-6b, 포맷 전용 변환파인튜닝의 시작점. 특징은 전체 55-D 정규 레이아웃이며, 로봇에 대한 슬롯 매핑을 전달하십시오.
lerobot/lingbot_vla_v2_robotwinrobbyant/lingbot-vla-v2-6b-robotwin, 50,000 스텝RoboTwin 2.0 평가. 14차원 상태/행동, 카메라 cam_high, cam_left_wrist, cam_right_wrist, QUANTILES (q01/q99) 정규화.

--policy.path를 사용하여 둘 중 하나를 로드합니다. 정책 유형은 체크포인트의 config.json에서 읽힙니다.

로봇을 정준 레이아웃에 매핑하기

모델은 55-D 상태를 보고 55-D 동작을 예측합니다. 레이아웃은 config의 canonical_joints에 의해 설정됩니다:

슬롯차원콘텐츠
arm.position14팔 관절 위치
end.position14end-effector 자세
effector.position2그리퍼 위치
hand.position12灵巧한 손 관절
waist.position4허리 관절
head.position2head joints
base.velocity3모바일 베이스 속도
reserved.slots4예약됨

--policy.state_slots와 --policy.action_slots는 데이터셋의 observation.state와 action 범위를 이러한 슬롯에 매핑하며, JSON 형식입니다:

{
  "observation.state.arm.position": {
    "origin_keys": [{ "observation.state": { "start": 0, "end": 5 } }]
  }
}
  • Slot 이름은 위의 정식 이름이며, 선택적으로 observation.state. 또는 action. 접두사가 붙을 수 있습니다. 알려지지 않은 이름은 오류를 발생시킵니다.
  • 각 슬롯은 observation.state(상태 슬롯) 또는 action(액션 슬롯)에서 하나 이상의 {start, end} 스팬을 읽습니다. 스팬은 슬롯의 시작부터 연결되어 패킹되며, 슬롯의 나머지 부분은 0으로 패딩되고 손실 계산에서 제외됩니다.
  • 슬롯 매핑이 없는 경우, 기본 체크포인트와 마찬가지로 원시 기능이 55-D 정준 레이아웃으로 사용됩니다.
  • 상대적 동작은 기본적으로 비활성화되어 있습니다. --policy.use_relative_actions=true는 --policy.relative_exclude_joints(기본값 ["gripper"])의 항목을 이름에 포함하는 차원을 제외하고, 현재 상태를 동작에서 뺍니다.

Postprocessor는 매핑을 역변환하므로 select_action는 로봇의 원시 액션 공간(raw action space)에서 액션을 반환합니다. Fine-tuned 체크포인트는 프로세서와 함께 슬롯 매핑 및 데이터셋 통계를 저장합니다.

카메라

이미지 단계는 체크포인트의 input_features에 나열된 카메라를 해당 순서대로 읽습니다. 기본 체크포인트의 경우 camera_top, camera_wrist_left, camera_wrist_right입니다. --rename_map를 사용하여 데이터셋의 카메라를 이들에 매핑하십시오. 로봇에 없는 뷰는 마스킹됩니다.

파인튜닝

maximellerbach/omx_multicubes의 예시입니다. 5개의 관절과 그립퍼, 두 개의 카메라(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). 이는 upstream의 방식과 동일합니다. --policy.dtype=bfloat16을 사용하면 옵티마이저가 bf16 가중치를 직접 업데이트하지만, 대부분의 업데이트 값이 가중치를 변경하기에는 너무 작습니다. 이 데이터셋에서는 66%의 가중치가 베이스 체크포인트와 비트 단위로 동일하게 유지되었고, 파인튜닝된 정책이 훨씬 더 거칠었습니다. 추론도 fp32로 실행하세요(이 방식으로 학습된 체크포인트의 기본값입니다). bf16 추론은 액션 청크의 매끄러움이 눈에 띄게 떨어집니다.

정규화 통계는 데이터셋에서 가져옵니다. 멀티 GPU 학습에는 --parallelism.* 및 --accelerator.* 플래그를 사용하여 표준 torchrun 런처를 사용합니다. fp32 가중치, 그래디언트 및 옵티마이저 상태는 약 96 GB를 차지하므로, GPU 하나만으로는 용량이 부족할 경우 --parallelism.dp_shard=<num_gpus>로 샤딩하세요.

이중 쿼리 증류

LingBot-VLA 2.0은 언어 토큰 뒤에 학습된 쿼리 토큰(현재 및 미래 깊이/비디오)을 추가하고, 액션 전문가가 이 토큰들에 주의를 기울입니다. 두 체크포인트 모두 align_params에 업스트림의 레시피를 포함하므로 추론 시 쿼리 토큰은 항상 사용됩니다. 학습 중에 작은 헤드들이 해당 토큰을 읽고, 동결된 교사 모델(LingBot-Depth with MoGe-2, 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_slotsnullRaw spans을 정규화된 슬롯으로 변환합니다(위 참조).
use_relative_actionsfalse현재 상태에 상대적인 액션으로 학습합니다.
loss_typeL1_fm속도에 대한 Flow-matching 손실.
normalization_mappingMEAN_STD 상태 및 동작RoboTwin 체크포인트는 QUANTILES를 사용합니다.
train_expert_onlyfalseQwen3-VL 백본을 동결하고 액션 전문가만 학습합니다.
freeze_vision_encoderfalse비전 타워를 동결합니다.
gradient_checkpointingfalsebackward 단계에서 메모리를 절약하기 위해 단계 시간의 증가를 감수하고 활성화 값을 다시 계산합니다.
use_moe_expert_lrtrueRouted experts는 upstream과 동일하게 lr * sqrt(num_experts / top_k)로 학습합니다.
optimizer_lr / scheduler_decay_lr1e-5 / 1e-5AdamW의 피크 및 최종 학습률.
resize_imgs_with_padding[256, 256]Frame size before the Qwen3-VL image processor, as upstream.
image_max_pixels / image_min_pixels65536 / 65536Qwen3-VL 픽셀 예산: 카메라당 64 토큰, 업스트림과 동일합니다.
chunk_size / n_action_steps50 / 50예측 지평 및 각 청크당 실행된 동작 수.
num_steps10추론 시의 노이즈 제거 단계.
tokenizer_pathQwen/Qwen3-VL-4B-InstructQwen3-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 체크포인트에 대한 upstream README에 보고된 수치로, Muon post-training은 clean 및 randomized 데이터로 수행했으며, upstream RoboTwin launcher를 사용하여 FP32 추론을 수행했습니다. 이는 upstream 수치이며, 이 port를 통해 측정된 값이 아닙니다.

설정π0.5LingBot-VLA 1.0LingBot-VLA 2.0
깨끗한82.74%88.56%93.52%
무작위76.76%86.68%92.80%

추론 속도 향상

기본적으로 모두 꺼져 있는 네 개의 플래그가 select_action를 가속화합니다. CUDA와 고정된 입력 형식이 필요하며, 추가적인 종속성이 없습니다:

  • --policy.use_cudagraph_denoise=true: denoising 루프를 하나의 CUDA graph로 캡처합니다.
  • --policy.use_cudagraph_prefix=true: 비전-언어 접두어 KV 채우기를 캡처합니다.
  • --policy.use_cudagraph_prefix_full=true: prefix graph에 vision tower도 캡처합니다.
  • --policy.compile_predict_velocity=true: 단계별 속도 예측을 torch.compile합니다. 첫 번째 호출 시 약 1분 동안 컴파일이 수행됩니다.

10개의 denoising 단계가 포함된 50-step action chunk 하나에 대한 소요 시간, RoboTwin 체크포인트, RTX PRO 6000 1개:

플래그bf16fp32
없음~756 ms~614 ms
세 가지 CUDA 그래프 플래그~180 ms~203 ms
세 가지 CUDA 그래프 플래그 + compile~120 ms~156 ms

bf16에서 CUDA graphs는 eager와 동일한 출력을 생성하며, torch.compile은 수치적 결과를 약간 변경합니다.

배포

로봇에서 lerobot-rollout로 fine-tuned 체크포인트를 실행하고, 학습 시 사용한 --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=cuda

--inference.type=rtc를 사용하면 다른 flow-matching 정책과 마찬가지로 Real-Time Chunking을 사용할 수 있습니다.

인용

@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}
}

라이선스

code와 변환된 checkpoints는 upstream LingBot-VLA 2.0 및 Qwen3-VL 릴리스와 마찬가지로 Apache-2.0 라이선스를 따릅니다.

Distillation 학습은 자체 라이선스에 따라 세 개의 동결된 teacher를 다운로드합니다(추론 시에는 로드되지 않음):

교사가중치라이선스
MoGe-2Ruicheng/moge-2-vitb-normalMIT
LingBot-Depthrobbyant/lingbot-vla-v2-6b (depth/)Apache-2.0
DINO-Videorobbyant/lingbot-vla-v2-6b (dino_video/)DINOv3 라이선스

DINO-Video 가중치는 Meta의 DINOv3에서 파생되었으므로, 증류(distillation)를 통한 학습은 DINOv3 라이선스 하에서 이루어집니다. 이 라이선스는 다른 조건들과 함께, 출판물에서 DINOv3를 명시적으로 언급할 것과 일부 최종 용도를 제한하는 내용을 포함합니다.

Update on GitHub