UI-TARS 2.0 论文精读
2025-12-16
DL论文
00

目录

1. 他们到底想解决什么问题?
2. 核心方法论:四大支柱
2.1 数据飞轮 (Data Flywheel)
怎么冷启动?
怎么迭代?
2.2 沙盒环境:All-in-One GUI Sandbox
(1) GUI 环境:云虚拟机集群
(2) 游戏环境:硬件加速的浏览器沙盒
2.3 数据标注:怎么搞到高质量轨迹?
CT 数据:In-Situ Annotation (原地标注)
SFT 数据:Interactive Annotation (交互式标注)
2.4 多轮强化学习:怎么训一个能玩 1000 步游戏的模型?
2.4.1 任务设计:怎么自动生成可验证的训练任务?
(1) GUI-Browsing: 信息检索任务
(2) GUI-General: 通用网页操作任务
(3) Gameplay: 游戏任务
2.4.2 奖励设计:怎么判断任务做得好不好?
(1) 有标准答案
(2) 没有标准答案 (GUI-General)
2.4.3 训练基础设施:怎么跑几百万次 rollout 不崩溃?
(1) 异步推理 + 服务器化 Rollout
(2) 有状态环境 (Stateful Environment)
(3) 流式训练 (Streaming Training)
2.4.4 RL 算法:PPO 魔改大法
技巧 1: Reward Shaping (奖励塑形)
技巧 2: Decoupled GAE (解耦广义优势估计)
技巧 3: Length-Adaptive GAE (长度自适应)
技巧 4: Value Pretraining (价值预训练)
技巧 5: Clip Higher (非对称裁剪)
2.5 参数插值:怎么把多个专家 Agent 合成一个通才?
3. 实验结果:到底有多强?
3.1 GUI 任务:全面吊打
3.2 游戏任务:接近人类 60%
3.3 推理时扩展 (Inference-Time Scaling)
4. 训练过程的有趣发现
4.1 熵的变化:探索 vs 利用
4.2 Think Length 的变化:从长到短
4.3 VLM-as-Verifier 靠谱吗?
4.4 PPO vs GRPO
4.5 混合 RL:GUI + GUI-SDK
5. 对我们的启发
5.1 数据层面
5.2 训练层面
5.3 环境层面
6. 还有哪些坑?
7. 总结

https://arxiv.org/pdf/2509.02544

1. 他们到底想解决什么问题?

想象一下,你想让 AI 帮你:

  • 在京东上搜"三体",找到刘慈欣写的、50 块钱以内的书,加入购物车
  • 玩一局 2048,尽量拿高分
  • 在 Ubuntu 上用终端命令处理文件、跑代码

这些任务有个共同特点:需要多步操作、需要看屏幕、需要根据反馈调整策略。这就是 GUI Agent 要干的事儿。

但现有方案有几个大坑:

  1. 数据太少: 不像文本和代码有海量训练数据,GUI 操作的轨迹数据贵得要死
  2. 多轮 RL 难训: 游戏可能要几百步才结束,奖励稀疏,模型不知道哪步做对了
  3. 纯 GUI 不够用: 很多任务用命令行、文件系统更高效,纯点鼠标太慢
  4. 环境不稳定: 要跑几百万次交互,虚拟机动不动就崩溃

UI-TARS-2 就是奔着这四个问题去的。


2. 核心方法论:四大支柱

2.1 数据飞轮 (Data Flywheel)

核心思想: 模型和数据互相喂养,越滚越大。

怎么冷启动?

一开始得有种子数据:

  • CT (Continual Pre-training) 数据: UI-TARS 1.0/1.5 的数据 + 网上爬的教程视频 + 人工标注的轨迹
  • SFT (Supervised Fine-Tuning) 数据: 合成数据 + 高质量人工标注

注意:Agent 数据只占一小部分,大头还是通用数据(聊天、推理等),目的是保留模型的通用能力。

怎么迭代?

训练完第一轮 RL 模型后,用它来生成新数据:

