🚀 DeepEyes:通过强化学习激励“以图思考”
DeepEyes是一个通过强化学习来激励“以图思考”的项目。它能够将视觉信息直接融入推理链,在图像文本处理任务中具有出色表现。
🚀 快速开始
环境搭建
pip install -e .
bash scripts/install_deepeyes.sh
开始训练
我们使用 Qwen-2.5-VL-7B-Instruct 作为强化学习训练的基础模型,同时也支持 Qwen-2.5-VL-32B-Instruct。
对于7B模型的训练,建议使用不少于32个GPU(4个节点 x 8个GPU);对于32B模型的训练,建议使用不少于64个GPU(8个节点 x 8个GPU)。每个节点建议使用不少于1200GB的CPU内存,因为V*和ArxivQA数据集中的高分辨率图像会占用大量内存。
步骤1:启动 Qwen-2.5-72B-Instruct 的vllm服务,用于大语言模型作为评判器的验证。
huggingface-cli download --resume-download https://huggingface.co/Qwen/Qwen2.5-72B-Instruct --local-dir /path/to/your/local/filedir --local-dir-use-symlinks False
vllm serve /path/to/your/local/filedir \
--port 18901 \
--gpu-memory-utilization 0.8 \
--max-model-len 32768 \
--tensor-parallel-size 8 \
--served-model-name "judge" \
--trust-remote-code \
--disable-log-requests
步骤2:为所有训练节点构建一个Ray集群。在开始训练前准备好数据,我们的训练数据集可以从 huggingface 下载。
步骤3:使用以下脚本之一开始训练。
wandb login
export LLM_AS_A_JUDGE_BASE="http://your.vllm.machine.ip:18901/v1"
export WORLD_SIZE=8
bash examples/agent/final_merged_v1v8_thinklite.sh
bash examples/agent/final_merged_v1v8_thinklite_32b.sh
训练脚本使用 wandb 和 RL Logging Board(很棒的项目)来可视化训练动态。
✨ 主要特性
- DeepEyes“以图思考”的能力是通过端到端强化学习习得的。它直接由结果奖励信号引导,无需冷启动或有监督的微调,也不依赖专门的外部模型。
- 尽管在中间步骤没有直接的监督,但在强化学习训练阶段,定位IoU和工具调用准确率都有所提高。
- 端到端的强化学习训练在高分辨率基准测试中带来了显著的性能提升,并且在视觉定位、幻觉缓解和数学问题解决任务中表现出强大的泛化能力。
- 在强化学习训练过程中,我们观察到了一些思考模式的出现,例如对小物体的视觉搜索、跨不同区域的视觉比较、使用
image_zoom_in_tools
进行答案验证等。
📚 详细文档
代码总体介绍
本仓库中的代码是一个基于 VeRL 的通用智能体强化学习训练框架。除了DeepEyes,还可以使用我们的代码实现进行任何形式的通用智能体强化学习(多轮强化学习)训练。
代码旨在满足以下需求:
- 高效的智能体强化学习训练:智能体在所有数据并行组中异步进行滚动更新。
- 允许智能体观察中的动态多模态输入:这是“以图思考”能力强化学习训练的关键。
- 允许对使用不同工具的智能体数据和非智能体数据进行混合训练:工具的使用不是硬编码在滚动更新循环中的,每个样本可以通过
env_name
字段指定自己的工具使用约束。
- 支持算法:支持PPO、GRPO和reinforce++。我们修改了优势估计、策略损失掩码以及Qwen-VL模型的mrope,以使其与智能体多轮强化学习训练的交错结构兼容。
- 兼容最新的VeRL更新:智能体强化学习训练作为VeRL的一个插件实现,便于与最新的VeRL更新合并。一旦关闭插件开关,其功能与原始版本的VeRL无异。
在自定义数据集上训练
在你的数据parquet文件中添加一个额外的字段 env_name
。每个样本的 env_name
应指定在进行智能体滚动更新时允许使用的工具。对于非智能体训练数据,将 env_name
留空或设为None。
例如,对于DeepEyes风格的训练,env_name
应指定为 visual_toolbox_v2
。
其余部分与原始VeRL数据集格式相同,详情请参考 VeRL官方文档。
使用自定义工具训练
在一个新的类中实现你的工具函数,该类继承自 verl/workers/agent/tool_envs.py 中的 ToolBase
类。
子类必须包含 name
变量,其值对应于训练数据parquet文件中的 env_name
字段。
实现 execute
和 reset
函数,以下是一个简单的示例:
class CustomTool(ToolBase):
name = "custom_tool_v0"
def __init__(self, _name, _desc, _params, **kwargs):
super().__init__(name=self.name)
def execute(self, action_string: str, **kwargs) -> tuple:
"""
根据大语言模型生成的文本执行工具功能。
此函数在每次vllm.generate之后调用
参数:
action_string: 大语言模型通过vllm.generate生成的字符串。
返回:
observation: 处理后图像的结构化观察结果。
reward: 如果你想为中间步骤中的最后一个生成令牌分配奖励,则设置一个非零值。
done: 该回合是否结束。
info: 额外信息。
"""
pass
def reset(self, raw_prompt, multi_modal_data, origin_multi_modal_data, **kwargs):
"""
此函数仅在初始化工具时调用一次
参数:
raw_prompt: 设置配置参数 `data.return_raw_chat=True` 以获取原始提示输入。
multi_modal_data: 详情请参考vllm文档 https://docs.vllm.ai/en/stable/features/multimodal_inputs.html
origin_multi_modal_data: VLM视觉处理器在图像太小或太大时可能会修改原始图像,通常是通过调整大小。如果你想访问未修改的视觉输入,请使用此参数。
"""
pass
参考 verl/workers/agent/envs/mm_process_engine/visual_toolbox_v2.py 中的 image_zoom_in_tool
示例。
重要提示:在 verl/workers/agent/init.py 中导入你的自定义工具。
from .envs.your_custom_tool import CustomTool
使用最新的VeRL代码
如果你想使用最新的VeRL代码进行训练,可以执行以下操作:
git remote add official https://github.com/volcengine/verl.git
git pull official main
📄 许可证
本项目根据 Apache许可证 发布。
引用
@article{zheng2025deepeyesincentivizingthinkingimages,
title={DeepEyes: Incentivizing "Thinking with Images" via Reinforcement Learning},
author={Ziwei Zheng, Michael Yang, Jack Hong, Chenxiao Zhao, Guohai Xu, Le Yang, Chao Shen, Xing Yu},
year={2025},
eprint={2505.14362},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2505.14362},
}
信息表格
属性 |
详情 |
基础模型 |
Qwen/Qwen2.5-VL-7B-Instruct |
语言 |
英文 |
许可证 |
apache-2.0 |
任务类型 |
图像文本到文本 |
库名称 |
transformers |
* 标志灵感来源于甲骨文“目”字。
⚠️ 重要提示
训练过程中需要注意GPU和内存的使用情况,确保资源充足。
💡 使用建议
在使用自定义数据集和工具时,仔细阅读文档并参考示例代码,确保配置正确。