Views
No views yet

They don’t just see an image, they can integrate visual information directly into the reasoning chain.

image_zoom_in_tools for answer verification, etc.

1# Follow the VeRL official installation procedure
2pip install -e .
3
4# Additional dependencies required by DeepEyes
5bash scripts/install_deepeyes.sh1# download Qwen-2.5-72B-Instruct model
2huggingface-cli download --resume-download https://huggingface.co/Qwen/Qwen2.5-72B-Instruct --local-dir /path/to/your/local/filedir --local-dir-use-symlinks False
3
4# start vllm serving
5vllm serve /path/to/your/local/filedir \
6 --port 18901 \
7 --gpu-memory-utilization 0.8 \
8 --max-model-len 32768 \
9 --tensor-parallel-size 8 \
10 --served-model-name "judge" \
11 --trust-remote-code \
12 --disable-log-requests1# your wandb access key here...
2wandb login
3
4# the IP and port for your Qwen-2.5-72B-Instruct vllm serving
5export LLM_AS_A_JUDGE_BASE="http://your.vllm.machine.ip:18901/v1"
6
7# umber of training nodes
8export WORLD_SIZE=8
9
10# config for 7B
11bash examples/agent/final_merged_v1v8_thinklite.sh
12
13# config for 32B
14bash examples/agent/final_merged_v1v8_thinklite_32b.shenv_name field.env_name to your data parquet files. The env_name of each sample should specify the which tool is allowed to use when performing agent rollout. For non-agent training data, leave the env_name to None or empty string.env_name should be specified as visual_toolbox_v2.ToolBase class in verl/workers/agent/tool_envs.py as its base class.name variable, whose value corresponds to the env_name field in training data parquet files.execute and reset functions. Here is an simple example:1class CustomTool(ToolBase):
2 name = "custom_tool_v0"
3
4 def __init__(self, _name, _desc, _params, **kwargs):
5 super().__init__(name=self.name)
6
7 def execute(self, action_string: str, **kwargs) -> tuple:
8 """
9 Execute the tool functionality based on the LLM generated text.
10 This function is called EACH TIME after vllm.generate
11
12 Args:
13 action_string: The string generated by LLM via vllm.generate.
14
15 Returns:
16 observation: The structured observation with the processed image.
17 reward: setting a non-zero value if you want to assign a reward to the LAST GENERATED TOKEN in the intermediate steps.
18 done: Whether the episode is terminated.
19 info: Additional info.
20 """
21 pass
22
23 def reset(self, raw_prompt, multi_modal_data, origin_multi_modal_data, **kwargs):
24 """
25 This function is called ONLY ONCE when initializing the tools
26
27 Args:
28 raw_prompt: setting config param `data.return_raw_chat=True` to get raw prompt input.
29 multi_modal_data: refer to vllm documentation for details https://docs.vllm.ai/en/stable/features/multimodal_inputs.html
30 origin_multi_modal_data: VLM vision processor can modify the original images, typically by resizing, when they are too small or too large, use this param if you want to get access to the unmodified vision input.
31 """
32 passimage_zoom_in_tool in DeepEyes.from .envs.your_custom_tool import CustomTool1git remote add official https://github.com/volcengine/verl.git
2git pull official main@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},
}