Stale but Stable:当异步强化学习的"老数据"撞上PPO裁剪半径
你有没有过这种体验——训练大模型时,推理引擎吭哧吭哧吐出的一批token,等送到训练侧时policy已经更新了好几轮。等训练器终于开始用这批"老"token做优化,它面对的是"我现在追的策略"和"当时采这个token的策略"之间已经被时间和工程现实撕开的那道缝隙。
这道缝隙有个正式的名字——训练-推理不匹配(training-inference mismatch),也叫staleness。
在异步RL已经成为工业界标配的今天,这件事到底有多严重?来自腾讯混元团队(Tencent Hy LLM Frontier)联合NUS、UMD、UGA、Indiana University的Junyao Yang等九位作者,给出了一个非常具体的回答:当配置的lag从1涨到8,PPO和GRPO的基线会直接训练崩溃(collapse)。他们提出的解决方案是SAT——Staleness-Adaptive Trust Region(陈旧性自适应信任域)。在Qwen3-30B-A3B-Base上,SAT-GSPO w/ R3在lag=1的AIME24 avg@8上跑到35.83,在lag=8上跑到34.79,是所有对比方法里的双榜冠军。
论文:Stale but Stable: Staleness-Adaptive Trust Regions for Stabilizing Asynchronous Reinforcement Learning(arXiv: 2607.18722)
一、当我们谈异步RL时,到底在谈什么
在动手讲SAT之前,先把"异步RL"这件事拆清楚。同步RL是一板一眼的:rollout出一批数据,等全部采完,训练器做几步优化,权重广播回去,再开始下一轮。问题也很明显——GPU有30-50%的时间在等。要么训练器等rollout采完,要么rollout等训练器更新完权重。
异步RL把这个硬同步打掉了:rollout引擎(SGLang)在一个GPU池上连续采,训练引擎(Megatron)在另一个GPU池上连续训,两者解耦,靠定期权重广播(weight broadcast)保持联系。这就是论文里反复出现的batch-wise asynchronous pipeline:

图1:SGLang rollout和Megatron训练分属两个GPU池,权重每8个optimizer step广播一次。Rollout batch 1采样用的是θ₀,batch 2也是θ₀,batch 3是θ₈,batch 4是θ₁₆——一个飞行中的batch被训练时,参数往往已经更新过若干次。论文里的"lag"就是两次权重广播之间的optimizer step数(这里是8)。
但天下没有免费的午餐。同步变异步的代价是训推不匹配——训练器优化时用的target policy \(\pi^{(j)}\),和实际采到这些token的behavior policy \(\mu_{b,t}\),已经不是同一个东西了。论文把这个失配量定义为token级log-ratio:
这玩意儿还分两段:\(d_{b,t} = \Delta^{\pi}_{b,t} + \Delta^{\mathrm{impl}}_{b,t}\)。前者是优化器走了n步累积下来的策略漂移,后者是训推引擎差异(kernel不一样、低精度数值差异、MoE路由不一致)引入的实现失配。前者随lag增长是显然的,后者即使权重完全一样也非零——这是工业级部署躲不掉的现实。
二、当lag从1涨到8,到底发生了什么
论文的Section 2.1给了一组非常干净的对比实验:除了lag不同,其他完全一致(同样的模型Qwen3-30B-A3B-Base,同样的数据,同样的奖励,同样的超参),只把"权重广播间隔"从1次优化器步拉长到8次。结果是两组很硬的现象:


图2:在GRPO下,lag=1(蓝)时\(|\log\pi_{\text{train}} - \log\pi_{\text{rollout}}|\)基本稳定在0.012附近,KL也稳定在0.0007上下;lag=8(红)则不然——logprob差在前期就冲到0.035,之后在0.011-0.021之间反复震荡;KL幅度也出现"training instability"的尖刺,峰值超过0.0028。这是分布的尾部在变重,不是中心在偏移。
紧接着是更狠的——评估分直接崩:

