LeRobot 集成 EVO1 策略实战:InternVL3 视觉语言骨干与 Flow-Matching 动作头的端到端机器人操控

发布时间:2026/9/10 15:09:15
LeRobot 集成 EVO1 策略实战:InternVL3 视觉语言骨干与 Flow-Matching 动作头的端到端机器人操控 LeRobot 集成 EVO1 策略实战InternVL3 视觉语言骨干与 Flow-Matching 动作头的端到端机器人操控【免费下载链接】lerobot LeRobot: Making AI for Robotics more accessible with end-to-end learning项目地址: https://gitcode.com/GitHub_Trending/le/lerobotEVO1 是一种面向机器人操控的 Vision-Language-ActionVLA策略。本文聚焦 LeRobot 仓库对 EVO1 的完整集成以 InternVL3 视觉语言骨干提取多视角图像与语言指令的融合表征以连续 flow-matching 动作头预测动作块并通过 LeRobot 标准策略 API 支持两阶段stage训练、检查点存取、rollout 与评估。读完本文你将掌握 EVO1 的架构原理、policy.typeevo1的关键配置参数、Stage 1 / Stage 2 训练命令以及如何在 LIBERO 基准上复现官方评估流程。EVO1 策略概览EVO1 在 LeRobot 中被实现为一个标准策略类型可以像其他策略一样使用 LeRobot 的数据集、检查点与处理器 API 进行训练和评估。其核心流程为使用 InternVL3 将一张或多张相机图像与语言任务指令嵌入为融合的视觉语言表征将机器人状态向量与动作向量填充pad到固定最大维度由 flow-matching 动作头预测未来一段连续动作块action chunk推理时从采样得到的动作块中依次消费n_action_steps步动作消费完毕后再重新采样。从源码结构看整个集成由 6 个模块构成src/lerobot/policies/evo1/文件职责configuration_evo1.pyEvo1Config配置类注册evo1策略类型包含全部可调超参数与训练阶段默认值解析internvl3_embedder.pyInternVL3Embedder原生 Hugging FacetransformersInternVL3 视觉语言嵌入器flow_matching.pyFlowmatchingActionHead等组件连续 flow-matching 动作预测头evo1_model.pyEvo1Model组合嵌入器与动作头的顶层模块并负责微调分支开关modeling_evo1.pyEvo1Policy实现 LeRobot 策略接口前向、select_action、predict_action_chunk、RTC 支持processor_evo1.py预/后处理管线含状态/动作填充、归一化统计填充、gripper 二值化对应测试位于tests/policies/evo1/test_evo1.py。架构深入从源码理解 EVO1 的实现细节InternVL3 视觉语言嵌入器InternVL3Embeddersrc/lerobot/policies/evo1/internvl3_embedder.py直接使用 Hugging Face 原生transformers的 InternVL3 实现无需trust_remote_code因此policy.vlm_model_name必须指向原生转换的检查点例如OpenGVLab/InternVL3-1B-hf注意-hf后缀。首次运行会下载配置的 VLM 检查点之后从 Hugging Face 缓存复用。嵌入器实现中的几个关键机制FlashAttention 回退attn_implementation在use_flash_attnTrue且环境装有 FlashAttention 2 时选择flash_attention_2否则自动回退到eager并打印警告保证在不兼容的 CUDA 栈上仍可运行。语言层截断vlm_num_layers默认 14将 InternVL3 语言模型的 Transformer 层截断为前 N 层显著减少参数量与显存占用。逐像素对齐的预处理_batched_resize_01将[0,1]浮点图像先量化到 uint8等价于 PILto_pil_image再以双三次插值缩放至 448×448数值上与 InternVL3 参考 PIL 预处理逐像素一致从而保证与上游 EVO1 检查点可互换。图像占位符与缺失视角掩码每个视角在 prompt 中展开为img 若干IMG_CONTEXT/img占位符缺失视角以零图像填充其占位 token 通过_mask_absent_image_tokens在注意力掩码中屏蔽且全程无 host↔device 同步。CLS 池化return_cls_onlyTrue默认时取因果解码器最后一个有效 token 的隐藏状态作为整个图像文本prompt 的池化表征作为动作头的上下文。连续 Flow-Matching 动作头FlowmatchingActionHeadsrc/lerobot/policies/evo1/flow_matching.py是 EVO1 区别于离散动作头如 ACT 的 MSE 回归的核心。其结构包括正弦位置编码SinusoidalPositionalEncoding与时间步嵌入支持超过 1000 步时自动扩展多层BasicTransformerBlock多头注意力 LayerNorm GELU 前馈以 VL 上下文 token 为 key/value、以动作 token 为 query并支持key_padding_maskMultiEmbodimentActionEncoder逐维 MLP 编码动作序列并叠加时间位置编码CategorySpecificLinear/CategorySpecificMLP支持多 embodimentnum_categories 1时按类别索引选择独立权重矩阵的线性层可选的状态编码器state_encoder将机器人状态嵌入并拼接到上下文 token 序列尾部。训练阶段velocity 回归在forward中从 Beta(2,2) 分布采样插值系数 t截断到 [0.02, 0.98]将噪声与真实动作线性插值得到中间动作x_t (1-t)·noise t·x_gt网络预测速度场损失为掩码后的均方误差fp32 下计算见modeling_evo1.py。推理阶段ODE 积分get_action从[-1,1]均匀噪声出发按num_inference_timesteps默认 32个步长以欧拉法积分x_{tdt} x_t dt·v逐步去噪得到最终动作块。该头还通过inference_delay、prev_chunk_left_over、execution_horizon等参数支持 RTC实时分块推理当配置了rtc_config时将 EVO1 的t: 0→1、v x1 - x0约定映射到 pi0 风格 RTC 处理器的time: 1→0约定翻转速度符号并令time 1 - t。状态与动作的固定宽度填充EVO1 的一个设计特点是策略内部统一使用固定最大维度。Evo1Config中的max_state_dim与max_action_dim默认均 24决定了状态向量与动作向量的填充宽度。在modeling_evo1.py中_prepare_state将observation.state填充到max_state_dim支持state_mask显式掩码并会将被掩码维度清零_prepare_actions将训练动作填充到max_action_dim支持action_mask并利用数据集的action_is_pad将 episode 结束后的重复动作排除在损失之外与 LeRobot 其他 chunked 策略一致推理时_prepare_inference_action_mask仅对真实动作维度由action_feature推断置 True预测结果在Evo1ActionProcessorStep后处理中裁剪回真实动作维度。预/后处理管线processor_evo1.py注册了三个自定义处理器步骤见make_evo1_pre_post_processorsEvo1PadStateProcessorStep归一化前将观测状态填充到max_state_dimEvo1PadActionProcessorStep训练动作填充到max_action_dim并在complementary_data中维护action_maskEvo1ActionProcessorStep后处理中将填充动作裁剪回真实维度action_dim可通过postprocess_action_dim覆盖并可选地对 gripper 通道做二值化binarize_gripper。值得注意的是_pad_evo1_stats填充维度对应的归一化统计使用中性值mean0, std1, min-1, max1等见_STAT_PAD_VALUES使填充观测在归一化后为 0仅提供形状兼容。从检查点加载时reconcile_evo1_processors会重新填充归一化统计、恢复 EVO1 专属的 batch 转换器evo1_batch_to_transition它保留了embodiment_id、state_mask与自定义 task 字段等非观测附加数据并依据当前配置重建动作后处理步骤从而让评估时命令行覆盖的postprocess_action_dim、binarize_gripper、gripper_*参数真正生效。安装与环境要求先按 安装指南 安装 LeRobot安装 EVO1 依赖pip install -e .[training,evo1]如需在 LIBERO 上训练与评估一并安装 LIBERO 附加依赖pip install -e .[training,evo1,libero]只有当flash-attnwheel 与你的 Python、PyTorch、CUDA 与 GPU 栈兼容时才安装。EVO1 在flash_attn不可用时自动回退到标准注意力eager。提示EVO1 使用 Hugging Face 原生transformers的 InternVL 实现因此policy.vlm_model_name必须是原生转换检查点带-hf后缀。首次运行会下载配置的 VLM 检查点之后从缓存复用。数据要求EVO1 期望一个 LeRobot 格式数据集包含1 到policy.max_views默认 3个视觉观测例如observation.images.imageobservation.stateaction数据集的task字段中的语言任务指令或用policy.task_field配置的其他字段。状态与动作向量会被填充到policy.max_state_dim与policy.max_action_dim预测结果在返回前会被裁剪回数据集的真实动作维度。真实动作维度由action_feature推断若为null则回退到max_action_dim见modeling_evo1.py。配置与使用在 LeRobot 配置中指定策略类型policy.typeevo1默认情况下新建的 EVO1 策略从以下地址初始化 VLMpolicy.vlm_model_nameOpenGVLab/InternVL3-1B-hf一旦得到 LeRobot 格式的 EVO1 检查点用以下方式加载policy.pathyour-org/your-evo1-checkpoint两阶段训练EVO1 采用与上游一致的staged training分阶段训练策略通过policy.training_stage切换Evo1Config.__post_init__会校验取值必须为stage1或stage2。Stage 1冻结 VLM训练动作头lerobot-train \ --dataset.repo_idyour_org/your_dataset \ --policy.typeevo1 \ --policy.training_stagestage1 \ --policy.vlm_model_nameOpenGVLab/InternVL3-1B-hf \ --policy.devicecuda \ --policy.chunk_size50 \ --policy.n_action_steps50 \ --policy.max_state_dim24 \ --policy.max_action_dim24 \ --policy.optimizer_lr1e-5 \ --batch_size4 \ --steps5000 \ --output_dir./outputs/evo1_stage1Stage 2加载 Stage 1 检查点微调 VLMStage 2 加载 Stage 1 的策略权重但会新建优化器与调度器lerobot-train \ --dataset.repo_idyour_org/your_dataset \ --policy.path./outputs/evo1_stage1/checkpoints/005000/pretrained_model \ --policy.training_stagestage2 \ --policy.vlm_model_nameOpenGVLab/InternVL3-1B-hf \ --policy.devicecuda \ --policy.chunk_size50 \ --policy.n_action_steps50 \ --policy.max_state_dim24 \ --policy.max_action_dim24 \ --policy.optimizer_lr1e-5 \ --batch_size4 \ --steps80000 \ --output_dir./outputs/evo1_stage2训练阶段默认值机制重要policy.training_stage默认会重新施加该阶段对应的微调默认值policy.apply_training_stage_defaultstrue。这在从 Stage 1 检查点启动 Stage 2 时至关重要Stage 1 检查点中保存的配置将 VLM 微调标志记录为关闭状态若不重新施加 Stage 2 默认值VLM 将保持冻结。源码中阶段默认值定义如下见configuration_evo1.py微调标志Stage 1 默认值Stage 2 默认值finetune_vlmFalseTruefinetune_language_modelFalseTruefinetune_vision_modelFalseTruefinetune_action_headTrueTrue这些阶段默认值优先于检查点中保存的或手动传入的policy.finetune_*标志仅当你希望手动控制每一个微调标志时才设置policy.apply_training_stage_defaultsfalse。此外配置还会校验finetune_vlm必须等于finetune_language_model or finetune_vision_model否则抛出ValueError。在模型层面Evo1Model.set_finetune_flagsevo1_model.py先整体冻结嵌入器再按分支重新启用language_model由finetune_language_model控制vision_tower与multi_modal_projector由finetune_vision_model控制动作头由finetune_action_head控制。Evo1Policy在 VLM 完全冻结时还会把嵌入器固定为 eval 模式_keep_frozen_embedder_eval并自动关闭梯度检查点冻结状态下开启它只会增加开销。关键训练参数参数默认值说明policy.vlm_model_nameOpenGVLab/InternVL3-1B-hf原生转换的 InternVL3 检查点或本地模型目录policy.training_stagestage1stage1训练动作头stage2微调 VLM 各分支policy.apply_training_stage_defaultstrue加载检查点后重新施加阶段微调默认值policy.vlm_num_layers14保留的 InternVL3 语言层数policy.vlm_dtypebfloat16请求的 VLM 数据类型policy.use_flash_attntrue已安装时请求 FlashAttention否则自动回退policy.enable_gradient_checkpointingtrue在支持的 InternVL3 模块上启用梯度检查点policy.gradient_checkpointing_use_reentrantfalse梯度检查点的 reentrant 设置policy.chunk_size50每个动作块预测的未来动作数policy.n_action_steps50每次从采样块中消费的动作数须 ≤chunk_sizepolicy.max_state_dim24状态填充维度policy.max_action_dim24动作填充维度policy.postprocess_action_dimnullEVO1 后处理返回的可选动作维度用于裁剪回真实动作空间policy.binarize_gripperfalse是否对后处理的 gripper 通道二值化LIBERO 风格评估用policy.task_fieldtask用作语言 prompt 的 batch 字段此外Evo1Config还提供若干可调项例如image_resolution必须为正方形因为 InternVL3 预处理使用标量image_size且须与 VLM 检查点原生分辨率一致否则会因占位符与视觉特征错位而报错、max_text_length默认 1024prompt 过长会从右侧截断需为长指令或多视角调大、num_inference_timesteps默认 32推理 ODE 积分步数、return_cls_only默认false为true时动作头仅以单个池化 VL token 为条件、num_categories与default_embodiment_id多 embodiment 支持、use_amp默认true在 CUDA 上以 bfloat16 autocast 包裹自身前向使数值不受外层 autocast 上下文 dtype 影响等。优化器使用 AdamW 预设optimizer_lr1e-5等调度器使用带 warmup 的余弦退火scheduler_warmup_steps300。推理与评估使用 rollout 试运行使用训练好的 EVO1 检查点进行 rolloutlerobot-rollout \ --policy.pathyour-org/your-evo1-checkpoint \ --inference.typertc \ # 可选启用 RTC 实时分块推理 ...Evo1Policy声明支持 RTCsupports_rtc() - True。在标准select_action模式下策略内部维护一个动作队列当队列为空时调用predict_action_chunk采样一个动作块并缓存前n_action_steps步随后每次弹出一步。在 RTC 模式下则通过--inference.typertc配置rtc_config并调用init_rtc_processor()将inference_delay、prev_chunk_left_over、execution_horizon传入 flow-matching 头的去噪循环。LIBERO 评估参考结果LeRobot 官方文档记录了释放的 Stage-2 检查点步骤 70,000单次运行在 LIBERO 上的评估结果评估种子 1000注意这是单次运行的原始数据不是多种子均值或置信度估计Suite成功 episode 数总 episode 数成功率LIBERO Spatial48550097.0%LIBERO Object49650099.2%LIBERO Goal48350096.6%LIBERO-1046950093.8%Overall1,9332,00096.65%该释放检查点记录了完整的 Stage-2 解析配置train_config.json实测运行使用 2 张 H100 GPU、2 个 DDP 进程、每进程 batch 64全局 batch 128两阶段拓扑相同基础 VLM 为OpenGVLab/InternVL3-1B-hf的固定 revision。参考训练配方可复现从 LeRobot 源码检出目录锁定依赖并下载指定 VLM revisionuv sync --locked --extra training --extra evo1 --extra libero VLM_DIR$(uv run hf download OpenGVLab/InternVL3-1B-hf \ --revision014c0583a0d4bedf29fbe2dbff4f865eb998e171)Stage 1冻结 VLM、训练动作头 5,000 步uv run accelerate launch --num_processes2 -m lerobot.scripts.lerobot_train \ --dataset.repo_idlerobot/libero \ --dataset.revisiona1aaacb7f6cd6ee5fb43120f673cebb0cfea7dd4 \ --dataset.video_backendtorchcodec \ --dataset.return_uint8true \ --dataset.image_transforms.enabletrue \ --dataset.use_imagenet_statstrue \ --dataset.eval_split0.0 \ --policy.typeevo1 \ --policy.training_stagestage1 \ --policy.apply_training_stage_defaultstrue \ --policy.vlm_model_name${VLM_DIR} \ --policy.vlm_num_layers14 \ --policy.vlm_dtypebfloat16 \ --policy.devicecuda \ --policy.use_amptrue \ --policy.use_flash_attntrue \ --policy.enable_gradient_checkpointingtrue \ --policy.gradient_checkpointing_use_reentrantfalse \ --policy.image_resolution[448,448] \ --policy.chunk_size50 \ --policy.n_action_steps50 \ --policy.max_state_dim24 \ --policy.max_action_dim24 \ --policy.dropout0.2 \ --policy.optimizer_lr1e-5 \ --policy.optimizer_weight_decay1e-3 \ --policy.optimizer_grad_clip_norm1.0 \ --policy.scheduler_warmup_steps1000 \ --policy.push_to_hubfalse \ --use_policy_training_presettrue \ --batch_size64 \ --steps5000 \ --save_checkpointtrue \ --save_checkpoint_to_hubfalse \ --save_freq2500 \ --log_freq10 \ --env_eval_freq0 \ --num_workers4 \ --prefetch_factor2 \ --persistent_workerstrue \ --seed1000 \ --wandb.enablefalse \ --output_dir./outputs/evo1-libero-stage1-g128-5kStage 2加载 Stage 1 检查点、新建优化器与调度器训练 80,000 步报告的检查点为步骤 70,000 的存档uv run accelerate launch --num_processes2 -m lerobot.scripts.lerobot_train \ --dataset.repo_idlerobot/libero \ --dataset.revisiona1aaacb7f6cd6ee5fb43120f673cebb0cfea7dd4 \ --dataset.video_backendtorchcodec \ --dataset.return_uint8true \ --dataset.image_transforms.enabletrue \ --dataset.use_imagenet_statstrue \ --dataset.eval_split0.0 \ --policy.path./outputs/evo1-libero-stage1-g128-5k/checkpoints/005000/pretrained_model \ --policy.training_stagestage2 \ --policy.apply_training_stage_defaultstrue \ --policy.vlm_model_name${VLM_DIR} \ --policy.vlm_num_layers14 \ --policy.vlm_dtypefloat32 \ --policy.devicecuda \ --policy.use_amptrue \ --policy.use_flash_attntrue \ --policy.enable_gradient_checkpointingtrue \ --policy.gradient_checkpointing_use_reentrantfalse \ --policy.image_resolution[448,448] \ --policy.chunk_size50 \ --policy.n_action_steps50 \ --policy.max_state_dim24 \ --policy.max_action_dim24 \ --policy.dropout0.2 \ --policy.optimizer_lr1e-5 \ --policy.optimizer_weight_decay1e-3 \ --policy.optimizer_grad_clip_norm1.0 \ --policy.scheduler_warmup_steps1000 \ --policy.push_to_hubfalse \ --use_policy_training_presettrue \ --batch_size64 \ --steps80000 \ --resumefalse \ --save_checkpointtrue \ --save_checkpoint_to_hubfalse \ --save_freq10000 \ --log_freq10 \ --env_eval_freq0 \ --num_workers4 \ --prefetch_factor2 \ --persistent_workerstrue \ --seed1000 \ --wandb.enablefalse \ --output_dir./outputs/evo1-libero-stage2-g128-80k注意上述命令是从当前检出仓库复现记录中的配置与拓扑而非逐位还原原始软件环境。作者格式评估配置LIBERO作者格式的 EVO1 LIBERO 评估 profile 使用原始 LIBERO 相机特征名observation.images.agentview_image与observation.images.robot0_eye_in_hand_image每 14 步重新规划一次并在步进仿真器前对 gripper 指令做二值化。EVO1 策略后处理器可把填充的 24 维动作裁剪回 7 维 LIBERO 动作空间并施加 gripper 二值化。在“每任务一个 episode”的评估设定下保持原始相机名并设置动作后处理标志lerobot-eval \ --policy.pathyour-org/your-evo1-libero-checkpoint \ --policy.vlm_model_nameOpenGVLab/InternVL3-1B-hf \ --policy.devicecuda \ --policy.use_flash_attntrue \ --policy.n_action_steps14 \ --policy.postprocess_action_dim7 \ --policy.binarize_grippertrue \ --env.typelibero \ --env.tasklibero_object \ --env.camera_name_mapping{agentview_image: agentview_image, robot0_eye_in_hand_image: robot0_eye_in_hand_image} \ --env.observation_height448 \ --env.observation_width448 \ --eval.batch_size1 \ --eval.n_episodes1原生lerobot/liberov3 评估配置lerobot/libero数据集的a1aaacb7f6cd6ee5fb43120f673cebb0cfea7dd4revision 将相机特征存储为image与image2。以下示例逐个评估全部十个 LIBERO Object 任务每个任务在独立进程中启动export MUJOCO_GLegl export PYOPENGL_PLATFORMegl suitelibero_object horizon280 for task_id in {0..9}; do lerobot-eval \ --policy.pathzuoxingdong/evo1_libero \ --policy.pretrained_revision515921f4a2c1d3f3ad523721eafa26fdf2af315b \ --policy.vlm_model_nameOpenGVLab/InternVL3-1B-hf \ --policy.devicecuda \ --policy.use_amptrue \ --policy.vlm_dtypebfloat16 \ --policy.use_flash_attnfalse \ --policy.enable_gradient_checkpointingfalse \ --policy.vlm_num_layers14 \ --policy.image_resolution[448,448] \ --policy.max_text_length1024 \ --policy.chunk_size50 \ --policy.n_action_steps14 \ --policy.max_state_dim24 \ --policy.max_action_dim24 \ --policy.num_inference_timesteps32 \ --policy.postprocess_action_dim7 \ --policy.binarize_grippertrue \ --policy.gripper_threshold0.0 \ --policy.gripper_below_threshold_value-1.0 \ --policy.gripper_above_threshold_value1.0 \ --env.typelibero \ --env.task${suite} \ --env.task_ids[${task_id}] \ --env.camera_nameagentview_image,robot0_eye_in_hand_image \ --env.camera_name_mapping{agentview_image: image, robot0_eye_in_hand_image: image2} \ --env.control_moderelative \ --env.obs_typepixels_agent_pos \ --env.observation_width448 \ --env.observation_height448 \ --env.init_statestrue \ --env.episode_length${horizon} \ --env.render_modergb_array \ --env.max_parallel_tasks1 \ --eval.n_episodes50 \ --eval.batch_size1 \ --eval.use_async_envsfalse \ --eval.recordingfalse \ --seed1000 \ --output_dir./outputs/evo1-libero-stage2-70k-eval/${suite}/task-${task_id} \ --job_nameevo1-libero-stage2-70k-${suite}-task-${task_id} done按以下episode_length对每个 suite 运行全部 10 个任务 ID即每个 suite 500 个 episode、共 2,000 个 episode且每任务独立进程的拓扑与实测 RNG 重置拓扑一致env.taskenv.episode_lengthlibero_spatial280libero_object280libero_goal300libero_10520参考与延伸阅读完整的 EVO1 集成说明见 docs/source/evo1.mdx 与 docs/source/policy_evo1_README.md策略配置类的全部参数与校验逻辑见 configuration_evo1.py策略前向与推理实现见 modeling_evo1.pyflow-matching 动作头见 flow_matching.pyInternVL3 嵌入器见 internvl3_embedder.py预/后处理管线状态/动作填充、归一化统计填充、gripper 二值化见 processor_evo1.pyEVO1 由 MINT-SJTU 团队提出Evo-1 项目2025LeRobot 集成遵循 Apache 2.0 许可释放的模型检查点与数据请以对应模型页面的许可为准。上游 EVO1 项目还包含额外的训练脚本与数据集工具本文聚焦 LeRobot 中的机器人控制策略路径。如需了解 LeRobot 中其他 VLA 策略的对比可参考 docs/source/policies.mdx 与 策略工厂。【免费下载链接】lerobot LeRobot: Making AI for Robotics more accessible with end-to-end learning项目地址: https://gitcode.com/GitHub_Trending/le/lerobot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考