LeRobot documentation

EVO1

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

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 로봇 제어 정책 경로에 초점을 맞춥니다.

설치 요구 사항

  1. 설치 가이드를 따라 LeRobot을 설치하세요.

  2. EVO1의 종속성을 설치합니다:

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

    LIBERO 학습 및 평가를 위해 LIBERO extra도 설치하세요:

    pip install -e ".[training,evo1,libero]"
  3. 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.image
  • observation.state
  • action
  • 데이터셋의 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_nameOpenGVLab/InternVL3-1B-hf네이티브로 변환된 InternVL3 체크포인트 또는 로컬 모델 디렉터리
policy.training_stagestage1stage1은 액션 헤드를 학습하고, stage2는 VLM 브랜치를 파인튜닝합니다
policy.apply_training_stage_defaultstrueReapplies stage finetuning defaults after loading a checkpoint
policy.vlm_num_layers14정책에 유지되는 InternVL3 언어 레이어의 수
policy.dtypebfloat16요청한 VLM dtype
policy.use_flash_attntrue설치된 경우 FlashAttention을 요청하고, 그렇지 않으면 폴백합니다
policy.enable_gradient_checkpointingtrue지원되는 InternVL3 모듈에서 체크포인트 기능을 활성화합니다
policy.gradient_checkpointing_use_reentrantfalse지원되는 경우 gradient checkpointing에 전달되는 Reentrant 설정
policy.chunk_size50Number of future actions predicted per chunk
policy.n_action_steps50샘플링된 청크에서 소비된 액션의 수
policy.max_state_dim24패딩 차원 상태
policy.max_action_dim24액션 패딩 차원
policy.postprocess_action_dimnullEVO1 후처리 후 반환되는 선택적 액션 차원
policy.binarize_gripperfalseLIBERO 스타일 평가용 후처리된 gripper 채널을 이진화합니다
policy.task_fieldtask언어 프롬프트로 사용되는 배치 필드

추론

학습된 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 Spatial48550097.0%
LIBERO Object49650099.2%
LIBERO 목표48350096.6%
LIBERO-1046950093.8%
전체1,9332,00096.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-5k

Stage 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=1

lerobot/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.taskenv.episode_length
libero_spatial280
libero_object280
libero_goal300
libero_10520

각 행에 대해 suite와 horizon를 설정합니다. 이렇게 하면 suite당 500개의 에피소드, 전체적으로 2,000개의 에피소드가 생성되며, 태스크마다 새 프로세스를 생성하는 루프 구조는 측정된 RNG 리셋 토폴로지와 일치합니다.

참고

라이선스

이 LeRobot 통합은 LeRobot에서 사용하는 Apache 2.0 라이선스를 따릅니다. 공개된 체크포인트와 데이터의 라이선스는 upstream EVO1 및 InternVL3 모델 페이지를 확인하세요.

Update on GitHub