展开代码
新数据 = rejection sampling (RFT) + interactive annotation

然后用一个验证模型 V(s) 给每条数据打分:

  • 高质量 (V(s)=1): 扔进下一轮 SFT
  • 低质量 (V(s)=0): 扔进下一轮 CT (让模型见见世面)

这样形成正反馈循环:

展开代码
更好的模型 → 更多高质量数据 → 更更好的模型

而且没有数据浪费,低质量数据也能用来做 CT。


2.2 沙盒环境
GUI Sandbox

训练 Agent 需要一个能跑得动、跑得稳的环境。UI-TARS-2 搞了两套:

(1) GUI 环境:云虚拟机集群

  • 支持 Windows、Ubuntu、Android 三大系统
  • 几千台虚拟机,支持每秒几千次查询 (QPS)
  • 每个 session 有独立 ID,支持 VNC 实时监控
  • 关键创新: 共享文件系统,浏览器下载的文件可以直接用命令行处理

技术细节:

python
展开代码
# 伪代码示意 vm = VMManager.allocate(os="ubuntu") vm.execute_gui_action("click", x=100, y=200) vm.execute_shell("cat downloaded_file.txt | grep keyword")

(2) 游戏环境:硬件加速的浏览器沙盒

为什么要单独搞游戏环境? 因为:

  • 游戏都是 HTML5/WebGL,必须跑在浏览器里
  • 需要高并发 (一个容器跑多个浏览器实例)
  • 需要控制时间流速 (加速训练)

黑科技: 重新实现了浏览器的 Window.setTimeout 等 API,可以暂停/加速游戏时间,同时不改变游戏逻辑。


2.3 数据标注:怎么搞到高质量轨迹?

CT 数据
Annotation (原地标注)

问题: 之前的数据只有 action,没有 reasoning (思考过程),导致模型只会模仿,不理解为什么这么做。

解决方案: Think-Aloud Protocol (边想边说)

  1. 标注员边操作边说出想法,录音
  2. 用 ASR 转文字,LLM 润色成高质量 reasoning
  3. 自动对齐到每一步操作

举个例子:

展开代码
[标注员操作] 点击搜索框 [录音转文字] "我现在要搜三体,先得点这个搜索框" [LLM 润色] "为了完成任务,首先需要在搜索框中输入关键词'三体'"

还有个妙招:让新手标注员做不会的任务。新手会搜索、试错、查资料,这些过程都是宝贵的训练数据。

SFT 数据
Annotation (交互式标注)

问题: 传统标注是 off-policy 的,标注员的操作和模型的操作分布不一样,训练效果差。

解决方案: Human-in-the-Loop (人在回路里)

流程:

  1. 给标注员一个任务 (比如"在京东搜三体")
  2. 模型生成 3 个候选 (每个都有 thought + action)
  3. 标注员选一个,或者自己手动输入
  4. 环境执行这个 action,模型看到反馈后继续预测
  5. 重复直到任务完成

关键优势: 标注数据和模型实际 rollout 的分布一致 (on-policy),而且标注员能实时纠错。


2.4 多轮强化学习:怎么训一个能玩 1000 步游戏的模型?

2.4.1 任务设计:怎么自动生成可验证的训练任务?

RL 需要大量任务 + 可靠的奖励信号。他们设计了三类任务:

(1) GUI-Browsing: 信息检索任务

目标: 让模型学会通过网页搜索、推理来回答复杂问题。

任务生成方法 1: 多条件模糊化

从维基百科抽取实体 (比如一个乐队),然后故意"脱敏":

展开代码
原始信息: - 乐队: AC/DC - 成员来自: Dreghorn 和 Irvine - 签约唱片公司: Atlantic Records 生成问题: "被某人才机构发现,最初阵容包括来自 Dreghorn 和 Irvine 的成员, 主唱是创始成员推荐的。这个乐队签的是哪家唱片公司?" 答案: Atlantic Records

