Co-evolutionary framework where Challenger generates tasks and Solver solves them. Models evolve autonomously from scratch without human annotations. Improves math reasoning +6.49pts and general reasoning +7.54pts.
Scanned 9/9/2026
Install to Claude Code
npx -y skills add ADu2021/skillXiv --skill r-zero-self-evolving-reasoning --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of R Zero Self Evolving Reasoning?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/adu2021-r-zero-self-evolving-reasoning)More formats (shields.io, HTML) on the badges page.
---
name: r-zero-self-evolving-reasoning
title: R-Zero - Self-Evolving Reasoning LLM from Zero Data
version: 0.0.2
engine: skillxiv-v0.0.2-claude-opus-4.6
license: MIT
url: https://arxiv.org/abs/2508.05004
keywords: [self-play, co-evolution, reasoning, data-generation, bootstrapping]
description: "Co-evolutionary framework where Challenger generates tasks and Solver solves them. Models evolve autonomously from scratch without human annotations. Improves math reasoning +6.49pts and general reasoning +7.54pts."
---
# R-Zero: Self-Evolving Reasoning LLM from Zero Data
## Core Concept
R-Zero eliminates dependency on human-curated task datasets through autonomous co-evolution. Two models—a Challenger that generates progressively harder tasks and a Solver that tackles them—interact in a feedback loop that generates training data and improves both models without any initial labeled dataset. This enables models to break through baseline capabilities through self-generated, curriculum-learned tasks.
## Architecture Overview
- **Challenger Model**: Generates tasks at the frontier of Solver capability
- **Solver Model**: Solves Challenger's tasks and learns from outcomes
- **Co-evolutionary Feedback**: Challenger rewarded for hard-but-solvable tasks; Solver for solving harder tasks
- **Curriculum Learning**: Task difficulty naturally increases as Solver improves
- **Data Generation**: Training data emerges from interaction, not annotation
## Implementation Steps
### Step 1: Initialize Challenger and Solver Models
Set up two models with appropriate initializations and objectives.
```python
import torch
from typing import Dict, List, Tuple
class ChallengerModel(torch.nn.Module):
"""
Generates tasks at the frontier of solver capability.
"""
def __init__(self, base_model, task_domain="math"):
super().__init__()
self.base_model = base_model
self.task_domain = task_domain
self.task_buffer = []
self.difficulty_estimate = 0.5 # 0-1 scale
def generate_task(self, difficulty_target: float) -> str:
"""
Generate a task at target difficulty.
Args:
difficulty_target: Target difficulty 0-1 (0=trivial, 1=impossible)
Returns:
Task prompt
"""
prompt = f"""
Generate a {self.task_domain} problem.
Difficulty target: {difficulty_target:.1f}/1.0
- 0.0: Trivial, easily solvable
- 0.5: Medium difficulty, requires some reasoning
- 1.0: Very hard, near impossible
Ensure the problem is clear and has a verifiable solution.
Problem:
"""
task = self.base_model.generate(prompt, max_length=300)
return task
def estimate_task_difficulty(self, task: str, solver_accuracy: float) -> float:
"""
Estimate task difficulty based on solver performance.
Args:
task: Task description
solver_accuracy: Proportion of attempts solver succeeds
Returns:
Estimated difficulty 0-1
"""
# Difficulty inversely related to solver accuracy
estimated_difficulty = 1.0 - solver_accuracy
return estimated_difficulty
def compute_reward(self, task: str, solver_solved: bool, solver_accuracy: float) -> float:
"""
Compute reward for Challenger.
Challenger rewarded for:
- Generating tasks Solver cannot solve (high difficulty)
- But not so hard Solver never solves them (curriculum)
Args:
task: Generated task
solver_solved: Whether Solver succeeded
solver_accuracy: Solver success rate on similar tasks
Returns:
Reward signal for Challenger
"""
# Target solver success rate around 30-50% (challenging but solvable)
target_success_rate = 0.4
difficulty = 1.0 - solver_accuracy
# Reward is highest when difficulty is at target
reward = -(difficulty - target_success_rate) ** 2
return reward
```
### Step 2: Implement Solver Model
Create a model that solves Challenger tasks and provides learning signal.
```python
class SolverModel(torch.nn.Module):
"""
Solves Challenger's tasks and learns from outcomes.
"""
def __init__(self, base_model, task_domain="math"):
super().__init__()
self.base_model = base_model
self.task_domain = task_domain
self.solution_buffer = []
self.performance_history = []
def solve_task(self, task: str, max_attempts: int = 1) -> Tuple[str, bool]:
"""
Attempt to solve a task.
Args:
task: Task prompt
max_attempts: Number of solution attempts
Returns:
(solution, is_correct)
"""
prompt = f"""
Solve this {self.task_domain} problem:
{task}
Show your work and provide final answer.
Solution:
"""
solution = self.base_model.generate(prompt, max_length=500)
# Verify solution (domain-specific)
is_correct = self.verify_solution(task, solution)
return solution, is_correct
def verify_solution(self, task: str, solution: str) -> bool:
"""
Verify correctness of solution.
Args:
task: Original task
solution: Proposed solution
Returns:
True if solution is correct
"""
verification_prompt = f"""
Task: {task}
Proposed solution: {solution}
Is this solution mathematically correct?
Respond with only YES or NO.
"""
response = self.base_model.generate(verification_prompt, max_length=10)
return "YES" in response.upper()
def compute_reward(self, task: str, solution: str, is_correct: bool) -> float:
"""
Compute reward for Solver.
Solver rewarded for solving increasingly hard tasks.
Args:
task: Task that was solved
solution: Solution provided
is_correct: Whether solution is correct
Returns:
Reward signal for Solver
"""
if is_correct:
# Reward based on how hard the task is
task_difficulty = self.estimate_task_difficulty(task)
reward = task_difficulty # Harder tasks = higher reward
else:
reward = -0.5 # Penalty for incorrect solution
return reward
def estimate_task_difficulty(self, task: str) -> float:
"""Estimate difficulty of a task."""
# Heuristic: complexity based on task description
complexity_score = min(len(task.split()), 100) / 100.0
return complexity_score
def learn_from_tasks(self, tasks: List[str], batch_size: int = 4):
"""
Learn from solved tasks.
Args:
tasks: List of tasks to train on
batch_size: Training batch size
"""
for i in range(0, len(tasks), batch_size):
batch_tasks = tasks[i:i+batch_size]
for task in batch_tasks:
solution, is_correct = self.solve_task(task)
if is_correct:
# Learn from correct solutions
self.train_on_solution(task, solution)
def train_on_solution(self, task: str, solution: str):
"""Fine-tune on task-solution pair."""
# Standard supervised fine-tuning on correct solution
prompt = f"Problem: {task}\nSolution:"
self.base_model.finetune(prompt, solution)
```
### Step 3: Implement Co-evolutionary Training Loop
Create the main loop where Challenger and Solver interact.
```python
class CoevolutionaryFramework:
"""
Framework orchestrating Challenger-Solver co-evolution.
"""
def __init__(self, challenger: ChallengerModel, solver: SolverModel):
self.challenger = challenger
self.solver = solver
self.generation = 0
self.task_archive = []
self.performance_log = []
def run_generation(self, num_tasks: int = 20) -> Dict:
"""
Run one generation of co-evolution.
Args:
num_tasks: Number of tasks to generate and solve
Returns:
Metrics for this generation
"""
self.generation += 1
tasks_generated = []
tasks_solved_correctly = 0
challenger_rewards = []
solver_rewards = []
# Dynamic difficulty: increase as solver improves
base_difficulty = self._compute_difficulty_target()
for task_idx in range(num_tasks):
# 1. Challenger generates task
task = self.challenger.generate_task(difficulty_target=base_difficulty)
tasks_generated.append(task)
# 2. Solver attempts to solve
solution, is_correct = self.solver.solve_task(task)
if is_correct:
tasks_solved_correctly += 1
# 3. Compute rewards
solver_success_rate = tasks_solved_correctly / (task_idx + 1)
# Challenger reward: task at right difficulty
challenger_reward = self.challenger.compute_reward(
task,
is_correct,
solver_success_rate
)
challenger_rewards.append(challenger_reward)
# Solver reward: harder tasks give more reward
solver_reward = self.solver.compute_reward(task, solution, is_correct)
solver_rewards.append(solver_reward)
# Store task for learning
self.task_archive.append({
"task": task,
"solution": solution,
"correct": is_correct,
"generation": self.generation
})
# 4. Learn from generated tasks
correct_tasks = [t["task"] for t in self.task_archive
if t["correct"] and t["generation"] == self.generation]
self.solver.learn_from_tasks(correct_tasks)
# 5. Update models via RL
# (In practice, use policy gradient methods)
self._update_models_from_rewards(challenger_rewards, solver_rewards)
# Compute metrics
metrics = {
"generation": self.generation,
"tasks_generated": len(tasks_generated),
"tasks_solved": tasks_solved_correctly,
"success_rate": tasks_solved_correctly / num_tasks,
"avg_challenger_reward": sum(challenger_rewards) / len(challenger_rewards),
"avg_solver_reward": sum(solver_rewards) / len(solver_rewards),
"avg_difficulty": base_difficulty
}
self.performance_log.append(metrics)
return metrics
def _compute_difficulty_target(self) -> float:
"""
Compute target difficulty for this generation.
Difficulty increases as solver improves (curriculum learning).
Returns:
Difficulty target 0-1
"""
if not self.performance_log:
return 0.3 # Start easy
# Increase difficulty if solver succeeds >50%
recent_success = self.performance_log[-1]["success_rate"]
if recent_success > 0.5:
# Increase difficulty
new_difficulty = min(1.0, self.performance_log[-1]["avg_difficulty"] * 1.1)
elif recent_success < 0.2:
# Decrease difficulty
new_difficulty = max(0.1, self.performance_log[-1]["avg_difficulty"] / 1.1)
else:
new_difficulty = self.performance_log[-1]["avg_difficulty"]
return new_difficulty
def _update_models_from_rewards(self, challenger_rewards: List[float], solver_rewards: List[float]):
"""Update models using rewards (simplified)."""
# In practice, use REINFORCE or other policy gradient methods
# For now, just update solver on correct tasks
pass
def run_coevolution(self, num_generations: int = 10):
"""
Run full co-evolutionary training.
Args:
num_generations: Number of generations to evolve
"""
for gen in range(num_generations):
metrics = self.run_generation(num_tasks=20)
print(f"Generation {gen}: "
f"Success Rate={metrics['success_rate']:.1%}, "
f"Difficulty={metrics['avg_difficulty']:.2f}")
return self.performance_log
```
### Step 4: Evaluate Final Performance
Benchmark the evolved model on standard benchmarks.
```python
def evaluate_r_zero_model(solver_model, benchmark_suites: Dict[str, List]) -> Dict:
"""
Evaluate R-Zero trained model on benchmarks.
Args:
solver_model: Evolved solver model
benchmark_suites: Different benchmark suites (math, reasoning, etc.)
Returns:
Performance on each benchmark
"""
results = {}
for benchmark_name, problems in benchmark_suites.items():
correct = 0
for problem in problems:
solution, is_correct = solver_model.solve_task(problem["prompt"])
if is_correct:
correct += 1
accuracy = correct / len(problems)
results[benchmark_name] = accuracy
print(f"{benchmark_name}: {accuracy:.1%}")
return results
```
## Practical Guidance
### When to Use R-Zero
- **No human annotations available**: Bootstrapping models from scratch
- **Continuous learning scenarios**: Models that improve by self-play
- **Curriculum learning applications**: Progressive task difficulty needed
- **Research on self-improvement**: Understanding autonomous capability growth
### When NOT to Use R-Zero
- **Abundant labeled data**: Supervised learning likely more efficient
- **Fixed task distribution**: No need for curriculum generation
- **Real-time constraints**: Co-evolution is slow and compute-intensive
- **Safety-critical systems**: Hard to control generated task distribution
### Hyperparameter Recommendations
- **Target solver success rate**: 0.3-0.5 (challenging but solvable)
- **Difficulty increase factor**: 1.05-1.15 per generation
- **Task batch size**: 16-32 tasks per generation
- **Number of generations**: 10-20 for meaningful improvement
- **Tasks per generation**: 20-50 depends on task complexity
### Key Insights
The critical insight is that task generation and solving can bootstrap each other. By rewarding the Challenger for hard-but-solvable tasks, the framework naturally creates a curriculum. The Solver improves by learning from successfully solved tasks, which in turn motivates the Challenger to generate harder problems. This virtuous cycle enables capability growth without human annotation.
## Reference
**R-Zero: Self-Evolving Reasoning LLM from Zero Data** (arXiv:2508.05004)
Introduces co-evolutionary framework with Challenger and Solver models that generate training data and improve autonomously. Demonstrates +6.49pts math and +7.54pts general reasoning improvement without pre-existing labeled data.
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!