Build reasoning capabilities through pure RL without distilled traces, achieving 50% AIME accuracy improvement via scalable asynchronous training with novel reward shaping for multilingual consistency.
Scanned 9/9/2026
Install to Claude Code
npx -y skills add ADu2021/skillXiv --skill magistral-reasoning-rl --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Magistral Reasoning Rl?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/adu2021-magistral-reasoning-rl)More formats (shields.io, HTML) on the badges page.
---
name: magistral-reasoning-rl
title: "Magistral: Scaling Reasoning with Reinforcement Learning"
version: 0.0.2
engine: skillxiv-v0.0.2-claude-opus-4.6
license: MIT
url: "https://arxiv.org/abs/2506.10910"
keywords: [reasoning models, reinforcement learning, GRPO, chain-of-thought, multimodal reasoning]
description: "Build reasoning capabilities through pure RL without distilled traces, achieving 50% AIME accuracy improvement via scalable asynchronous training with novel reward shaping for multilingual consistency."
---
# Magistral: Scaling Reasoning with Reinforcement Learning
## Core Concept
Magistral demonstrates that pure reinforcement learning (without cold-start distilled reasoning traces) achieves strong reasoning through carefully designed rewards and scalable infrastructure. The system improves AIME-24 pass@1 accuracy by nearly 50% using a modified GRPO algorithm, asynchronous weight updates, and multi-stage curriculum learning. Novel insights: RL improves smaller models beyond distillation baselines and unexpectedly enhances multimodal capabilities despite text-only training.
## Architecture Overview
- **Modified GRPO Algorithm**: Five adaptations including eliminated KL divergence penalty, loss normalization across generation groups, advantage normalization, relaxed clipping (Clip-Higher), and zero-variance filtering
- **Four-Component Reward Architecture**: Formatting (think tags), correctness (verified answers/test passing), length penalty (soft constraints), language consistency (multilingual response matching)
- **Asynchronous Infrastructure**: Continuous weight updates without interrupting generators; NCCL broadcast under 5 seconds; GPU-to-GPU communication minimized
- **Multi-Stage Curriculum**: Difficulty progression across stages; batch size reduction (8k→4k→2k); completion length increases (16k→24k→32k tokens)
- **Data Curation Pipeline**: Mathematical problems filtered from 699k to 38k; code problems validated at 35k with comprehensive test suites
## Implementation
### Step 1: Modified GRPO Optimizer Setup
```python
import torch
import torch.nn as nn
from torch.optim import Optimizer
class ModifiedGRPO(Optimizer):
"""
Group Relative Policy Optimization with Magistral adaptations:
- Eliminated KL divergence penalty
- Loss normalization across generation groups
- Advantage normalization at minibatch level
- Relaxed upper clipping (Clip-Higher strategy)
- Zero-variance group filtering
"""
def __init__(self, params, lr=1e-5, epsilon=1e-6,
clip_ratio=2.0, clip_lower=0.5):
defaults = dict(lr=lr, epsilon=epsilon,
clip_ratio=clip_ratio, clip_lower=clip_lower)
super().__init__(params, defaults)
def step(self, closure=None):
loss = None
if closure is not None:
loss = closure()
for group in self.param_groups:
for p in group['params']:
if p.grad is None:
continue
grad = p.grad.data
# Clip-Higher strategy: relaxed upper bound
# clip_ratio acts as soft upper bound, not hard limit
if group['clip_ratio'] is not None:
# Allow exploration beyond standard PPO bounds
grad_magnitude = torch.norm(grad)
if grad_magnitude > group['clip_ratio']:
grad = grad / (grad_magnitude / group['clip_ratio'])
p.data.add_(grad, alpha=-group['lr'])
return loss
```
### Step 2: Reward Shaping Architecture
```python
class RewardShaper:
"""
Four-component reward function for reasoning tasks.
Combines formatting, correctness, length penalty, and language consistency.
"""
def __init__(self, language_code='en', length_target=2000):
self.language_code = language_code
self.length_target = length_target
self.code_executor = CodeExecutor()
self.answer_verifier = AnswerVerifier()
def compute_reward(self, generated_text, reference_answer=None,
user_language='en', is_code=False):
"""
Compute total reward from four components.
Returns scalar reward in [0, 1] range.
"""
rewards = {}
# Component 1: Formatting reward
has_think_tags = '<think>' in generated_text and '</think>' in generated_text
rewards['formatting'] = 0.25 if has_think_tags else 0.0
# Component 2: Correctness reward
if is_code:
passed_tests = self.code_executor.run_tests(generated_text)
rewards['correctness'] = min(passed_tests / 10, 1.0) * 0.50 # Up to 50%
else:
is_correct = self.answer_verifier.verify(generated_text, reference_answer)
rewards['correctness'] = 0.50 if is_correct else 0.0
# Component 3: Length penalty (soft constraint)
response_length = len(generated_text.split())
length_penalty = 1.0 - abs(response_length - self.length_target) / (2 * self.length_target)
length_penalty = max(0, length_penalty)
rewards['length'] = length_penalty * 0.15 # Up to 15%
# Component 4: Language consistency
response_language = self._detect_language(generated_text)
language_bonus = 0.10 if response_language == user_language else 0.0
rewards['language'] = language_bonus
total_reward = sum(rewards.values())
return {
'total': min(total_reward, 1.0),
'breakdown': rewards
}
def _detect_language(self, text):
"""Detect primary language of generated text."""
# Simplified: check for non-ASCII patterns
if any(ord(c) > 127 for c in text):
return 'non-en'
return 'en'
```
### Step 3: Asynchronous Training Infrastructure
```python
class AsynchronousTrainer:
"""
Manages continuous weight updates without interrupting generators.
Key innovation: GPU-to-GPU NCCL broadcast completes in <5 seconds.
"""
def __init__(self, model, reward_shaper, num_generators=8):
self.model = model
self.reward_shaper = reward_shaper
self.num_generators = num_generators
self.model_queue = []
self.latest_weights = None
def async_generation_loop(self, generator_id, input_batch):
"""
Generator continuously produces samples without blocking on updates.
Receives periodic weight synchronization via broadcast.
"""
local_model = copy.deepcopy(self.model)
while True:
# Generate samples with current local weights
with torch.no_grad():
outputs = local_model.generate(
input_batch,
max_length=2048,
temperature=1.0,
do_sample=True,
num_return_sequences=4
)
# Non-blocking weight sync: receive latest model via NCCL
if self.latest_weights is not None:
# GPU-to-GPU broadcast: <5 seconds
local_model.load_state_dict(self.latest_weights, non_blocking=True)
yield outputs
def update_weights(self, loss_tensor):
"""
Optimizer step updates weights and broadcasts to all generators.
Does not block generation pipeline.
"""
self.optimizer.zero_grad()
loss_tensor.backward()
# Apply gradient clipping
torch.nn.utils.clip_grad_norm_(self.model.parameters(), max_norm=1.0)
self.optimizer.step()
# Broadcast updated weights to all generators asynchronously
self.latest_weights = dict(self.model.named_parameters())
```
### Step 4: Multi-Stage Curriculum Learning
```python
class CurriculumScheduler:
"""
Manages difficulty progression and training configuration across stages.
Increases challenge: batch size reduction, completion length increase.
"""
def __init__(self, num_stages=3):
self.num_stages = num_stages
self.current_stage = 0
self.stage_config = [
{'batch_size': 8192, 'max_length': 16000, 'difficulty': 'easy'},
{'batch_size': 4096, 'max_length': 24000, 'difficulty': 'medium'},
{'batch_size': 2048, 'max_length': 32000, 'difficulty': 'hard'}
]
def get_current_config(self):
return self.stage_config[min(self.current_stage, len(self.stage_config) - 1)]
def progress_stage(self, val_accuracy):
"""Advance to next stage based on validation performance."""
if val_accuracy > 0.7 and self.current_stage < self.num_stages - 1:
self.current_stage += 1
print(f"Curriculum progression: stage {self.current_stage}")
```
## Practical Guidance
**Data Preparation**:
- Mathematical problems: Collect diverse sources (competition, textbooks); validate with multiple verifiers (SymPy, WolframAlpha)
- Code problems: Use comprehensive test suites (50+ test cases minimum); separate train/test data carefully
- Filtering strategy: Remove ambiguous or duplicate problems; keep diverse difficulty spectrum
**Reward Design Principles**:
- Formatting reward (25%): Enforce think tags for chain-of-thought; strong signal during early training
- Correctness reward (50%): Most important component; use automated verification (answer matching or test execution)
- Length penalty (15%): Soft constraint; encourage natural length without hard cutoffs
- Language consistency (10%): Multilingual support; bonus when response matches user's language
**Scaling Considerations**:
- Batch size correlation: Larger batches enable stable advantage normalization; 8k-16k optimal
- Asynchronous updates: Maximum 10-second intervals between weight syncs; generators may use slightly stale weights
- GPU utilization: 8-16 generator GPUs + 2-4 optimizer GPUs; communication bandwidth saturates around 16 generators
**When to Use Magistral Approach**:
- Building reasoning from scratch without distillation data
- Multilingual reasoning models (language consistency reward handles this)
- Long-context reasoning (curriculum handles up to 32k tokens)
- Smaller models (<25B) where RL outperforms distillation
## Reference
- Group Relative Policy Optimization (GRPO): advantage normalization improves stability in RL for generation
- NCCL all-reduce: collective communication primitive; broadcast is unidirectional variant
- Curriculum learning: gradual difficulty progression prevents early convergence to local optima
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!