关键:无法直接搜索,必须多步推理

任务生成方法 2: 多跳链式条件

递归构造推理链:

展开代码
问题: "完成某 20 世纪航天计划的指令舱驾驶员毕业的大学, 校园里以他命名的工程楼叫什么?" 推理链: 1. 某航天计划 → 阿波罗 11 号 2. 指令舱驾驶员 → Michael Collins 3. 毕业大学 → 西点军校 4. 以他命名的工程楼 → (搜索答案)
(2) GUI-General: 通用网页操作任务

直接从真实网站抽取功能,合成任务:

展开代码
"访问京东,搜索'三体',找到刘慈欣著、价格<50元的纸质书,加入购物车"

过滤掉:

  • 需要登录的
  • 太简单的 (一步完成)
  • 太难验证的
(3) Gameplay: 游戏任务

收集/生成小游戏,写 JS 验证脚本:

javascript
展开代码
// 验证脚本示例 function verify_game_state() { return { score: game.score, level: game.level, success: game.score > 1000 }; }

为什么要训游戏? 游戏是最好的长周期决策训练场,而且能自动生成无限任务。


2.4.2 奖励设计:怎么判断任务做得好不好?

两种情况:

(1) 有标准答案
  • Gameplay: 直接看游戏分数
  • GUI-Browsing: 用 LLM-as-Judge 比对答案
python
展开代码
# LLM-as-Judge 伪代码 def evaluate(model_answer, ground_truth): prompt = f"模型答案:{model_answer}\n标准答案:{ground_truth}\n是否正确?(是/否)" return llm(prompt) == "是"
(2) 没有标准答案 (GUI-General)

问题: 网页操作任务往往没有唯一答案,怎么判断对错?

解决方案: 训练一个专门的 Outcome Reward Model (ORM)

  • 输入: 完整文本历史 + 最后 5 张截图
  • 输出: 0~1 的分数
  • 训练方法:
    1. 人工标注一批 (成功/失败)
    2. 用 single-turn RL 训练到 F1=83.8

有意思的发现:即使 ORM 有 16% 的错误率,RL 照样能训好。为啥? 因为就算最终任务失败,中间步骤可能是对的,模型还是能学到东西。


2.4.3 训练基础设施:怎么跑几百万次 rollout 不崩溃?

三个关键设计:

(1) 异步推理 + 服务器化 Rollout

传统方式:

python
展开代码
for task in tasks: trajectory = model.rollout(task) # 阻塞等待 train(trajectory) # 训练

问题:长尾任务 (比如 1000 步的游戏) 会卡住整个训练流程。

新方式:

python
展开代码
# 伪代码 rollout_pool = [] for task in tasks: async_start(model.rollout, task) # 异步启动 while True: if len(rollout_pool) >= min_batch_size: train(rollout_pool) # 够一个 batch 就训练 rollout_pool = [未完成的轨迹] # 未完成的留着

效果: 不用等所有任务都跑完,够一个 batch 就可以开始训练。

(2) 有状态环境 (Stateful Environment)

传统 RL 环境每次 reset 都重新开始,UI-TARS-2 的环境保持状态:

python
展开代码
# 传统方式 env.reset() for step in range(max_steps): action = model(obs) obs = env.step(action) # UI-TARS-2 方式 session = env.create_session() # 创建持久 session for step in range(max_steps): action = model(obs) obs = session.step(action) # session 保持状态 # session 自动清理

好处: 支持需要多轮工具调用、文件读写的复杂任务。

(3) 流式训练 (Streaming Training)

不用等整个 batch 跑完:

展开代码
Rollout Pool: [完成的轨迹1, 完成的轨迹2, ..., 未完成的轨迹N] ↓ 只要够 min_batch_size 就开始训练 ↓ 未完成的轨迹继续跑,下次再训练

2.4.4 RL 算法
魔改大法

基础算法是 PPO (Proximal Policy Optimization),目标函数:

