Skip to main content Home Creators 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.
Jump to install Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/ADu2021/skillXiv --skill slow-fast-policy-optimization-rlThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository
Related occupations SOC
Based on SOC occupation classification
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.