LeRobot documentation
EVO1
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 机器人控制策略路径。
安装要求
按照安装指南安装 LeRobot。
安装 EVO1 依赖项:
pip install -e ".[training,evo1]"对于 LIBERO 训练和评估,请同时安装 LIBERO 附加组件:
pip install -e ".[training,evo1,libero]"仅当
flash-attnwheel 与您的 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.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
阶段 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_name | OpenGVLab/InternVL3-1B-hf | 原生转换的 InternVL3 检查点或本地模型目录 |
policy.training_stage | stage1 | stage1 训练动作头;stage2 微调 VLM 分支 |
policy.apply_training_stage_defaults | true | 在加载检查点后重新应用阶段微调的默认设置 |
policy.vlm_num_layers | 14 | 用于策略的保留的 InternVL3 语言层数量 |
policy.dtype | bfloat16 | 请求的 VLM 数据类型 |
policy.use_flash_attn | true | 如果已安装,则请求使用 FlashAttention;否则回退 |
policy.enable_gradient_checkpointing | true | 在受支持的 InternVL3 模块上启用检查点 |
policy.gradient_checkpointing_use_reentrant | false | 在支持的情况下,传递给梯度检查点的重入设置 |
policy.chunk_size | 50 | 每个块预测的未来动作数量 |
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 风格的评估 |
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 检查点已通过干净下载和 rollout 验证:
zuoxingdong/evo1_libero,修订版本515921f4a2c1d3f3ad523721eafa26fdf2af315b。 干净下载评估使用了 LeRobot 修订版本e40b58a8dfa9e7b86918c374791599d070518d11。
在 70,000 步的单次运行 Stage-2 检查点生成了:
| 套件 | 成功的回合 | 剧集 | 成功率 |
|---|---|---|---|
| LIBERO 空间 | 485 | 500 | 97.0% |
| LIBERO 对象 | 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 进程,每个进程的 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-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 策略后处理器可以将填充后的 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.task | env.episode_length |
|---|---|
libero_spatial | 280 |
libero_object | 280 |
libero_goal | 300 |
libero_10 | 520 |
为每一行设置 suite 和 horizon。这样每个 suite 包含 500 个 episode,总计 2,000 个 episode,同时循环中每个任务使用全新进程的做法与实测的 RNG 重置拓扑结构相匹配。
参考
许可证
此 LeRobot 集成遵循 LeRobot 使用的 Apache 2.0 许可证。请查阅上游 EVO1 和 InternVL3 模型页面,以了解已发布的检查点和数据的许可证。
Update on GitHub