JPPO(θ)=E[min(rt(θ)A^t,clip(rt(θ),1εlow,1+εhigh)A^t)]\mathcal{J}_{\text{PPO}}(\theta) = \mathbb{E} \left[ \min \left( r_t(\theta) \hat{A}_t, \text{clip}(r_t(\theta), 1-\varepsilon_{\text{low}}, 1+\varepsilon_{\text{high}}) \hat{A}_t \right) \right]

其中:

  • rt(θ)=πθ(atst)πθold(atst)r_t(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{\text{old}}}(a_t|s_t)} (新旧策略的概率比)
  • A^t\hat{A}_t (Advantage,表示这个动作比平均好多少)
  • clip(x,a,b)\text{clip}(x, a, b) (把 xx 限制在 [a,b][a, b] 之间)

但直接用 PPO 训长周期任务会炸,他们加了 5 个关键技巧:

技巧 1: Reward Shaping (奖励塑形)

问题: 游戏可能 1000 步才结束,前 999 步奖励都是 0,模型不知道哪步做对了。

解决方案:

  • 主要奖励: 只看最终成功/失败
  • 辅助奖励:
    • Format Reward (输出格式对了就给点分)
    • Length Penalty (太长或太短都扣分)
python
展开代码
reward = final_success * 100 # 主奖励 if valid_format: reward += 1 # 格式奖励 reward -= 0.01 * num_steps # 长度惩罚
技巧 2: Decoupled GAE (解耦广义优势估计)

背景知识: Advantage A^t\hat{A}_t 衡量"这个动作比平均好多少",计算公式:

A^t=l=0(γλ)lδt+l\hat{A}_t = \sum_{l=0}^{\infty} (\gamma \lambda)^l \delta_{t+l}

其中 δt=rt+γV(st+1)V(st)\delta_t = r_t + \gamma V(s_{t+1}) - V(s_t) (TD error)

问题: 长序列 (比如 1000 步) 时,λ\lambda 太大会放大噪声,λ\lambda 太小会丢失长期信息。

解决方案: 策略网络和价值网络用不同的 λ\lambda:

策略网络:λpolicy=0.98(保留长期信息)价值网络:λcritic=0.90(快速衰减噪声)\begin{align} \text{策略网络}: & \quad \lambda_{\text{policy}} = 0.98 \quad \text{(保留长期信息)} \\ \text{价值网络}: & \quad \lambda_{\text{critic}} = 0.90 \quad \text{(快速衰减噪声)} \end{align}

直觉: 策略网络需要看到远期回报来学习规划,价值网络需要稳定估计来指导训练。

技巧 3: Length-Adaptive GAE (长度自适应)

问题: 10 步的简单任务和 1000 步的复杂任务,用同一个 λ\lambda 不合理。

解决方案: 根据序列长度 ll 动态调整:

λpolicy=11αl\lambda_{\text{policy}} = 1 - \frac{1}{\alpha \cdot l}

其中 α=0.05\alpha=0.05 (超参数)

效果:

  • 短序列 (l=10l=10): λ0.8\lambda \approx 0.8 (只看近期)
  • 长序列 (l=1000l=1000): λ0.98\lambda \approx 0.98 (看长期)
技巧 4: Value Pretraining (价值预训练)

问题: PPO 开始时,价值网络是随机初始化的,给出的 V(s)V(s) 乱七八糟,导致 Advantage 估计很差。

解决方案: 先用固定策略 (比如 SFT 模型) 跑一堆轨迹,用 Monte Carlo 真实回报 (λ=1.0\lambda=1.0) 训练价值网络:

Loss=E[(Vθ(st)k=0Ttγkrt+k)2]\text{Loss} = \mathbb{E} \left[ \left( V_\theta(s_t) - \sum_{k=0}^{T-t} \gamma^k r_{t+k} \right)^2 \right]

训练到 Explained Variance > 0.9 (价值网络能解释 90% 的回报方差) 再开始 PPO。

