LeRobot documentation
EVO1
EVO1
EVO1은 InternVL3 백본과 연속형 flow-matching 액션 헤드를 기반으로 로봇 제어를 위한 Vision-Language-Action 정책입니다. 이 LeRobot 통합은 EVO1을 표준 정책 유형으로 노출하여, 일반적인 LeRobot 데이터셋, 체크포인트, 프로세서 API로 학습 및 평가할 수 있도록 합니다.
모델 개요
정책은 InternVL3를 사용하여 하나 이상의 카메라 이미지와 언어 작업 프롬프트를 임베딩하고, 로봇 상태/액션 벡터를 고정된 최대 차원으로 패딩한 후, flow-matching 액션 헤드를 사용하여 미래 액션 청크를 예측합니다. 추론 시 정책은 액션 청크를 샘플링한 후 해당 청크에서 n_action_steps개의 액션을 반환하고 다시 샘플링합니다.
LeRobot 통합의 범위
- LeRobot를 통한 표준
policy.type=evo1구성 - FlashAttention 폴백이 선택적으로 가능한 InternVL3 이미지/텍스트 임베딩
- 액션 헤드 전용 및 VLM 파인튜닝 실행에 대한 단계별 파인튜닝 제어
- 연속 플로우 매칭 액션 예측
- LeRobot 정책 API를 통한 Checkpoint 저장/로드
lerobot-train로 학습하고 표준 정책 추론 API로 평가
더 넓은 범위의 EVO1 프로젝트에는 추가적인 학습 스크립트와 데이터셋 도구가 포함될 수 있습니다. 이 페이지는 LeRobot 로봇 제어 정책 경로에 초점을 맞춥니다.
설치 요구 사항
설치 가이드를 따라 LeRobot을 설치하세요.
EVO1의 종속성을 설치합니다:
pip install -e ".[training,evo1]"LIBERO 학습 및 평가를 위해 LIBERO extra도 설치하세요:
pip install -e ".[training,evo1,libero]"Python, PyTorch, CUDA, GPU 스택과 호환되는 경우에만
flash-attn휠을 설치하세요.flash_attn이 사용 불가능한 경우 EVO1은 표준 attention으로 폴백됩니다.
EVO1은 Hugging Face의 네이티브 transformers InternVL 구현을 사용하므로, policy.vlm_model_name은 OpenGVLab/InternVL3-1B-hf와 같이 네이티브로 변환된 체크포인트를 가리켜야 합니다(-hf 접미사에 유의하세요). 첫 실행 시 구성된 VLM 체크포인트가 다운로드되며, 이후 실행에서는 Hugging Face 캐시에서 이를 재사용합니다.
데이터 요구 사항
EVO1은 다음을 포함하는 LeRobot 데이터셋을 기대합니다:
policy.max_views개의 시각적 관측, 예를 들어observation.images.imageobservation.stateaction- 데이터셋의
task필드에 있는 언어 작업 지시문 또는policy.task_field로 구성된 다른 필드
상태 및 동작 벡터는 policy.max_state_dim 및 policy.max_action_dim으로 패딩됩니다. 예측 값은 반환되기 전에 데이터셋의 동작 차원으로 다시 잘립니다.
사용
LeRobot 구성에서 EVO1을 사용하려면 다음을 지정하세요:
policy.type=evo1기본적으로 새로운 EVO1 정책은 다음에서 VLM을 초기화합니다:
policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf
LeRobot 형식의 EVO1 체크포인트가 사용 가능해지면 다음으로 로드합니다:
policy.path=your-org/your-evo1-checkpoint
학습
1단계
Stage 1에서는 VLM을 고정하고 액션 헤드를 학습합니다:
lerobot-train \ --dataset.repo_id=your_org/your_dataset \ --policy.type=evo1 \ --policy.training_stage=stage1 \ --policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf \ --policy.device=cuda \ --policy.chunk_size=50 \ --policy.n_action_steps=50 \ --policy.max_state_dim=24 \ --policy.max_action_dim=24 \ --policy.optimizer_lr=1e-5 \ --batch_size=4 \ --steps=5000 \ --output_dir=./outputs/evo1_stage1
2단계
Stage 2는 Stage 1 정책을 로드하지만, 새로운 옵티마이저와 스케줄러를 시작합니다:
lerobot-train \ --dataset.repo_id=your_org/your_dataset \ --policy.path=./outputs/evo1_stage1/checkpoints/005000/pretrained_model \ --policy.training_stage=stage2 \ --policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf \ --policy.device=cuda \ --policy.chunk_size=50 \ --policy.n_action_steps=50 \ --policy.max_state_dim=24 \ --policy.max_action_dim=24 \ --policy.optimizer_lr=1e-5 \ --batch_size=4 \ --steps=80000 \ --output_dir=./outputs/evo1_stage2
기본적으로 policy.training_stage는 해당 단계의 finetuning 기본값을 다시 적용합니다. Stage 1 체크포인트에서 Stage 2를 시작할 때 이는 중요합니다. Stage 1 체크포인트 구성에는 VLM finetuning 플래그가 비활성화 상태로 저장되어 있기 때문입니다. policy.apply_training_stage_defaults=false가 아닌 한, 이러한 단계 기본값은 저장된 또는 수동으로 제공된 policy.finetune_* 플래그보다 우선합니다. 따라서 모든 finetuning 플래그를 수동으로 제어할 때만 해당 플래그를 설정하세요.
주요 학습 매개변수
| 매개변수 | 기본값 | 설명 |
|---|---|---|
policy.vlm_model_name | OpenGVLab/InternVL3-1B-hf | 네이티브로 변환된 InternVL3 체크포인트 또는 로컬 모델 디렉터리 |
policy.training_stage | stage1 | stage1은 액션 헤드를 학습하고, stage2는 VLM 브랜치를 파인튜닝합니다 |
policy.apply_training_stage_defaults | true | Reapplies stage finetuning defaults after loading a checkpoint |
policy.vlm_num_layers | 14 | 정책에 유지되는 InternVL3 언어 레이어의 수 |
policy.dtype | bfloat16 | 요청한 VLM dtype |
policy.use_flash_attn | true | 설치된 경우 FlashAttention을 요청하고, 그렇지 않으면 폴백합니다 |
policy.enable_gradient_checkpointing | true | 지원되는 InternVL3 모듈에서 체크포인트 기능을 활성화합니다 |
policy.gradient_checkpointing_use_reentrant | false | 지원되는 경우 gradient checkpointing에 전달되는 Reentrant 설정 |
policy.chunk_size | 50 | Number of future actions predicted per chunk |
policy.n_action_steps | 50 | 샘플링된 청크에서 소비된 액션의 수 |
policy.max_state_dim | 24 | 패딩 차원 상태 |
policy.max_action_dim | 24 | 액션 패딩 차원 |
policy.postprocess_action_dim | null | EVO1 후처리 후 반환되는 선택적 액션 차원 |
policy.binarize_gripper | false | LIBERO 스타일 평가용 후처리된 gripper 채널을 이진화합니다 |
policy.task_field | task | 언어 프롬프트로 사용되는 배치 필드 |
추론
학습된 EVO1 체크포인트로 직접 사용해 보세요:
# --inference.type=rtc is optional
lerobot-rollout \
--policy.path=your-org/your-evo1-checkpoint \
--inference.type=rtc \
...결과
LIBERO 평가
참조 결과
발행된 Stage-2 체크포인트는 clean-download 및 rollout 검증을 통과했습니다:
zuoxingdong/evo1_libero, 리비전515921f4a2c1d3f3ad523721eafa26fdf2af315b. clean-download 평가에는 LeRobot 리비전e40b58a8dfa9e7b86918c374791599d070518d11가 사용되었습니다.
70,000 단계에서 생성된 단일 실행 Stage-2 체크포인트는 다음을 생성했습니다:
| Suite | 성공적인 에피소드 | 에피소드 | 성공률 |
|---|---|---|---|
| LIBERO Spatial | 485 | 500 | 97.0% |
| LIBERO Object | 496 | 500 | 99.2% |
| LIBERO 목표 | 483 | 500 | 96.6% |
| LIBERO-10 | 469 | 500 | 93.8% |
| 전체 | 1,933 | 2,000 | 96.65% |
이 결과는 학습된 체크포인트 하나와 평가 시드 1000를 사용합니다. 여러 시드에 대한 평균이나 신뢰도 추정치가 아닙니다.
참고 학습 레시피
공개된 체크포인트는 train_config.json에 Stage-2의 완전한 해결된 구성을 기록합니다.
측정된 실행은 두 개의 H100 GPU와 두 개의 DDP 프로세스, 프로세스당 배치 64를 사용하여 전역 배치 128을 구성했습니다. 두 단계 모두 동일한 토폴로지를 사용했습니다. 기본 VLM은 OpenGVLab/InternVL3-1B-hf의 리비전 014c0583a0d4bedf29fbe2dbff4f865eb998e171에서 가져왔습니다.
공개된 아티팩트는 정확한 LeRobot 학습 커밋이나 원래의 의존성 잠금(lock)을 기록하지 않으므로,
아래 명령은 소프트웨어 환경을 비트 단위로 재구성하는 것이 아니라 현재 체크아웃에서 기록된 구성과 토폴로지를 재현합니다.
LeRobot 소스 체크아웃에서 고정된 의존성을 설치하고 해당 VLM 리비전을 다운로드합니다:
uv sync --locked --extra training --extra evo1 --extra libero
VLM_DIR=$(uv run hf download OpenGVLab/InternVL3-1B-hf \
--revision=014c0583a0d4bedf29fbe2dbff4f865eb998e171)Stage 1에서는 VLM을 고정하고 5,000단계 동안 action head를 학습합니다:
uv run accelerate launch --num_processes=2 -m lerobot.scripts.lerobot_train \
--dataset.repo_id=lerobot/libero \
--dataset.revision=a1aaacb7f6cd6ee5fb43120f673cebb0cfea7dd4 \
--dataset.video_backend=torchcodec \
--dataset.return_uint8=true \
--dataset.image_transforms.enable=true \
--dataset.use_imagenet_stats=true \
--dataset.eval_split=0.0 \
--policy.type=evo1 \
--policy.training_stage=stage1 \
--policy.apply_training_stage_defaults=true \
--policy.vlm_model_name="${VLM_DIR}" \
--policy.vlm_num_layers=14 \
--policy.dtype=bfloat16 \
--policy.device=cuda \
--policy.use_amp=true \
--policy.use_flash_attn=true \
--policy.enable_gradient_checkpointing=true \
--policy.gradient_checkpointing_use_reentrant=false \
--policy.image_resolution='[448,448]' \
--policy.chunk_size=50 \
--policy.n_action_steps=50 \
--policy.max_state_dim=24 \
--policy.max_action_dim=24 \
--policy.dropout=0.2 \
--policy.optimizer_lr=1e-5 \
--policy.optimizer_weight_decay=1e-3 \
--policy.optimizer_grad_clip_norm=1.0 \
--policy.scheduler_warmup_steps=1000 \
--policy.push_to_hub=false \
--use_policy_training_preset=true \
--batch_size=64 \
--steps=5000 \
--save_checkpoint=true \
--save_checkpoint_to_hub=false \
--save_freq=2500 \
--log_freq=10 \
--env_eval_freq=0 \
--num_workers=4 \
--prefetch_factor=2 \
--persistent_workers=true \
--seed=1000 \
--trackio.enable=false \
--output_dir=./outputs/evo1-libero-stage1-g128-5kStage 2는 Stage-1 정책을 로드하지만 새로운 옵티마이저와 스케줄러를 시작합니다. 80,000단계 동안 학습하며, 보고된 체크포인트는 70,000단계에서 저장된 것입니다:
uv run accelerate launch --num_processes=2 -m lerobot.scripts.lerobot_train \
--dataset.repo_id=lerobot/libero \
--dataset.revision=a1aaacb7f6cd6ee5fb43120f673cebb0cfea7dd4 \
--dataset.video_backend=torchcodec \
--dataset.return_uint8=true \
--dataset.image_transforms.enable=true \
--dataset.use_imagenet_stats=true \
--dataset.eval_split=0.0 \
--policy.path=./outputs/evo1-libero-stage1-g128-5k/checkpoints/005000/pretrained_model \
--policy.training_stage=stage2 \
--policy.apply_training_stage_defaults=true \
--policy.vlm_model_name="${VLM_DIR}" \
--policy.vlm_num_layers=14 \
--policy.dtype=float32 \
--policy.device=cuda \
--policy.use_amp=true \
--policy.use_flash_attn=true \
--policy.enable_gradient_checkpointing=true \
--policy.gradient_checkpointing_use_reentrant=false \
--policy.image_resolution='[448,448]' \
--policy.chunk_size=50 \
--policy.n_action_steps=50 \
--policy.max_state_dim=24 \
--policy.max_action_dim=24 \
--policy.dropout=0.2 \
--policy.optimizer_lr=1e-5 \
--policy.optimizer_weight_decay=1e-3 \
--policy.optimizer_grad_clip_norm=1.0 \
--policy.scheduler_warmup_steps=1000 \
--policy.push_to_hub=false \
--use_policy_training_preset=true \
--batch_size=64 \
--steps=80000 \
--resume=false \
--save_checkpoint=true \
--save_checkpoint_to_hub=false \
--save_freq=10000 \
--log_freq=10 \
--env_eval_freq=0 \
--num_workers=4 \
--prefetch_factor=2 \
--persistent_workers=true \
--seed=1000 \
--trackio.enable=false \
--output_dir=./outputs/evo1-libero-stage2-g128-80k저자 형식 평가 프로필
저자 형식의 EVO1 LIBERO 프로필은 원본 LIBERO 카메라 기능 이름(observation.images.agentview_image 및 observation.images.robot0_eye_in_hand_image)을 사용하며, 14개 동작마다 재계획을 수행하고 시뮬레이터를 스텝하기 전에 그립커 명령을 이진화합니다. EVO1 정책 후처리기는 패딩된 24D 동작을 7D LIBERO 동작 공간으로 잘라내고 해당 그립커 이진화를 적용할 수 있습니다. 동일한 에피소드당 1개 작업 설정에서 저자 형식 체크포인트를 평가하려면 기본 image/image2 매핑 대신 원본 카메라 이름을 유지하고 LIBERO 동작 후처리 플래그를 설정하세요:
lerobot-eval \
--policy.path=your-org/your-evo1-libero-checkpoint \
--policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf \
--policy.device=cuda \
--policy.use_flash_attn=true \
--policy.n_action_steps=14 \
--policy.postprocess_action_dim=7 \
--policy.binarize_gripper=true \
--env.type=libero \
--env.task=libero_object \
--env.camera_name_mapping="{agentview_image: agentview_image, robot0_eye_in_hand_image: robot0_eye_in_hand_image}" \
--env.observation_height=448 \
--env.observation_width=448 \
--eval.batch_size=1 \
--eval.n_episodes=1lerobot/libero v3 네이티브 프로필
Revision a1aaacb7f6cd6ee5fb43120f673cebb0cfea7dd4에서는 카메라 특징을 image와 image2로 저장합니다. 이 예제는 모든 LIBERO Object 작업을 평가하며, 각 작업을 새로운 프로세스에서 실행합니다:
export MUJOCO_GL=egl
export PYOPENGL_PLATFORM=egl
suite=libero_object
horizon=280
for task_id in {0..9}; do
lerobot-eval \
--policy.path=zuoxingdong/evo1_libero \
--policy.pretrained_revision=515921f4a2c1d3f3ad523721eafa26fdf2af315b \
--policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf \
--policy.device=cuda \
--policy.use_amp=true \
--policy.dtype=bfloat16 \
--policy.use_flash_attn=false \
--policy.enable_gradient_checkpointing=false \
--policy.vlm_num_layers=14 \
--policy.image_resolution='[448,448]' \
--policy.max_text_length=1024 \
--policy.chunk_size=50 \
--policy.n_action_steps=14 \
--policy.max_state_dim=24 \
--policy.max_action_dim=24 \
--policy.num_inference_timesteps=32 \
--policy.postprocess_action_dim=7 \
--policy.binarize_gripper=true \
--policy.gripper_threshold=0.0 \
--policy.gripper_below_threshold_value=-1.0 \
--policy.gripper_above_threshold_value=1.0 \
--env.type=libero \
--env.task="${suite}" \
--env.task_ids="[${task_id}]" \
--env.camera_name=agentview_image,robot0_eye_in_hand_image \
--env.camera_name_mapping="{agentview_image: image, robot0_eye_in_hand_image: image2}" \
--env.control_mode=relative \
--env.obs_type=pixels_agent_pos \
--env.observation_width=448 \
--env.observation_height=448 \
--env.init_states=true \
--env.episode_length="${horizon}" \
--env.render_mode=rgb_array \
--env.max_parallel_tasks=1 \
--eval.n_episodes=50 \
--eval.batch_size=1 \
--eval.use_async_envs=false \
--eval.recording=false \
--seed=1000 \
--output_dir="./outputs/evo1-libero-stage2-70k-eval/${suite}/task-${task_id}" \
--job_name="evo1-libero-stage2-70k-${suite}-task-${task_id}"
done각 스위트에 대해 다음 horizon을 사용하여 모든 10개의 작업 ID를 실행합니다:
env.task | env.episode_length |
|---|---|
libero_spatial | 280 |
libero_object | 280 |
libero_goal | 300 |
libero_10 | 520 |
각 행에 대해 suite와 horizon를 설정합니다. 이렇게 하면 suite당 500개의 에피소드, 전체적으로 2,000개의 에피소드가 생성되며, 태스크마다 새 프로세스를 생성하는 루프 구조는 측정된 RNG 리셋 토폴로지와 일치합니다.
참고
라이선스
이 LeRobot 통합은 LeRobot에서 사용하는 Apache 2.0 라이선스를 따릅니다. 공개된 체크포인트와 데이터의 라이선스는 upstream EVO1 및 InternVL3 모델 페이지를 확인하세요.
Update on GitHub