Infini RL
1. Condense 给 RL 训练带来的新问题
Condense 解决了 rollout 能不能跑完的问题,但对训练而言却引入了一个根本性矛盾:
一个任务在 rollout 端是一条完整的轨迹,但在训练端被 condense 切成了 N 段彼此独立的 prompt-response 样本。
具体困难有三:
- 训练样本碎片化:condense 后每段的 prompt 都是"压缩过的新起点",trainer 看到的是 N 个互不相关的
(prompt, response)pair,原本属于同一条轨迹的因果关系被切断。 - Reward 信号位置错位:reward 只能在最终答案那一段算出来(前面段没有最终输出,无法 verify)。如果按传统 PPO/GRPO 每段独立算 advantage,前面 N-1 段的所有 token 拿到的 advantage 都是 0,等于浪费了 80%+ 的 rollout 算力。
- GAE 边界不连续:标准 GAE 在每段末尾把
nextvalues = 0(视为 terminal state),但在 long-horizon agent 中,段尾并不是"任务结束",而是"被 condense 打断"。把它当 terminal 会让 value function 学到错误的边界,导致 critic 永远低估前面段的价值。
| 维度 | drop(ToolFIFOCondenser) | summarize(LLMSummary / Claude /compact) |
|---|---|---|
| log_prob 可复现 | ✓ 训练时跟 rollout 时完全一致 | ✗ summary 文本本身有随机性 |
| 段边界确定性 | ✓ FIFO 是确定性操作,段边界 token 序列固定 | ✗ summary 内容/长度都不固定,GAE 拼接难做 |
| 行为可解释 | ✓ 直观可见丢了哪条 | ✗ 出错难以 debug |
| 生产延迟 | ✓ 零额外开销 | ✗ 多一次 LLM call |
| 信息保真 | ✗ drop 即真丢 | △ 取决于 summary 质量 |
| 跟现有 mask 机制契合 | ✓ 复用 loss_mask |
✗ 需要新增 “summary token 区分” |
代价是信息损失更彻底,但 Infini RL 通过 GAE 跨段拼接把这部分信息以 reward 信号的形式补回来:被丢掉的 observation 对应的 assistant token 仍然能拿到非零 advantage(来自后续段的 reward 经 γλ 衰减反传)。整体在数学上闭合、在工程上可复现,是 production-grade RL 训练的合理取舍。
挑战
|
|
D1. Reward 归属:reward 只产生在最后一段,前面段怎么训?
任务成功/失败的 reward 信号只在 inv_iter=0 这段产生(agent 答对/答错的那一刻)。但前面 N-1 段的 action 才是把 trajectory 引向成功的真正原因。如果只用最后一段算 loss,前 N-1 段的 assistant 输出就完全得不到 credit assignment —— 模型学不到"前期搜索策略要怎么选才好"。
核心矛盾:reward 时空上集中在末尾,但需要把信号"反传"到前面所有段。
D2. Advantage 估计断裂:标准 GAE 跨不过段边界
GAE 的递推公式是:
$$ δ_t = r_t + γ·V (s_{t+1}) − V (s_t) $$
$$ A_t = δ_t + γλ·A_{t+1} $$ 它本质是从后往前沿着 token 序列递推。如果把每段当独立 trajectory 算:
段 2 GAE: A_t = δ_t + γλ·A_{t+1}, …, 直到段 2 第一个 token,链断。
段 1 GAE: A_t 完全独立计算,从段 1 末尾倒推
段 0 GAE: 同上
→ 段 2 的 reward 信号根本无法反传到段 1/段 0 的 action。这是 D 1 的技术表现。
D3. 段间 prompt “不连续”
段 1 开头的 prompt 是 [sys, user_q, t₃](被 condense 后的骨架),跟段 0 末尾的 prompt [sys, user_q, a₁ t₁ a₂ t₂ a₃ t₃] 不是延续关系。这意味着:
- 不能简单 concat 所有段的 token 来算"一条长 trajectory 的 GAE"
- 段 1 起点的
V(s)估计跟段 0 终点的V(s)估计是两个 state 上的值,不能直接接
D4. Importance Sampling 的 prompt 复现
PPO 的核心是 ratio = π_new(a|s) / π_old(a|s),训练时必须用当时的 prompt + 当时的 response 重算 π_new(a|s)。Condense 是 deterministic 的(Drop 路线 OK),但训练 worker 必须能完全复现 rollout worker 当时看到的 prompt —— 这要求把 condense 的产物(哪段 message 被丢了、剩了哪些)准确序列化到 DataProto 里随 batch 传过来。
D5. Sequence Length 维度的爆炸
如果朴素地把整条逻辑 trajectory 拼到一起塞给训练(不切段),单条 sample 的 sequence length 可能是几十万 token,GPU 装不下。但如果按段切(每段 ≤ max_prompt_length + max_response_length),又面临 1-4 的问题。
→ 既要段化 fit 进 GPU,又要保留段间信号传递。
D6. 重复内容的 loss 重复计算
每段 prompt 的开头都重复包含 [sys, user_q, ...还有上次 condense 留的骨架]。如果不做特殊处理,PPO loss 会在多段里反复对同一段 token 算 loss:
- assistant 段 0 输出的
a₃既出现在段 0 的 response 区域,也可能出现在段 1 的 prompt 区域(如果 condense 没把它丢掉的话) - 还有 sys、user_q 这些静态 prompt 永远在每段重复
→ 必须明确:哪段的哪些 token 才参与 loss 计算?
3. InfiniRL 的核心 idea
InfiniRL 的整体设计可以用一句话概括:
物理上分段、逻辑上连续 —— 每段当独立 sample 喂给 trainer(解决 D5),但通过
inv_iter+loss_mask+ 跨段 GAE 三个机制把段间的信号通路重新接上(解决 D1-D4、D6)。
═══════════════════════════════════════════════════════════════════════════
InfiniRL 三件套
═══════════════════════════════════════════════════════════════════════════
┌───────────────────────────────────────────────────────────────────┐
│ 机制 1: inv_iter ── 给每段标号 │
│ ───────────────────────────── │
│ 最末段 inv_iter=0, 倒数第二段 inv_iter=1, ... │
│ 在 rollout 端 (swalm_handler.py:1602-1605) 注入到 DataProto │
│ trainer 端 (ppo.py:445-523) 用它决定 GAE 处理顺序 │
└───────────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────┐
│ 机制 2: loss_mask ── 谁的 token 算 loss │
│ ─────────────────────────────────── │
│ 新生成的 assistant token: loss_mask = 1 │
│ 被 condense 进 prompt 的老 token: loss_mask = 0 │
│ → 每段 loss 只对"本段刚 generate 出来的"算 │
│ → 重复出现的 sys/user_q/骨架不参与 loss │
└───────────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────┐
│ 机制 3: 跨段 GAE ── reward 信号反传链 │
│ ────────────────────────────────── │
│ 按 inv_iter 从大到小处理: inv_iter=N → N-1 → ... → 1 → 0 │
│ 跨段传递 (lastgaelam, critic_lastgaelam, nextvalues) │
│ → 末段的 reward 沿着 GAE 链反传到所有段的 action 上 │
└───────────────────────────────────────────────────────────────────┘
═══════════════════════════════════════════════════════════════════════════
-
No backlinks found.