效果: 避免训练初期因为价值估计太烂导致策略崩溃。

技巧 5: Clip Higher (非对称裁剪)

标准 PPO: 把概率比裁剪到 [0.8,1.2][0.8, 1.2] (对称)

UI-TARS-2: 裁剪到 [0.9,1.3][0.9, 1.3] (非对称)

clip(rt,1εlow,1+εhigh)where εlow=0.1,εhigh=0.3\text{clip}(r_t, 1-\varepsilon_{\text{low}}, 1+\varepsilon_{\text{high}}) \quad \text{where } \varepsilon_{\text{low}}=0.1, \varepsilon_{\text{high}}=0.3

直觉:

  • εlow=0.1\varepsilon_{\text{low}}=0.1 (保守): 不轻易抛弃旧策略 (防止遗忘)
  • εhigh=0.3\varepsilon_{\text{high}}=0.3 (激进): 鼓励尝试低概率但可能高回报的新动作 (扩大探索)

2.5 参数插值:怎么把多个专家 Agent 合成一个通才?

问题: GUI-Browsing、GUI-General、Game 三个领域差异很大,联合训练不稳定。

解决方案: 分别训练,然后参数加权平均:

θ(merge)=α1θ(GUI-Browsing)+α2θ(GUI-General)+α3θ(Game)+\theta^{(\text{merge})} = \alpha_1 \theta^{(\text{GUI-Browsing})} + \alpha_2 \theta^{(\text{GUI-General})} + \alpha_3 \theta^{(\text{Game})} + \cdots

其中 αi=1,αi0\sum \alpha_i = 1, \alpha_i \geq 0

理论依据: 从同一个预训练模型微调出来的模型,在参数空间里是线性模式连接的 (linearly mode-connected),即参数插值后的模型性能不会太差。

实验发现: 合并后的模型在每个领域的表现都接近该领域的专家模型,而且能处理需要跨领域技能的复合任务。


3. 实验结果:到底有多强?

3.1 GUI 任务:全面吊打

模型OSWorldWindowsAgentArenaAndroidWorldOnline-Mind2Web
Claude-443.9---
OpenAI CUA-o342.9-52.571.0
UI-TARS-1.542.542.164.275.8
UI-TARS-247.550.673.388.2

关键发现:

  • 在 Online-Mind2Web 上达到 88.2%,接近人类水平
  • RL 训练后,OOD 泛化能力暴增 (OSWorld +10.5%, AndroidWorld +8.7%)

3.2 游戏任务:接近人类 60%

15 款游戏的平均归一化分数 (人类=100):

模型平均分
人类100.0
UI-TARS-259.8
OpenAI CUA24.7
Claude Computer Use21.6

亮点:

  • 在 2048、Infinity-Loop 等游戏上达到人类 90%+ 水平
  • 在 Shapes 上超过人类 (108.9 vs 100)
  • 比 OpenAI CUA 高 2.4 倍,比 Claude 高 2.8 倍

3.3 推理时扩展 (Inference-Time Scaling)

发现: 随着允许的最大步数增加,UI-TARS-2 的表现持续上升,其他模型很快就饱和了。

为什么? UI-TARS-2 学会了解锁新子目标,而不是瞎转悠。


4. 训练过程的有趣发现

4.1 熵的变化:探索 vs 利用

传统 reasoning RL (比如 OpenAI o1) 训练时,熵单调下降 (模型越来越确定)。

UI-TARS-2 的熵先升后降:

解释: GUI 和游戏环境需要持续探索,模型在学习过程中发现了更多有效策略,而不是过早收敛到单一解法。

4.2 Think Length 的变化:从长到短

GUI 任务: Think length 持续下降

解释: 一旦知道该点哪个按钮,就不需要长篇大论的推理了,直接行动更高效。

游戏任务: Think length 呈周期性

解释: 每次游戏升级难度,Think length 就上升 (需要思考新策略),熟悉后又下降。

4.3 VLM-as-Verifier 靠谱吗?