图3:GSPO在lag=1下整个训练都稳定在0.30附近;lag=8的曲线一路爬到0.34(比lag=1还高),然后在约step 449直接砸到0.14——典型的late-stage collapse。注意collapse的时点恰好对应KL信号开始发散的阶段。
这两个症状不是GRPO独有的——Table 1里能清楚看到GSPO lag=8也在step 424 collapse了。在高staleness场景下,固定裁剪半径的异步RL就是不稳定的,而且collapse的时点和失配开始发散的时点高度相关。这给了我们一个非常清晰的工程直觉:要把异步RL训稳,关键不在数据、奖励或优化器,而在控制失配。
三、问题的根源:PPO clip到底在做什么
要理解SAT为什么能work,得先想清楚PPO clip到底在做什么。论文给出了一个在我看来非常精准的视角:PPO clip从来不是"信任域"(trust region),它是一个采样层面的代理。
回到经典的policy improvement bound。对于有限horizon生成任务,有
也就是说,policy改的每一小步,对应的近似误差惩罚是一个累积的token级total variation散度。结合Lemma 1.1里的恒等式
可以看出:如果对状态s下所有action都有一个硬ratio上界\(|r_s(a)-1|\le\varepsilon\),那\(D_{\mathrm{TV}}\)就被控制住了——这是真正的"信任域"含义。
但PPO clip做的事情根本不是这个。PPO只对实际采到的那一个action做clip:
它从不检查其他token的\(r_s(a)\)是多少,只是把采到的那一个的梯度在边界外砍掉。所以PPO clip只是命题1.2("理想全动作ratio上界")的sampled surrogate——一个采样层面的代理,名字里带"trust region"但和真正的信任域不是一回事。
问题来了:在异步RL里,PPO clip的固定半径\(\varepsilon\)默认"所有token一样可靠"。但失配\(d_{b,t}\)是重尾异质的——大多数token还在policy 1附近,一小撮token被policy lag和工程实现差异推到很远。固定的\(\varepsilon\)陷入两难:调小了绝大多数普通token的学习被压制,调大了那些高staleness的尾部token得到和正常token一样的"外出更新"(outward update)许可。
这恰好是异步RL的失稳机制——尾部那一点点"远"token被无差别地放行了,policy在那个方向上走得太远,积累下去就崩了。
四、SAT的解法:让裁剪半径自己看失配
SAT的核心idea一句话讲完:用采到的log-ratio作为staleness proxy,让clip半径只对每个batch里失配最重的尾部token收缩,其他token保持PPO原行为。
它分三步走,论文里写得非常干净。
第一步:detached log-ratio作为失配代理。直接用现成的\(d^{\mathrm{sg}}_{b,t} = \mathrm{sg}[\log r_{b,t}]\)——注意是stop-gradient的,只用来决定半径,本身不参与优化。
第二步:自校准的分位数阈值。和设一个全局阈值(比如\(|d|>0.02\))不同,SAT用当前batch的失配分布自己校准:算出经验CDF \(\hat F_{|d|}(x)\),取90%分位数\(q = \mathrm{sg}[\inf\{x: \hat F_{|d|}(x)\ge 0.9\}]\)。这意味着batch里失配最大的那10%是"高失配尾部"。这个分位数随batch动态调整,不需要手调绝对阈值。
第三步:hill kernel缩放 + 符号选择endpoint收缩。对每个token,按\(d\)的符号分成两条路("上"和"下"),分别用kernel函数缩放:
然后收缩因子:
于是自适应半径:
关键点:当\(d_{b,t}>0\)(target已经超过behavior)时只收缩上端,当\(d_{b,t}<0\)时只收缩下端。也就是说,只有那个把\(r\)推得更远离1的方向会被收紧,pull-back方向(让\(r\)往1靠拢的方向)保留原样。这个"方向选择"是结构性设计——避免把已经在"回头"的更新也误伤。
最后把它塞回PPO的min-clip公式:
值得注意的是,SAT不是新目标——它就是把PPO的clip上限/下限换成自适应版本,加上一行quantile和几行elementwise tensor。\(c_{\pm,b,t}=1\)的token完全回到PPO原行为。GSPO版本用序列级ratio \(\rho^{\mathrm{seq}}_b = \exp(\frac{1}{T_b}\sum_t \log r^{\mathrm{tok}}_{b,t})\)代替单token ratio,其余流程一样。
五、SAT在数学上到底改了什么
论文给了一个很有意思的Proposition 1.3,把SAT相对PPO的"局部几何"刻画得清清楚楚:
- (i) 包含性:\(\mathcal I^{\mathrm{SAT}}_{b,t} \subseteq \mathcal I^{\mathrm{PPO}}\)。SAT的clip区间永远在PPO内部,最多多端点重合,最少一端点严格内移。这保证了"启用SAT不会放大更新,只会收紧"。
- (ii) 逐点悲观:\(\mathcal S^{\mathrm{SAT}}(r,\hat A) \le \mathcal S^{\mathrm{PPO}}(r,\hat A)\)。在同一个ratio \(r\)和advantage \(\hat A\)下,SAT的surrogate不会比PPO更乐观。
- (iii) 改动区域精确刻画:两个目标的导数之差只出现在两个"新被裁剪的外出带"上——
也就是SAT只把这一个signature外出带上的gradient置零,PPO原本是放行的;其他所有位置两个目标完全一致。Pull-back分支(让\(r\)往1靠拢的更新)保留原样,已经被PPO裁掉的\(r\)在两个目标下导数都是0。
这个证明很巧妙,但更重要的是它的工程含义:SAT的"开销"在梯度层面是局部的、可解释的、可证伪的。它不重塑policy分布本身,只重塑sampled surrogate的局部梯度流。
六、实验:SAT真的能压住高staleness
6.1 主实验结果
论文用的全套配置非常工业级:slime异步框架 + SGLang推理 + Megatron训练,模型是Qwen3-30B-A3B-Base(一个MoE,故意选MoE就是为了让\(\Delta^{\mathrm{impl}}\)中的路由失配也起作用)。训练数据是DAPO-Math-17k + Dolci-RL-Zero-Math-7B共30,712个prompt,每iter 256 prompt × 16 sample = 4,096个response,跑544 iter,temperature=0.95,top-p=1.0,top-k=-1(特意关掉nucleus截断,因为Lemma 1.1的全vocab支持假设需要它),32k token response上限,clip半径0.2,学习率\(10^{-6}\)。SAT的quantile阈值\(\alpha=0.90\),kernel用\(\psi(u;q) = 1/(1+(u/q)^2)\)。
主表(Table 1)给出了所有配置在AIME24 avg@8上的结果,我把它拆成两部分来看:
基线vs SAT(lag=1 vs lag=8)
| 方法 | AIME24 lag=1 ↑ | AIME24 lag=8 ↑ | 失配量 lag=1 ↓ | 失配量 lag=8 ↓ |
|---|---|---|---|---|
| GRPO | 31.25 | 30.17 ⚠️ 429 步collapse | 0.0103 | 0.0110 |
| GSPO | 32.25 | 31.46 ⚠️ 424 步collapse | 0.0097 | 0.0109 |
| GRPO w/ R3 | 31.83 | 29.58 | 0.0058 | 0.0218 |
| GSPO w/ R3 | 34.00 | 33.13 | 0.0091 | 0.0158 |
| GRPO w/ TIS w/ R3 | 31.79 | 31.79 | 0.0048 | 0.0081 |
| GSPO w/ TIS w/ R3 | 31.88 | 32.92 | 0.0054 | 0.0068 |
| DPPO | 33.96 | 32.71 | 0.0108 | 0.0118 |
| SAT-GRPO | 32.71 | 32.08 | 0.0101 | 0.0108 |
| SAT-GSPO | 34.17 | 32.71 | 0.0095 | 0.0107 |
| SAT-GRPO w/ R3 | 33.75 | 33.13 | 0.0056 | 0.0079 |
| SAT-GSPO w/ R3 | 35.83 | 34.79 | 0.0056 | 0.0076 |
几个关键观察:
- SAT-GSPO w/ R3在两个lag上都是第一,且collapse-free——lag=1上35.83,lag=8上34.79。相比GRPO/GSPO裸跑,gain分别是4.58/4.62 和 3.58/3.33;相比DPPO还有1.87/2.08的优势。
- GRPO和GSPO的裸跑确实在高staleness下崩了(429和424步),印证了Section 2.1的诊断。
- R3(路由replay)的作用是把失配量整体压低——所有带R3的变体失配量都明显更小,\(\dpi\)普遍在0.005-0.008区间,没R3的变体都在0.010+。这是个"水平调节器"。
- SAT的作用不是降低失配水平,而是压住失配尾部——SAT-GRPO和GRPO的\(\dpi\)几乎一样(0.0101 vs 0.0103),但SAT-GRPO避免了collapse。配合R3之后,\(\dpi\)进一步压低(0.0056),效果叠加。
6.2 失配演化轨迹


