Advantage 估计与 GAE:把长期回报变成局部学习信号¶
策略梯度需要回答的不是“这条轨迹最后得了多少分”,而是“在当时已经看到的信息下,这个动作比策略通常会做的选择好多少”。前者是 return,后者是 advantage。两者只差一个 baseline,却对应完全不同的统计问题:return 决定任务目标,advantage estimator 决定有限样本怎样把这个目标分配给每一次更新。
本页从 TD residual 推出 Generalized Advantage Estimation(GAE),重点解释它的边界语义、actor 与 critic 的不同 target,以及语言模型中 token、turn、segment 三条时间轴。多步 return 与 eligibility trace 的共同背景见多步回报、资格迹与 GAE,策略梯度为什么允许减去 baseline 见 Policy Gradient,value function 的训练耦合见 Actor–Critic。
Advantage 为什么是策略更新的接口¶
对策略 \(\pi\),状态价值、动作价值与优势函数分别为
\(Q^\pi\) 回答“先做这个动作,再按 \(\pi\) 行动会得到什么”,\(V^\pi\) 回答“按 \(\pi\) 在这里通常会得到什么”。二者相减后,正 advantage 表示该动作优于当前策略的条件平均水平,负 advantage 表示更差。Policy-gradient theorem 因而可以写成
真实 \(A^\pi\) 不可直接查询,只能用 rollout 与 learned value 估计。最简单的 Monte Carlo estimator 是
它等待完整回报,较少依赖 bootstrap,却会把后续所有随机性都带回当前时刻。一步 TD estimator 则是
方差通常更低,但直接依赖 value 的局部准确性。GAE 不是一种新的 reward,也不改变环境目标;它在这两端之间组合多个 TD residual。
从 TD residual 推出 GAE¶
先固定一份 value snapshot \(\widehat V\)。对非终止 transition 定义
把连续两个 residual 相加:
中间的 \(\widehat V(s_{t+1})\) 正好抵消,得到两步 bootstrap return 减去当前 value。一般地,
GAE 再用 \(\lambda\) 对这些不同长度的 advantage estimator 做指数加权。最常用的 residual 形式为
在没有边界的理想情形下:
- \(\lambda=0\) 只保留一步 TD residual;
- \(\lambda\to1\) 且展开到真实 episode 终点时,望远镜消去中间 value,接近 Monte Carlo return 减 baseline;
- 中间的 \(\lambda\) 让较远 residual 的影响按 \((\gamma\lambda)^\ell\) 衰减。
这里 \(\gamma\) 与 \(\lambda\) 不能互换。\(\gamma\) 首先定义任务怎样权衡远期 reward;改变它通常改变优化目标。\(\lambda\) 主要决定 advantage estimator 对 bootstrap bias 与采样 variance 的权衡。把 \(\lambda\) 称为“第二个 discount”会掩盖这个区别。
有限轨迹上不应真的构造所有 \(n\)-step return。反向递推即可得到同一固定 value snapshot 下的结果:
真正困难的部分不是这行递推,而是“下一项是否存在”“下一状态是否还能 bootstrap”以及“一步究竟对应 token、turn 还是环境 transition”。
Terminal 与 truncated 是两个不同问题¶
令
其中轨迹边界包含 terminated 与 truncated。于是 TD residual 应写成
GAE 递推则写成
两个 mask 承担不同职责:
terminated表示任务动力学已经结束,未来价值为零,因此禁止 bootstrap;truncated表示时间预算、最大步数或采样窗口结束,任务本身未必结束,因此通常仍从真实 final observation bootstrap;- 两者都会结束当前存储片段,所以 GAE carry 不得穿进 batch 中物理相邻的下一条轨迹;
- timeout、工具崩溃、reward 服务缺失等基础设施错误不应被悄悄编码成普通 terminal 或零 reward。
一个常见错误是只保存 done = terminated or truncated,并同时用它关闭 bootstrap 与 trace。这样会把 time-limit truncation 的尾部价值系统性压低。另一个错误是在截断处读取 packed tensor 的 value[t + 1];那个位置可能已经属于下一条 episode。正确的数据对象应显式保存 transition 自己的 next_value,它由该 transition 的真实后继 observation 计算。
下面的语义实现直接接收一维 packed transition;terminated[t] 只关闭当前 TD bootstrap,boundary[t] 只阻止 carry 流入物理相邻的下一条轨迹。输出 advantage 与 \(\lambda\)-return 都被冻结,可分别交给 actor 和 critic;padding 应在调用前移除,action mask 则只在后续 policy loss 中使用。
import torch
@torch.no_grad()
def packed_gae(reward, value, next_value, terminated, boundary, gamma=.99, lam=.95):
if not all(x.shape == reward.shape for x in (value, next_value, terminated, boundary)):
raise ValueError("all transition tensors must have the same shape")
if reward.ndim != 1 or reward.numel() == 0 or not boundary[-1]:
raise ValueError("a packed fragment must be non-empty, one-dimensional and boundary-closed")
if terminated.dtype != torch.bool or boundary.dtype != torch.bool:
raise ValueError("terminated and boundary must be boolean")
if torch.any(terminated & ~boundary):
raise ValueError("every terminal transition must also close its packed trajectory")
bootstrap = torch.where(terminated, torch.zeros_like(next_value), next_value)
delta = reward + gamma * bootstrap - value
advantage = torch.empty_like(delta)
carry = delta.new_zeros(())
for t in range(delta.numel() - 1, -1, -1):
carry = delta[t] if boundary[t] else delta[t] + gamma * lam * carry
advantage[t] = carry
return advantage, advantage + value
reward, value, next_value = map(torch.tensor, ([1., 2., 10.], [.5, 1., 3.], [1., 4., float("nan")]))
terminated = torch.tensor([False, False, True]); boundary = torch.tensor([False, True, True])
adv, target = packed_gae(reward, value, next_value, terminated, boundary, .5, .8)
delta = reward + .5 * torch.where(terminated, torch.zeros_like(next_value), next_value) - value
torch.testing.assert_close(adv, torch.tensor([delta[0] + .4 * delta[1], delta[1], delta[2]]))
assert not adv.requires_grad and target[1] == 4
for bad_terminated, bad_boundary in [
(torch.tensor([False, True, False]), torch.tensor([False, False, True])),
(torch.zeros_like(terminated), torch.tensor([False, True, False])),
(terminated.long(), boundary.long()),
]:
try:
packed_gae(reward, value, next_value, bad_terminated, bad_boundary)
except ValueError:
continue
raise AssertionError("invalid packed boundaries must be rejected")
第二个 transition 模拟 time-limit truncation:它仍用 next_value=4 bootstrap,但 boundary=True 让第一条轨迹在此结束。生产 batch 还要按 trajectory_id 校验顺序,并把基础设施失败从可学习 transition 中剔除;单靠两个布尔量无法表达丢失的 final observation。
Actor target 与 critic target 不能混成一个张量¶
GAE 首先产生 actor 使用的 advantage target:
停止梯度很重要。策略损失不应通过 \(\widehat A_t\) 反向修改 value network,尤其不能让 actor 通过改变 baseline 人为降低自身 loss。若 actor 与 critic 共享 backbone,仍应在 target 边界 detach,再由各自损失对共享参数产生明确梯度。
critic 常用的回归 target 为
并优化
这里加回的是生成 target 时冻结的 value snapshot,而不是 optimizer 已更新后的当前 \(V_\phi\)。若同一批 rollout 做多个 minibatch epoch,return 与 advantage 通常保持冻结;每个 epoch 重新用变化中的 critic 计算 GAE,会让 actor target 在一批数据内部漂移。
actor 与 critic 还可能使用不同的 mask 和 reduction:
- actor 只在 policy 实际选择的 action 上计算 log-probability loss;
- critic 可以在每个有明确定义 value target 的决策状态上回归;
- observation token 可能用于构造状态,却不一定是动作;
- padding、缺失 reward 与无效轨迹必须同时从分子和分母排除。
Advantage whitening 也不是 GAE 定义的一部分。按整个 batch、每个 prompt group、每条序列或每个任务分别中心化,会改变不同样本的相对权重。分布式训练若只在单个 rank 上计算均值与方差,还会让同一 global batch 因切分方式不同而得到不同更新。
三条时间轴:token、turn 与 segment¶
语言模型作为策略指出,同一段文本可以同时包含 prompt、模型动作、工具 observation 与环境状态。GAE 必须先选择决策时间轴,再谈递推。
Token 时间轴¶
把每个生成 token 视作动作时,
value head 需要解释为“给定当前 prefix,继续按策略生成的期望未来回报”。若只有 response 末尾的 outcome reward,中间 token 的 TD residual 主要来自相邻 value 差;这给出细粒度信用,却要求 token-level value 真正校准。
prompt、system token、tool 返回和复制进上下文的 observation 通常不属于 policy action。实现至少要分开:
action mask: 哪些位置进入 actor loss
trace mask: 哪些 transition 沿同一决策链传播 GAE
bootstrap mask: 哪些后继状态仍有未来价值
valid mask: 哪些位置进入统计分母
只用一个 attention mask 代替这四种语义,通常会把“模型能够读取”误写成“模型选择了这个动作”。
Turn 时间轴¶
在工具 Agent 中,更自然的一步可能是一次 assistant message、一次 tool call 或一个 action span。环境返回 observation 后才进入下一决策状态:
state h_t
-> assistant action a_t
-> environment / tool transition
-> reward r_t and next state h_{t+1}
此时 \(\gamma\) 描述的是跨 turn 的延迟,而不是跨 token 的距离。一个很长的 JSON tool call 是否比一个短调用多折扣数百次,应由任务语义决定,不能由 tokenizer 偶然决定。turn-level critic 可以显著缩短 GAE 序列,但会失去 action span 内部的信用分辨率。
Segment 时间轴¶
长程 Agent 可能把一次 episode 切成多个训练 segment,或在上下文接近上限时生成摘要再继续。segment boundary 只是存储或表示边界,不应自动成为环境 terminal。
如果后一段仍属于同一 episode,就需要保存:
- segment 的全局顺序与原始 episode ID;
- 前段末状态和后段初状态的对应关系;
- 摘要是策略动作、外部变换还是只读 observation;
- 后续 value 能否在压缩后的信息状态上可靠 bootstrap;
- GAE carry 是否跨 segment,以及跨越时按哪种时间距离衰减。
跨 segment 递推并不自动正确。若压缩丢失了影响未来 reward 的信息,critic 实际在一个近似 belief state 上预测;延长 trace 只能传播 estimator,不能恢复已经丢失的状态信息。长轨迹中的 action、observation 与层级信用边界见语言模型信用分配和轨迹与策略契约。
一个两步手算¶
设 \(\gamma=0.9,\lambda=0.95\)。第一步是普通 transition:
第二步因时间预算而 truncation,但真实 final observation 的 value 为 \(0.8\):
truncation 允许当前 TD target bootstrap,却必须在这里截断 trace,因此
第一步的 residual 与 advantage 为
如果第二步是真正 terminal,同样的即时 reward 会得到 \(\delta_1=1-0.6=0.4\);差异来自是否存在可继续估值的环境状态,而不是数组是否在这里结束。可执行 packed-tensor 版本及退化断言集中在手撕 LLM 策略优化。
偏差、方差与失败边界¶
\(\lambda\) 增大通常减少对局部 critic 的依赖,也让更远 reward 噪声进入当前 advantage。这个经验方向不等于固定排序:
- critic 在某类状态上系统性偏高时,较短 trace 会继承局部 bias;
- episode 很长、reward 极稀疏时,较长 trace 的 variance 和数值范围可能迅速增加;
- policy lag 使 residual 对应的 value、reward 与当前策略不一致,调小 \(\lambda\) 不能替代 Off-policy 校正;
- value pretraining、actor/critic 更新频率和 target normalization 都会改变同一 \(\lambda\) 的表现;
- response 长度、turn 数与 segment 数不同,固定 \(\gamma\lambda\) 会给不同任务不同的有效信用半衰期。
诊断时不应只看 advantage 的全局均值和方差。至少按 trajectory length、reward 类型、terminal/truncated、任务类别与 policy version 分层,并检查:
- \(\lambda=0\) 时 advantage 是否精确等于 TD residual;
- 真正 terminal 是否关闭 bootstrap;
- truncation 是否使用真实 final observation 的 value;
- carry 是否在每条 episode 或存储边界正确重置;
- actor mask 改动 prompt、observation 与 padding 后,policy loss 是否保持不变;
- critic target 是否由冻结 snapshot 构造;
- advantage whitening 的统计范围是否跨全部参与 rank 一致;
- token、turn、segment 三种长度变化时,优势尺度与有效样本权重怎样变化。
GAE 最值得保留的不是一条反向循环,而是一组明确的接口:reward 属于哪一步、value 预测哪个策略的未来、什么会终止任务、什么只会截断存储、actor 对哪些动作负责。接口没有固定时,两个都叫“GAE”的实现可能在优化不同对象。
Reference¶
- Schulman et al., High-Dimensional Continuous Control Using Generalized Advantage Estimation
- Sutton and Barto, Reinforcement Learning: An Introduction, Second Edition
- Pardo et al., Time Limits in Reinforcement Learning
- Schulman et al., Proximal Policy Optimization Algorithms