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 骨干网络和连续流匹配动作头构成。此 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