用 UI-TARS-2 自己当 ORM (奖励模型),F1=83.8,错误率 16%。

惊人发现: 即使错误率这么高,RL 照样训得好!

原因: 即使任务最终失败,中间很多步骤可能是对的,模型还是能从正确的中间步骤学到东西。这些正确步骤的奖励 > 错误奖励的负面影响。

4.4 PPO vs GRPO

GRPO 在推理任务上很强,但在 GUI Agent 上 PPO 碾压 GRPO:

推测: GRPO 更适合单轮推理,PPO 更适合多轮交互。

4.5 混合 RL
+ GUI-SDK

实验设置:

  • Baseline: 分别训练 GUI-only 和 GUI-SDK-only
  • Hybrid: 同时训练两种接口 (每种接口的数据量减半)

结果:

  • Hybrid 模型在 GUI-only 任务上超过 GUI-only baseline
  • 原因:GUI-SDK 学到的知识迁移到了 GUI

启示: 更强大的接口能帮助模型学习更好的表征,即使最终只用弱接口。


5. 对我们的启发

5.1 数据层面

  1. 在线 Interactive Annotation 是王道

    • 模型生成多个候选,人工选择/修正
    • 保证数据是 on-policy 的
  2. Think-Aloud 标注法

    • 让标注员边操作边说想法
    • ASR + LLM 润色,得到高质量 reasoning
  3. 数据飞轮

    • 高质量数据进 SFT,低质量数据进 CT
    • 没有数据浪费,持续迭代

5.2 训练层面

  1. 必须上 RL

    • SFT 只能到 80% 左右,RL 能冲到 90%+
    • RL 带来的泛化能力提升巨大 (OOD +10%)
  2. 长周期 RL 的关键技巧

    • Value Pretraining (价值预训练)
    • Decoupled GAE (解耦 λ\lambda)
    • Length-Adaptive GAE (自适应 λ\lambda)
    • Clip Higher (非对称裁剪)
  3. 流式训练 + 异步 Rollout

    • 不要等长尾任务,够一个 batch 就训练
    • 大幅提升训练效率

5.3 环境层面

  1. Stateful Environment

    • 支持多轮工具调用,保持状态
  2. GUI + SDK 混合

    • 纯 GUI 不够用,命令行、文件系统必不可少
  3. 硬件加速 + 时间操控

    • 游戏环境需要 GPU 加速截图
    • 能暂停/加速游戏时间,提升采样效率

6. 还有哪些坑?

  1. 奖励模型的假阳率

    • 当前 ORM 的 F1=83.8,还有 16% 的错误
    • 虽然不影响训练,但理论上还有提升空间
  2. 长周期任务的信用分配

    • 1000 步的游戏,怎么知道第 37 步做对了?
    • 当前主要靠稀疏奖励 + Value Pretraining,还可以引入更多先验 (比如 Hindsight Experience Replay)
  3. 参数插值的权重

    • 论文没说 αi\alpha_i 怎么定的
    • 可能需要网格搜索或者用验证集调
  4. 量化带来的精度损失

    • W4A8 量化后,OSWorld 从 47.5 降到 44.4
    • 对延迟敏感的应用可以接受,但还有优化空间

7. 总结

UI-TARS-2 最牛的地方不是某个单点技术,而是系统性的方法论:

  1. 数据飞轮: 模型和数据互相喂养,持续迭代
  2. Interactive Annotation: On-policy 数据采集,人在回路
  3. Sandbox 环境: GUI + SDK 混合,有状态,高并发
  4. 魔改 PPO: 5 个关键技巧,专治长周期 RL
  5. 参数插值: 分别训练专家,合并成通才

如果你想做 GUI Agent,这篇论文是必读的。不仅技术细节清晰,而且很多坑都帮你踩过了。

最后提一句:开源万岁! 字节愿意把这么多细节公开,对整个社区都是巨大贡献。


参考文献:

  • UI-TARS-2
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!