LeRobot documentation

EVO1

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.7.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

EVO1

EVO1 是一种用于机器人控制的视觉-语言-动作策略,其核心由 InternVL3 骨干网络和连续流匹配动作头构成。此 LeRobot 集成将 EVO1 暴露为标准策略类型,使其能够使用常规的 LeRobot 数据集、检查点和处理器 API 进行训练和评估。

模型概览

该策略使用 InternVL3 对一张或多张相机图像以及语言任务提示进行嵌入,将机器人状态/动作向量填充至固定的最大维度,并通过流匹配动作头预测未来的动作块。在推理过程中,策略会采样一个动作块,并从该块中返回 n_action_steps 个动作,然后再进行下一次采样。

LeRobot 集成涵盖的内容

  • 通过 LeRobot 配置标准的 policy.type=evo1
  • InternVL3 图像/文本嵌入,支持可选的 FlashAttention 回退
  • 基于阶段的微调控制,用于仅针对动作头(action-head)的微调运行以及 VLM 微调运行
  • 连续流匹配动作预测
  • 通过 LeRobot 策略 API 保存/加载检查点
  • 使用 lerobot-train 进行训练,并使用标准策略推理 API 进行评估

更广泛的 EVO1 项目可能包含额外的训练脚本和数据集工具。本页专注于 LeRobot 机器人控制策略路径。

安装要求

  1. 按照安装指南安装 LeRobot。

  2. 安装 EVO1 依赖项:

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

    对于 LIBERO 训练和评估,请同时安装 LIBERO 附加组件:

    pip install -e ".[training,evo1,libero]"
  3. 仅当 flash-attn wheel 与您的 Python、PyTorch、CUDA 和 GPU 环境兼容时,才安装它。如果 flash_attn 不可用,EVO1 会回退到标准注意力机制。

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

阶段 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 会重新应用该阶段的微调默认设置。当从 Stage 1 检查点启动 Stage 2 时,这一点尤为重要,因为 Stage 1 检查点的配置会将 VLM 微调标志存储为禁用状态。除非设置了 policy.apply_training_stage_defaults=false,否则这些阶段默认值会优先于已保存或手动提供的 policy.finetune_* 标志,因此仅在手动控制所有微调标志时才应设置该标志。

关键训练参数

参数默认描述
policy.vlm_model_nameOpenGVLab/InternVL3-1B-hf原生转换的 InternVL3 检查点或本地模型目录
policy.training_stagestage1stage1 训练动作头;stage2 微调 VLM 分支
policy.apply_training_stage_defaultstrue在加载检查点后重新应用阶段微调的默认设置
policy.vlm_num_layers14用于策略的保留的 InternVL3 语言层数量
policy.dtypebfloat16请求的 VLM 数据类型
policy.use_flash_attntrue如果已安装,则请求使用 FlashAttention;否则回退
policy.enable_gradient_checkpointingtrue在受支持的 InternVL3 模块上启用检查点
policy.gradient_checkpointing_use_reentrantfalse在支持的情况下,传递给梯度检查点的重入设置
policy.chunk_size50每个块预测的未来动作数量
policy.n_action_steps50从采样块中消耗的动作数量
policy.max_state_dim24状态填充维度
policy.max_action_dim24动作填充维度
policy.postprocess_action_dimnullEVO1 后处理之后返回的可选动作维度
policy.binarize_gripperfalse将后处理后的夹爪通道二值化,用于 LIBERO 风格的评估
policy.task_fieldtask用作语言提示的批处理字段

推理

使用训练好的 EVO1 检查点试一试:

# --inference.type=rtc is optional
lerobot-rollout \
  --policy.path=your-org/your-evo1-checkpoint \
  --inference.type=rtc \
  ...

结果

LIBERO 评估

参考结果

发布的 Stage-2 检查点已通过干净下载和 rollout 验证:zuoxingdong/evo1_libero,修订版本 515921f4a2c1d3f3ad523721eafa26fdf2af315b。 干净下载评估使用了 LeRobot 修订版本 e40b58a8dfa9e7b86918c374791599d070518d11。

在 70,000 步的单次运行 Stage-2 检查点生成了:

套件成功的回合剧集成功率
LIBERO 空间48550097.0%
LIBERO 对象49650099.2%
LIBERO 目标48350096.6%
LIBERO-1046950093.8%
总体1,9332,00096.65%

这些结果使用了一个训练好的检查点和评估种子 1000;它们不是多种子均值或置信度估计。

参考训练配方

发布的检查点在 train_config.json 中记录了完整的已解析 Stage-2 配置。 实测运行使用了两个 H100 GPU,配备两个 DDP 进程,每个进程的 batch 为 64,因此全局 batch 为 128。两个阶段使用了相同的拓扑结构。基础 VLM 来自 OpenGVLab/InternVL3-1B-hf 的修订版本 014c0583a0d4bedf29fbe2dbff4f865eb998e171。 发布的工件并未记录确切的 LeRobot 训练 commit 或其原始依赖锁定文件, 因此以下命令是从当前 checkout 中复现所记录的配置和拓扑结构, 而不是逐位重建软件环境。

从 LeRobot 源代码检出中,安装锁定的依赖项并下载该确切的 VLM 版本:

uv sync --locked --extra training --extra evo1 --extra libero
VLM_DIR=$(uv run hf download OpenGVLab/InternVL3-1B-hf \
  --revision=014c0583a0d4bedf29fbe2dbff4f865eb998e171)

阶段 1 冻结 VLM 并训练动作头 5,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.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 策略后处理器可以将填充后的 24 维动作裁剪回 7 维 LIBERO 动作空间,并应用该夹爪二值化。要在相同的每任务单回合设置下评估作者格式的 checkpoint,请保留原始相机名称,而不是默认的 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 配置文件

修订版本 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

使用以下时间范围,为每个套件运行全部十个任务 ID:

env.taskenv.episode_length
libero_spatial280
libero_object280
libero_goal300
libero_10520

为每一行设置 suite 和 horizon。这样每个 suite 包含 500 个 episode,总计 2,000 个 episode,同时循环中每个任务使用全新进程的做法与实测的 RNG 重置拓扑结构相匹配。

参考

许可证

此 LeRobot 集成遵循 LeRobot 使用的 Apache 2.0 许可证。请查阅上游 EVO1 和 InternVL3 模型页面,以了解已发布的检查点和数据的许可证。

Update on GitHub