Skip to content
Back to skills

R Zero Self Evolving Reasoning

ASecurity

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.

  • 6 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added September 9, 2026
ai-agentspythonperformance

Security analysis

A100/100

Scanned September 9, 2026

npx -y skills add ADu2021/skillXiv --skill r-zero-self-evolving-reasoning --agent claude-code

Installs 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 with every re-scan.

Security grade badge for R Zero Self Evolving Reasoning
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/adu2021-r-zero-self-evolving-reasoning/badge)](https://www.skillsdirectory.com/skills/adu2021-r-zero-self-evolving-reasoning)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.