Update README.md
Browse files
README.md
CHANGED
|
@@ -12,67 +12,141 @@ tags:
|
|
| 12 |
- rlvr
|
| 13 |
datasets:
|
| 14 |
- HuggingFaceFW/fineweb-edu
|
|
|
|
| 15 |
metrics:
|
| 16 |
- accuracy
|
|
|
|
| 17 |
---
|
| 18 |
|
| 19 |
# Rune-R1 (351M) — GRPO Reasoning Model
|
| 20 |
|
| 21 |
-
**Rune-R1** is a ~351M parameter decoder-only transformer trained from scratch
|
| 22 |
-
aligned for math reasoning via a
|
| 23 |
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
KL-to-reference regularization, using a verifiable reward on math answer correctness
|
| 28 |
-
(reasoning-from-scratch style recipe). Trained for 2000 steps.
|
| 29 |
|
| 30 |
-
This
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
-
## Model
|
| 33 |
|
| 34 |
-
- **
|
| 35 |
-
- **
|
| 36 |
-
- **
|
| 37 |
-
- **
|
| 38 |
-
- **
|
| 39 |
-
- **
|
| 40 |
-
- **Position Embeddings**: RoPE (Rotary Position Embeddings)
|
| 41 |
-
- **Normalization**: RMSNorm (with QK Normalization)
|
| 42 |
-
- **Context Length**: 1024 tokens
|
| 43 |
- **Tokenizer**: GPT-2 (`tiktoken`)
|
|
|
|
| 44 |
|
| 45 |
-
##
|
| 46 |
|
| 47 |
-
|
| 48 |
-
-
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
-
|
| 53 |
-
and 1900), reflecting the small model size and limited RL budget rather than a fully
|
| 54 |
-
converged reasoning model. Mean reward per step across training was ~0.016, with
|
| 55 |
-
occasional higher-reward rollouts (max single-step average 0.75).
|
| 56 |
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
|
| 61 |
```python
|
| 62 |
import torch
|
| 63 |
import tiktoken
|
| 64 |
from rune.model import CONFIG_350M, RuneModel
|
| 65 |
|
| 66 |
-
# Load model weights
|
| 67 |
ckpt = torch.load("pytorch_model.bin", map_location="cpu")
|
| 68 |
model = RuneModel(CONFIG_350M)
|
| 69 |
model.load_state_dict(ckpt)
|
| 70 |
model.eval()
|
| 71 |
|
| 72 |
-
# Encode prompt
|
| 73 |
enc = tiktoken.get_encoding("gpt2")
|
| 74 |
-
prompt = "
|
| 75 |
tokens = torch.tensor([enc.encode(prompt)], dtype=torch.long)
|
| 76 |
|
| 77 |
-
#
|
|
|
|
| 78 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
- rlvr
|
| 13 |
datasets:
|
| 14 |
- HuggingFaceFW/fineweb-edu
|
| 15 |
+
- rasbt/math_distill
|
| 16 |
metrics:
|
| 17 |
- accuracy
|
| 18 |
+
pipeline_tag: text-generation
|
| 19 |
---
|
| 20 |
|
| 21 |
# Rune-R1 (351M) — GRPO Reasoning Model
|
| 22 |
|
| 23 |
+
**Rune-R1** is a ~351M parameter decoder-only transformer trained from scratch and
|
| 24 |
+
aligned for math reasoning via a three-stage pipeline:
|
| 25 |
|
| 26 |
+
```
|
| 27 |
+
Pretrain (FineWeb-Edu) → SFT (distilled CoT format) → GRPO (RLVR on math correctness)
|
| 28 |
+
```
|
|
|
|
|
|
|
| 29 |
|
| 30 |
+
This repository holds the final checkpoint: the GRPO-tuned policy, starting from
|
| 31 |
+
[Rune-R1-SFT](https://huggingface.co/samueljayasingh/Rune-R1-sft) and optimized
|
| 32 |
+
with Group Relative Policy Optimization against a verifiable, rule-based reward for
|
| 33 |
+
math answer correctness. See [Rune-R1-Base](https://huggingface.co/samueljayasingh/Rune-R1-base)
|
| 34 |
+
and [Rune-R1-SFT](https://huggingface.co/samueljayasingh/Rune-R1-sft) for the earlier
|
| 35 |
+
pipeline stages.
|
| 36 |
|
| 37 |
+
## Model Description
|
| 38 |
|
| 39 |
+
- **Developed by**: samueljayasingh
|
| 40 |
+
- **Model type**: Causal language model (text-only)
|
| 41 |
+
- **Base model**: [Rune-R1-SFT](https://huggingface.co/samueljayasingh/Rune-R1-sft) (351M, chain-of-thought SFT on top of Rune-R1-Base)
|
| 42 |
+
- **Fine-tuning method**: GRPO (Group Relative Policy Optimization) with PPO-style clipping and a KL penalty to a frozen reference (RLVR — reinforcement learning from verifiable rewards)
|
| 43 |
+
- **Dataset**: `data/math_train.json` (math word problems with verifiable final answers), evaluated on a 50-example MATH-500 held-out subset
|
| 44 |
+
- **Language**: English
|
|
|
|
|
|
|
|
|
|
| 45 |
- **Tokenizer**: GPT-2 (`tiktoken`)
|
| 46 |
+
- **License**: Apache 2.0
|
| 47 |
|
| 48 |
+
### Architecture details
|
| 49 |
|
| 50 |
+
| Parameter | Value |
|
| 51 |
+
|---|---|
|
| 52 |
+
| Layers | 22 |
|
| 53 |
+
| Embedding dimension | 1024 |
|
| 54 |
+
| Attention heads / KV groups | 16 / 4 (GQA) |
|
| 55 |
+
| Feed-forward hidden dim | 2816 (SwiGLU) |
|
| 56 |
+
| Context length | 1024 tokens |
|
| 57 |
+
| Position embeddings | RoPE (base 10,000) |
|
| 58 |
+
| Normalization | RMSNorm, with QK normalization |
|
| 59 |
|
| 60 |
+
## Intended Uses & Limitations
|
|
|
|
|
|
|
|
|
|
| 61 |
|
| 62 |
+
**Intended use:**
|
| 63 |
+
- Research into RLVR / GRPO-style reasoning fine-tuning at small model scale.
|
| 64 |
+
- Reference implementation for reward-verified RL post-training pipelines (pretrain → SFT → RL).
|
| 65 |
+
- Studying reward hacking, KL-regularization tradeoffs, and reasoning-accuracy dynamics under a small RL step budget.
|
| 66 |
|
| 67 |
+
**Limitations:**
|
| 68 |
+
- Small model (351M) with a limited RL budget (2,000 steps) — MATH-500 accuracy
|
| 69 |
+
remains low (0–4% across evaluation checkpoints; see table below) and should not
|
| 70 |
+
be compared to production-scale reasoning models.
|
| 71 |
+
- Reward signal is a rule-based correctness check (`\boxed{}` extraction + symbolic
|
| 72 |
+
grading), so the model may still learn to produce well-formatted but incorrect
|
| 73 |
+
reasoning that occasionally reward-hacks the verifier.
|
| 74 |
+
- Inherits base/SFT limitations: 1024-token context, ~5B pretraining tokens, no
|
| 75 |
+
broad safety/RLHF alignment beyond the math-correctness reward.
|
| 76 |
+
- Not suitable for production or user-facing deployment — this is a research
|
| 77 |
+
artifact demonstrating the training pipeline, not a competitive reasoning model.
|
| 78 |
+
|
| 79 |
+
## How to Use
|
| 80 |
|
| 81 |
```python
|
| 82 |
import torch
|
| 83 |
import tiktoken
|
| 84 |
from rune.model import CONFIG_350M, RuneModel
|
| 85 |
|
|
|
|
| 86 |
ckpt = torch.load("pytorch_model.bin", map_location="cpu")
|
| 87 |
model = RuneModel(CONFIG_350M)
|
| 88 |
model.load_state_dict(ckpt)
|
| 89 |
model.eval()
|
| 90 |
|
|
|
|
| 91 |
enc = tiktoken.get_encoding("gpt2")
|
| 92 |
+
prompt = "What is 12 * 15?"
|
| 93 |
tokens = torch.tensor([enc.encode(prompt)], dtype=torch.long)
|
| 94 |
|
| 95 |
+
# Model responds in "<think>...reasoning...</think>\n\n\\boxed{final_answer}" format.
|
| 96 |
+
# See rune/generate.py in the source repo for full sampling / KV-cache generation code.
|
| 97 |
```
|
| 98 |
+
|
| 99 |
+
The `rune` package (model definition + generation utilities) is available at the
|
| 100 |
+
[Rune-R1 GitHub repository](https://github.com/samueljayasingh/Rune-R1).
|
| 101 |
+
|
| 102 |
+
## Training & Evaluation
|
| 103 |
+
|
| 104 |
+
### Training procedure
|
| 105 |
+
|
| 106 |
+
| Parameter | Value |
|
| 107 |
+
|---|---|
|
| 108 |
+
| Starting checkpoint | Rune-R1-SFT |
|
| 109 |
+
| Reference model | Frozen copy of the SFT checkpoint (KL penalty target) |
|
| 110 |
+
| Training steps | 2,000 |
|
| 111 |
+
| Rollouts per prompt (group size) | 8 |
|
| 112 |
+
| Inner epochs per rollout batch | 2 |
|
| 113 |
+
| Max new tokens (rollout) | 512 |
|
| 114 |
+
| Sampling temperature / top-p | 0.8 / 0.9 |
|
| 115 |
+
| PPO clip epsilon | 10.0 |
|
| 116 |
+
| KL coefficient | 0.001 |
|
| 117 |
+
| Learning rate | 1e-6 |
|
| 118 |
+
| Reward function | Rule-based: extract `\boxed{}` answer, symbolically grade vs. ground truth (1.0 / 0.0) |
|
| 119 |
+
| Eval cadence | MATH-500 (50-example subset), every 100 steps |
|
| 120 |
+
| Hardware | 1x AMD MI300X GPU |
|
| 121 |
+
|
| 122 |
+
### Evaluation results
|
| 123 |
+
|
| 124 |
+
| Metric | Value |
|
| 125 |
+
|---|---|
|
| 126 |
+
| Final MATH-500 accuracy (step 2000) | 0% (50 examples) |
|
| 127 |
+
| Peak MATH-500 accuracy | 4% (steps 1600, 1900) |
|
| 128 |
+
| Mean reward per step (over training) | ~0.016 |
|
| 129 |
+
| Max single-step average reward | 0.75 |
|
| 130 |
+
| Steps with nonzero reward | 152 / 2001 |
|
| 131 |
+
|
| 132 |
+
MATH-500 accuracy fluctuated in the 0–4% range throughout training rather than
|
| 133 |
+
improving monotonically, reflecting the small model size and limited RL budget
|
| 134 |
+
rather than a fully converged reasoning model.
|
| 135 |
+
|
| 136 |
+
## Citation
|
| 137 |
+
|
| 138 |
+
```bibtex
|
| 139 |
+
@misc{RuneR12026,
|
| 140 |
+
author = {Samuel Jayasingh},
|
| 141 |
+
title = {Rune-R1: A 351M Transformer Reasoning Model Trained via Pretrain-SFT-GRPO from Scratch},
|
| 142 |
+
year = {2026},
|
| 143 |
+
publisher = {Hugging Face},
|
| 144 |
+
howpublished = {\url{https://huggingface.co/samueljayasingh/Rune-R1}}
|
| 145 |
+
}
|
| 146 |
+
```
|
| 147 |
+
|
| 148 |
+
## Acknowledgements
|
| 149 |
+
|
| 150 |
+
- [HuggingFaceFW/fineweb-edu](https://huggingface.co/datasets/HuggingFaceFW/fineweb-edu) — pretraining corpus.
|
| 151 |
+
- [rasbt/math_distill](https://huggingface.co/datasets/rasbt/math_distill) — distilled chain-of-thought SFT data.
|
| 152 |
+
- [rasbt/LLMs-from-scratch](https://github.com/rasbt/LLMs-from-scratch) — architecture and the pretrain→SFT→GRPO reasoning-from-scratch recipe this pipeline is adapted from.
|