Views
No views yet

Figure: Performance of UI-Venus across multiple benchmark datasets. UI-Venus achieves State-of-the-Art (SOTA) results on key UI understanding and interaction benchmarks, including ScreenSpot-Pro, ScreenSpot-v2, OS-World-G, UI-Vision, and Android World. The results demonstrate its superior capability in visual grounding, UI navigation, cross-platform generalization, and complex task reasoning.
pip install transformers==4.49.0 qwen-vl-utils1from transformers import Qwen2_5_VLForConditionalGeneration, AutoTokenizer, AutoProcessor
2from typing import Dict, Tuple, Any
3import torch
4import os
5import re
6from qwen_vl_utils import process_vision_info
7
8# -----------------------------
9# Model & Tokenizer
10# -----------------------------
11MODEL_NAME = "inclusionAI/UI-Venus-Navi-72B"
12
13model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
14 MODEL_NAME,
15 device_map="auto",
16 trust_remote_code=True,
17 torch_dtype=torch.bfloat16,
18 attn_implementation="flash_attention_2"
19).eval()
20
21tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
22processor = AutoProcessor.from_pretrained(MODEL_NAME)
23
24GENERATION_CONFIG = {
25 "max_new_tokens": 2048,
26 "do_sample": False,
27 "temperature": 0.0,
28}
29
30# -----------------------------
31# Prompt Template
32# -----------------------------
33PROMPT_TEMPLATE = """**You are a GUI Agent.**
34Your task is to analyze a given user task, review current screenshot and previous actions, and determine the next action to complete the task.
35
36### User Task
37{user_task}
38
39### Previous Actions
40{previous_actions}
41
42### Available Actions
43Click(box=(x1, y1))
44Drag(start=(x1, y1), end=(x2, y2))
45Scroll(start=(x1, y1), end=(x2, y2), direction='down/up/right/left')
46Type(content='')
47Launch(app='')
48Wait()
49Finished(content='')
50CallUser(content='')
51LongPress(box=(x1, y1))
52PressBack()
53PressHome()
54PressEnter()
55PressRecent()
56
57### Instruction
58- Make sure you understand the task goal to avoid wrong actions.
59- Examine the screenshot carefully. History may be unreliable.
60- For user questions, reply with `CallUser`, then `Finished` if done.
61- Explore screen content using scroll in different directions.
62- Copy text: select → click `copy`.
63- Paste text: long press text box → click `paste`.
64- First reason inside <think>, then provide <action>, then summarize in <conclusion>.
65"""
66
67# -----------------------------
68# Parse action
69# -----------------------------
70def parse_action(action_str: str) -> Tuple[str, Dict[str, Any]]:
71 """Parse action string into action type + params."""
72 pattern = r"^(\w+)\((.*)\)$"
73 match = re.match(pattern, action_str.strip(), re.DOTALL)
74 if not match:
75 print(f"Invalid action type: {action_str}")
76 return "", {}
77
78 action_type, params_str = match.group(1), match.group(2).strip()
79 params = {}
80
81 if params_str:
82 try:
83 # split by comma not inside parentheses
84 param_pairs = re.split(r",(?![^(]*\))", params_str)
85 for pair in param_pairs:
86 if "=" in pair:
87 key, value = pair.split("=", 1)
88 params[key.strip()] = value.strip().strip("'").strip()
89 else:
90 params[pair.strip()] = None
91 except Exception as e:
92 print(f"Parse param failed: {e}")
93 return action_type, {}
94 return action_type, params
95
96
97def extract_tag(content: str, tag: str) -> str:
98 """Extract latest <tag>...</tag> content from model output."""
99 pattern = fr"<{tag}>(.*?)</{tag}>"
100 matches = list(re.finditer(pattern, content, re.DOTALL))
101 if not matches:
102 print(f"{tag} Not Found")
103 return ""
104 return matches[-1].group(1).strip()
105
106# -----------------------------
107# Inference
108# -----------------------------
109def inference(image_path: str, goal: str) -> Dict[str, str]:
110 if not (os.path.exists(image_path) and os.path.isfile(image_path)):
111 raise FileNotFoundError(f"Invalid input image path: {image_path}")
112
113 full_prompt = PROMPT_TEMPLATE.format(user_task=goal, previous_actions="")
114
115 messages = [{
116 "role": "user",
117 "content": [
118 {"type": "text", "text": full_prompt},
119 {"type": "image", "image": image_path, "min_pixels": 3136, "max_pixels": 12845056},
120 ],
121 }]
122
123 text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
124 image_inputs, video_inputs = process_vision_info(messages)
125
126 model_inputs = processor(
127 text=[text],
128 images=image_inputs,
129 videos=video_inputs,
130 padding=True,
131 return_tensors="pt"
132 ).to(model.device)
133
134 generated_ids = model.generate(**model_inputs, **GENERATION_CONFIG)
135 generated_ids_trimmed = [out[len(inp):] for inp, out in zip(model_inputs.input_ids, generated_ids)]
136 output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True)[0]
137
138 return {
139 "raw_response": output_text,
140 "think": extract_tag(output_text, "think"),
141 "action": extract_tag(output_text, "action"),
142 "conclusion": extract_tag(output_text, "conclusion"),
143 }max_pixels and min_pixels before applying them.| Models | With Planner | A11y Tree | Screenshot | Success Rate (pass@1) |
|---|---|---|---|---|
| Closed-source Models | ||||
| GPT-4o | ❌ | ✅ | ❌ | 30.6 |
| ScaleTrack | ❌ | ✅ | ❌ | 44.0 |
| SeedVL-1.5 | ❌ | ✅ | ✅ | 62.1 |
| UI-TARS-1.5 | ❌ | ❌ | ✅ | 64.2 |
| Open-source Models | ||||
| GUI-Critic-R1-7B | ❌ | ✅ | ✅ | 27.6 |
| Qwen2.5-VL-72B* | ❌ | ❌ | ✅ | 35.0 |
| UGround | ✅ | ❌ | ✅ | 44.0 |
| Aria-UI | ✅ | ❌ | ✅ | 44.8 |
| UI-TARS-72B | ❌ | ❌ | ✅ | 46.6 |
| GLM-4.5v | ❌ | ❌ | ✅ | 57.0 |
| Ours | ||||
| UI-Venus-Navi-7B | ❌ | ❌ | ✅ | 49.1 |
| UI-Venus-Navi-72B | ❌ | ❌ | ✅ | 65.9 |
Table: Performance comparison on AndroidWorld for end-to-end models. Our UI-Venus-Navi-72B achieves state-of-the-art performance, outperforming all baseline methods across different settings.
| Models | AndroidControl-Low Type Acc. | AndroidControl-Low Step SR | AndroidControl-High Type Acc. | AndroidControl-High Step SR | GUI-Odyssey Type Acc. | GUI-Odyssey Step SR |
|---|---|---|---|---|---|---|
| Closed-source Models | ||||||
| GPT-4o | 74.3 | 19.4 | 66.3 | 20.8 | 34.3 | 3.3 |
| Open Source Models | ||||||
| Qwen2.5-VL-7B | 94.1 | 85.0 | 75.1 | 62.9 | 59.5 | 46.3 |
| SeeClick | 93.0 | 75.0 | 82.9 | 59.1 | 71.0 | 53.9 |
| OS-Atlas-7B | 93.6 | 85.2 | 85.2 | 71.2 | 84.5 | 62.0 |
| Aguvis-7B | - | 80.5 | - | 61.5 | - | - |
| Aguvis-72B | - | 84.4 | - | 66.4 | - | - |
| OS-Genesis-7B | 90.7 | 74.2 | 66.2 | 44.5 | - | - |
| UI-TARS-7B | 98.0 | 90.8 | 83.7 | 72.5 | 94.6 | 87.0 |
| UI-TARS-72B | 98.1 | 91.3 | 85.2 | 74.7 | 95.4 | 88.6 |
| GUI-R1-7B | 85.2 | 66.5 | 71.6 | 51.7 | 65.5 | 38.8 |
| NaviMaster-7B | 85.6 | 69.9 | 72.9 | 54.0 | - | - |
| UI-AGILE-7B | 87.7 | 77.6 | 80.1 | 60.6 | - | - |
| AgentCPM-GUI | 94.4 | 90.2 | 77.7 | 69.2 | 90.0 | 75.0 |
| Ours | ||||||
| UI-Venus-Navi-7B | 97.1 | 92.4 | 86.5 | 76.1 | 87.3 | 71.5 |
| UI-Venus-Navi-72B | 96.7 | 92.9 | 85.9 | 77.2 | 87.2 | 72.4 |
Table: Performance comparison on offline UI navigation datasets including AndroidControl and GUI-Odyssey. Note that models with * are reproduced.
1@misc{gu2025uivenustechnicalreportbuilding,
2 title={UI-Venus Technical Report: Building High-performance UI Agents with RFT},
3 author={Zhangxuan Gu and Zhengwen Zeng and Zhenyu Xu and Xingran Zhou and Shuheng Shen and Yunfei Liu and Beitong Zhou and Changhua Meng and Tianyu Xia and Weizhi Chen and Yue Wen and Jingya Dou and Fei Tang and Jinzhen Lin and Yulin Liu and Zhenlin Guo and Yichen Gong and Heng Jia and Changlong Gao and Yuan Guo and Yong Deng and Zhenyu Guo and Liang Chen and Weiqiang Wang},
4 year={2025},
5 eprint={2508.10833},
6 archivePrefix={arXiv},
7 primaryClass={cs.CV},
8 url={https://arxiv.org/abs/2508.10833},
9}