图4:横轴是训练步,纵轴是\(|\log\pi_{\text{train}} - \log\pi_{\text{rollout}}|\)。在lag=1(左)下,所有方法在前40步就稳态化,R3相关方法(包括SAT-GRPO w/ R3、SAT-GSPO w/ R3)持续稳定在0.005-0.007,没有R3的稳定在0.010-0.012。在lag=8(右)下,故事不一样了——GSPO在约step 350后开始剧烈发散,标注直接写"training collapse after about step 350",一路飙到0.036。R3相关变体保持低失配稳定,SAT相关变体(即使没R3)也守住了失配水平。
这两张图把"SAT解决什么、R3解决什么"分得很清楚: - R3把失配曲线的水平压低——一旦把MoE路由replay进去,训推log-prob的差立刻就降一档; - SAT不是用来压低失配曲线的,而是用来拦截尾部的——所有变体里SAT和baseline在平均水平上几乎重合,但没有SAT的基线在lag=8的GSPO上直接崩了。
这两个机制是互补的。Table 1的列也印证了:R3单独用可以压失配但AIME分不一定最好(GRPO w/ R3 lag=8只有29.58),SAT和R3叠在一起才同时有"低失配+高分+不崩"。
6.3 SAT在非对称裁剪家族中的位置
为了和PPO的固定半径、DPPO的\(D_{\mathrm{TV}}\)加权边界做横向比较,论文把非对称裁剪统一写成"门控掩码"。PPO的掩码是
DPPO把判别式从\(|r_t-1|\)换成\(D^{\mathrm{TV}}_t = \mu(a|s)|r_t-1|\),等价于\(|r_t-1|\le \delta/\mu(a|s)\),所以对head token更紧、对长尾rare token更松。SAT则按当前batch的失配尾部来选boundary。
论文附了一张AIME24 avg@8的bar图(Figure 5,用tikz画的没单独导出,描述如下):GRPO lag=1 31.25/lag=8 30.17,GSPO 32.25/31.46,DPPO 33.96/32.71,SAT-GSPO 34.17/32.71,SAT-GSPO w/ R3 35.83/34.79。DPPO已经比vanilla GRPO/GSPO好很多了(避开collapse),但还是比SAT-GSPO w/ R3差——非对称性本身不稀缺,稀缺的是"用对了非对称的边界"。
七、我的判断:它work,但别把它神化
读到Table 1最后一行的时候,我是有点兴奋的——35.83和34.79的AIME24 avg@8确实是强数。但兴奋过后我得退一步,这篇论文到底给我们留下了什么。
第一,SAT是个"对称裁剪半径"的微创新,不是目标层面的发明。从Proposition 1.3可以看出,SAT只动"一个新裁剪的外出带"上的gradient,它不重新设计目标,不改ratio统计量,不动advantage估计。换句话说,SAT对其他RL变体(GRPO、GSPO、Dr.GRPO、REINFORCE++等)都是即插即用的——加一个quantile和几行tensor而已。从工程实用度看,这是它最值钱的地方。
第二,"对头收紧、对尾放松"的非对称思想其实不算新鲜。DPPO在做类似的事情,但DPPO的边界由\(D_{\mathrm{TV}}\)和\(\mu(a|s)\)反推,给rare token更宽松的更新——直觉上反直觉,因为rare token的ratio也常常更大,宽松更新可能反而把分布推到更远。SAT的逻辑不一样:它对失配最严重的尾部token收紧,对正常token保持PPO原样。这其实更符合"信任域"的本意。
第三,R3和SAT是互补而不是冗余。R3靠路由replay压低训推实现差异\(\Delta^{\mathrm{impl}}\)(特别是MoE的路由不一致),SAT靠自适应的clip半径控制梯度流出。Table 1里\(\dpi\)列的对比非常说明问题:GRPO w/ R3 lag=8的\(\dpi\)是0.0218(反直觉地比GRPO lag=8的0.0110高——加了R3之后AIME分也变差,可能因为R3牺牲了部分exploration),而SAT-GRPO w/ R3 lag=8的\(\dpi\)是0.0079,AIME 33.13。这说明单独用R3不一定更稳,单独用SAT也不一定压失配——两者需要组合。
第四,关于理论保证。Proposition 1.3的三个性质(包含、悲观、改动区域精确刻画)都是单batch surrogate层面的,不是训练动力学层面的。论文自己也明说:参数是跨token共享的,一个token的外出gradient被SAT砍掉后,下一步可能因为其他token的gradient更新而被拉过去。所以SAT对训练的最终policy轨迹只能给出"局部约束",不能直接推出policy改善的全局下界。这和TRPO那种"硬信任域带KL bound"的风格不一样——作者没夸大。
第五,实验设置的"甜区"。论文选的是Qwen3-30B-A3B-Base这个MoE、配置是slime + SGLang + Megatron、temperature 0.95 top-p 1.0(特意关nucleus),这都是有讲究的——Lemma 1.1的全vocab支持假设需要它。换到其他场景(比如top-p=0.9的agentic RL、或者很小的dense模型)SAT是不是还work,论文里没验证,作者在Limitations也明说了。
八、和同期工作的位置
2026年异步RL稳定性这个问题,有几篇同期工作都在做:
- SAO(清华 / Z.AI, arXiv: 2607.07508)走的是single-rollout + 双面clip + value model设计的路线,核心是"group barrier在异步下结构不匹配",所以去掉group换成single-rollout。它解决的是"为什么要异步采"的问题。
- GAC(arXiv: 2603.01501)走的是gradient alignment control路线,通过控制相邻梯度的cosine相似度来稳定训练——它观察到同步RL的梯度是低cosine(多样方向),异步RL的梯度是高cosine(反复同向),这种alignment是崩溃的根因。它解决的是"训练动力学层面"的问题。
- SAT(本文)走的是trust region视角的sampled surrogate调整,通过clip半径自适应给尾部token一个收敛外边界。它解决的是"梯度流层面"的问题。
三条路各打各的靶子,理论上不互斥——GAC管梯度方向,SAO管数据流,SAT管gradient magnitude的限制。在工业级部署上,GAC + SAT很可能可以组合(一个管方向、一个管幅度上限),这种"机制互补"的组合在工程上往往比单一技巧更鲁棒。
九、给做工程的人:什么时候该试SAT
读完之后我的实操建议是这样的:
- 如果你已经在用PPO/GRPO/GSPO做异步RL,SAT几乎是零成本集成——加一个quantile算子、几行kernel缩放和clip半径替换。值得作为默认clip机制,特别是在MoE模型上。
- 如果你的失配量\(\dpi\)水平整体偏高(比如>0.015),先检查是不是路由replay/引擎一致性没做好(\(\Delta^{\mathrm{impl}}\)太大),R3类的方案可能比SAT更治本。
- 如果你的训练已经在"训到一半突然崩",大概率是tail risk没控住。SAT的"signature外出带"裁剪正是为这个场景设计的——它不动平均水平,只截掉最危险的尾部更新。
- 如果你在做agentic RL(多轮、tool use、top-p截断),SAT的Lemma 1.1假设需要全vocab支持——你得自己改quantile和kernel的设计,或者用SAT的"思想"而不是原方案。论文Limitations也明确说sequence-level SAT在token log-ratio cancel问题上要单独处理。
十、最后
SAT这个名字起得挺巧——Staleness-Adaptive Trust Region。Stale but Stable的slogan和论文标题呼应得也漂亮:异步RL"老数据"这件事不可怕,可怕的是用固定半径去应对异质失配。
它不是"第一个发现异步RL在高staleness下会崩"的论文(这事工业界早知道了),也不是"第一个用自适应clip"的论文(之前DAPO、Dr.GRPO都在clip上动过心思)。它的贡献在于把"自适应clip"这件事严谨地嵌进了PPO的trust region几何里——Proposition 1.3的三条性质告诉你"它和PPO相比到底改了什么、改在哪里、为什么不会更差"。这种"surrogate层面的可证设计"在RL领域其实不常见,大多数自适应方法都靠实验说话。
35.83 vs 31.25,4.58个点的gain不算多,但在lag=8的GSPO已经崩了的对照下,能稳到34.79不崩——这才是工程上真正值钱的特性。
觉得有启发的话,欢迎点赞、在看、转发。跟进最新AI前沿,关注我。