Skip to main content الرئيسية المنشئون adu2021 skillxiv slow-fast-policy-optimization-rl
slow-fast-policy-optimization-rl Stabilize RL for LLM reasoning via three-phase decomposition: fast inner trajectory optimization, repositioning to manage off-policy drift, slow correction for stable updates. Achieve up to 2.80-point math reasoning gains over GRPO while reducing rollouts 4.93x and wall-clock time 4.19x via improved stability without changing reward structure.
الانتقال إلى التثبيت سوق المهارات اكتشف واستكشف مهارات الذكاء الاصطناعي التي بناها المجتمع.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
نسخ Promptعرض تفاصيل Prompt يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/ADu2021/skillXiv --skill slow-fast-policy-optimization-rlيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
تحميل Zip جاري التحميل... المهن ذات الصلة SOC
استنادا إلى تصنيف SOC المهني
name slow-fast-policy-optimization-rl title Slow-Fast Policy Optimization: Reposition-Before-Update for LLM Reasoning version 0.0.2 engine skillxiv-v0.0.2-claude-opus-4.6 license MIT url https://arxiv.org/abs/2510.04072 keywords ["policy optimization","RL stability","gradient control","off-policy divergence","reasoning models"] description Stabilize RL for LLM reasoning via three-phase decomposition: fast inner trajectory optimization, repositioning to manage off-policy drift, slow correction for stable updates. Achieve up to 2.80-point math reasoning gains over GRPO while reducing rollouts 4.93x and wall-clock time 4.19x via improved stability without changing reward structure.
Slow-Fast Policy Optimization: Reposition-Before-Update
Core Concept
On-policy RL for LLMs suffers gradient instability from noisy early-training rollouts. Slow-Fast Policy Optimization (SFPO) decomposes each training step into three phases: fast optimization on the current batch, repositioning to constrain off-policy divergence, and slow correction for stable updates. This decomposition is plug-compatible with existing pipelines while dramatically improving stability and efficiency.
Architecture Overview
Three-Phase Framework : (1) Fast trajectory optimization on same batch; (2) Reposition to manage divergence; (3) Slow correction phase
Off-Policy Divergence Control : Track KL divergence during each phase to prevent catastrophic divergence
Plug-Compatible Design : Works with existing policy gradient implementations (GRPO, PPO) without modification
Efficiency Gains : 4.93× rollout reduction, 4.19× wall-clock speedup while improving performance
Implementation Steps
1. Three-Phase Decomposition Framework
Structure each training iteration into coordinated phases.
class SlowFastPolicyOptimizer :
def __init__ (self, policy_model, learning_rate=1e-6 , max_kl=0.1 ):
self .policy = policy_model
self .optimizer = torch.optim.AdamW(self .policy.parameters(), lr=learning_rate)
self .max_kl = max_kl
def train_step_sfpo (self, batch, initial_policy_state=None ):
"""
Single SFPO training step with three phases.
Args:
batch: (observations, actions, rewards, values) from single rollout
initial_policy_state: Reference policy for KL computation
"""
if initial_policy_state is None :
initial_policy_state = {
name: param.detach().clone()
name, param .policy.named_parameters()
}
( )
fast_loss = ._phase1_fast_optimization(batch)
( )
repositioned_state = ._phase2_repositioning(initial_policy_state)
( )
final_loss = ._phase3_slow_correction(batch, repositioned_state)
{
: fast_loss,
: final_loss,
: ._compute_kl_divergence(initial_policy_state)
}
( ):
obs, actions, rewards, values = batch
advantages = rewards - values
advantages = (advantages - advantages.mean()) / (advantages.std() + )
inner_losses = []
_ ( ):
action_logits = .policy(obs)
log_probs = torch.log_softmax(action_logits, dim=- )
selected_log_probs = log_probs[ ( (actions)), actions]
ratio = torch.exp(selected_log_probs - selected_log_probs.detach())
clipped_ratio = torch.clamp(ratio, , )
loss = -torch. (ratio, clipped_ratio) * advantages
.optimizer.zero_grad()
loss.mean().backward()
torch.nn.utils.clip_grad_norm_( .policy.parameters(), )
.optimizer.step()
inner_losses.append(loss.mean().item())
(inner_losses) / (inner_losses)
( ):
current_kl = ._compute_kl_divergence(initial_state)
current_kl > .max_kl:
( )
( )
excess_divergence = ( , current_kl - .max_kl)
alpha = excess_divergence / (current_kl + )
(name, param), (init_name, init_param) (
.policy.named_parameters(),
initial_state.items()
):
name == init_name:
param.data = ( - alpha) * param.data + alpha * init_param
{
: current_kl,
: current_kl > .max_kl
}
( ):
obs, actions, rewards, values = batch
advantages = rewards - values
advantages = (advantages - advantages.mean()) / (advantages.std() + )
action_logits = .policy(obs)
log_probs = torch.log_softmax(action_logits, dim=- )
selected_log_probs = log_probs[ ( (actions)), actions]
ratio = torch.exp(selected_log_probs - selected_log_probs.detach())
clipped_ratio = torch.clamp(ratio, , )
loss = -torch. (ratio, clipped_ratio) * advantages
.optimizer.param_groups[ ][ ] =
.optimizer.zero_grad()
loss.mean().backward()
torch.nn.utils.clip_grad_norm_( .policy.parameters(), )
.optimizer.step()
.optimizer.param_groups[ ][ ] =
loss.mean().item()
( ):
total_kl =
(name, param), (ref_name, ref_param) (
.policy.named_parameters(),
reference_state.items()
):
name == ref_name:
kl = torch.norm(param.data - ref_param) / (torch.norm(ref_param) + )
total_kl += kl.item()
total_kl / (reference_state)
for
in
self
print
"Phase 1: Fast inner trajectory optimization"
self
print
"Phase 2: Repositioning mechanism"
self
print
"Phase 3: Slow correction for stability"
self
return
'phase1_loss'
'phase3_loss'
'total_divergence'
self
def
_phase1_fast_optimization
self, batch
"""
Fast inner optimization: take multiple gradient steps on same batch.
"""
1e-8
for
in
range
5
self
1
range
len
0.9
1.1
min
self
self
1.0
self
return
sum
len
def
_phase2_repositioning
self, initial_state
"""
Repositioning: Adjust policy to constrain KL divergence from initial state.
Prevents divergence from accumulating across training steps.
"""
self
if
self
print
f"KL divergence {current_kl:.4 f} exceeds threshold {self.max_kl:.4 f} "
print
"Applying repositioning correction..."
max
0
self
1e-8
for
in
zip
self
if
1
return
'kl_divergence'
'repositioned'
self
def
_phase3_slow_correction
self, batch, repositioned_state
"""
Slow correction: Final update step with reduced learning rate.
Ensures stability after repositioning.
"""
1e-8
self
1
range
len
0.95
1.05
min
self
0
'lr'
1e-7
self
self
0.1
self
self
0
'lr'
1e-6
return
def
_compute_kl_divergence
self, reference_state
"""
Compute KL divergence from reference policy parameters.
Simplified: L2 distance in parameter space (proxy for KL).
"""
0
for
in
zip
self
if
1e-8
return
len
2. Integration with GRPO Pipeline SFPO is plug-compatible; use as drop-in replacement for standard gradient steps.
def grpo_training_with_sfpo (
policy, base_model, train_loader, num_epochs=5 , group_size=8
):
"""
Standard GRPO training loop but with SFPO decomposition.
"""
optimizer = SlowFastPolicyOptimizer(policy, learning_rate=1e-6 )
for epoch in range (num_epochs):
total_loss = 0
num_batches = 0
for batch_idx, batch in enumerate (train_loader):
obs, actions, rewards = batch
with torch.no_grad():
values = base_model.estimate_value(obs)
group_rewards = []
for i in range (0 , len (rewards), group_size):
group = rewards[i:i+group_size]
group_mean = group.mean()
group_std = group.std() + 1e-8
normalized = (group - group_mean) / group_std
group_rewards.extend(normalized)
group_rewards = torch.tensor(group_rewards)
batch_data = (obs, actions, group_rewards, values)
sfpo_result = optimizer.train_step_sfpo(batch_data)
total_loss += sfpo_result['phase3_loss' ]
num_batches += 1
if (batch_idx + 1 ) % 10 == 0 :
avg_loss = total_loss / num_batches
print (f"Epoch {epoch} , Batch {batch_idx+1 } : Loss={avg_loss:.4 f} " )
return policy
3. Hyperparameter Configuration SFPO requires minimal tuning; primary hyperparameter is KL threshold.
sfpo_config = {
'learning_rate' : 1e-6 ,
'inner_loop_steps' : 5 ,
'max_kl_divergence' : 0.1 ,
'phase3_learning_rate' : 1e-7 ,
'phase1_clipping' : (0.9 , 1.1 ),
'phase3_clipping' : (0.95 , 1.05 ),
'grad_clip_norm' : 1.0
}
sfpo_math_config = {
'inner_loop_steps' : 3 ,
'max_kl' : 0.05 ,
'batch_size' : 32 ,
'num_epochs' : 3
}
Performance Results Evaluation on mathematical reasoning benchmarks:
results = {
'grpo_baseline' : {
'accuracy' : 'Base' ,
'rollouts_per_iter' : 32 ,
'wall_clock' : '100% (baseline)'
},
'sfpo' : {
'accuracy_improvement' : '+2.8 points (on AIME subset)' ,
'rollouts_per_iter' : 32 ,
'actual_rollouts_used' : '6.5 (4.93x reduction)' ,
'wall_clock' : '23.8% of baseline (4.19x speedup)' ,
'mechanism' : 'Better reuse of low-quality initial rollouts via repositioning'
}
}
Practical Guidance Phase Balancing : Adjust inner loop steps (Phase 1) based on rollout quality. More steps needed if rollouts are noisy.
KL Threshold : 0.05-0.1 works well for most domains. Start conservative; increase if divergence becomes a bottleneck.
Clipping Adjustment : Phase 3 should use tighter clipping (0.95-1.05) to prevent destabilization after repositioning.
Compatibility : SFPO works with any policy gradient objective (GRPO, PPO, REINFORCE). No changes to reward structure needed.
When to Use / When NOT to Use
Training reasoning models where rollout quality is variable
Early training stages with high gradient noise
Compute budget is constrained (4x speedup is significant)
Stability is critical (robotics, safety-sensitive tasks)
Tasks with uniformly high-quality rollouts
Scenarios where convergence speed matters more than stability
Very small batch sizes (<8) where repositioning has minimal effect
Reference This skill synthesizes findings from "Slow-Fast Policy Optimization: Reposition-Before-Update for LLM Reasoning" (arXiv:2510.04072, ICLR 2026). Three-phase decomposition achieves stability without objective modification.