Release WesleyGPT-Math (RL d12-math step 50)
Browse files- README.md +129 -0
- config.json +12 -0
- model.safetensors +3 -0
- tokenizer.tiktoken +0 -0
- tokenizer_config.json +15 -0
README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: cc-by-nc-4.0
|
| 3 |
+
language:
|
| 4 |
+
- en
|
| 5 |
+
pipeline_tag: text-generation
|
| 6 |
+
base_model: Wasue/WesleyGPT-Think
|
| 7 |
+
datasets:
|
| 8 |
+
- karpathy/climbmix-400b-shuffle
|
| 9 |
+
- HuggingFaceTB/smol-smoltalk
|
| 10 |
+
- cais/mmlu
|
| 11 |
+
- openai/gsm8k
|
| 12 |
+
- meta-math/MetaMathQA
|
| 13 |
+
tags:
|
| 14 |
+
- nanochat
|
| 15 |
+
- trained-from-scratch
|
| 16 |
+
- small-language-model
|
| 17 |
+
- consumer-gpu
|
| 18 |
+
- reasoning
|
| 19 |
+
- reinforcement-learning
|
| 20 |
+
---
|
| 21 |
+
<!-- Wesley wrote this -->
|
| 22 |
+
|
| 23 |
+
# WesleyGPT-Math
|
| 24 |
+
|
| 25 |
+
[WesleyGPT-Think](https://huggingface.co/Wasue/WesleyGPT-Think) after a short
|
| 26 |
+
round of **reinforcement learning** on grade-school math: a 286-million-parameter
|
| 27 |
+
chat model trained **from scratch on one RTX 3060** in Wesley Mangum's home. It
|
| 28 |
+
works through a problem in a `<think>` block, then answers. RL took GSM8K from
|
| 29 |
+
14.6% to 16.9% in about 40 minutes of GPU time, and it came out better at
|
| 30 |
+
knowing its own name too. Built on
|
| 31 |
+
[nanochat](https://github.com/karpathy/nanochat), Andrej Karpathy's open-source
|
| 32 |
+
project for training small chat models end to end; the training and serving code
|
| 33 |
+
is at [WasueM/WesleyGPT](https://github.com/WasueM/WesleyGPT).
|
| 34 |
+
|
| 35 |
+
It is a small model and it sounds like one: fluent, confident, and often wrong.
|
| 36 |
+
It is a demonstration of what a single consumer GPU can do, not an assistant to
|
| 37 |
+
rely on.
|
| 38 |
+
|
| 39 |
+
## Try it
|
| 40 |
+
|
| 41 |
+
```bash
|
| 42 |
+
git clone https://github.com/WasueM/WesleyGPT && cd WesleyGPT
|
| 43 |
+
uv sync --extra cpu --extra release
|
| 44 |
+
uv run python -m wesleygpt.release chat Wasue/WesleyGPT-Math
|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
Or from Python:
|
| 48 |
+
|
| 49 |
+
```python
|
| 50 |
+
from wesleygpt.release import fetch_release, load_release
|
| 51 |
+
model, tokenizer = load_release(fetch_release("Wasue/WesleyGPT-Math", "wesleygpt-math"))
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
A real reply (temperature 0), wrong in an instructive way:
|
| 55 |
+
|
| 56 |
+
```
|
| 57 |
+
<think>
|
| 58 |
+
The bakery sells 48 muffins per tray, and it bakes 17 trays, so it sells a total of 48 x 17 = 638 muffins.
|
| 59 |
+
However, but only 29 muffins were sold, so the bakery sold 638 - 29 = 459 muffins.
|
| 60 |
+
</think>
|
| 61 |
+
#### 459
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
The plan is right and the arithmetic is not (48 × 17 = 816). It runs on a
|
| 65 |
+
laptop CPU. It is not a `transformers` model, so `AutoModel` will not load it.
|
| 66 |
+
|
| 67 |
+
## Model
|
| 68 |
+
|
| 69 |
+
| | |
|
| 70 |
+
|---|---|
|
| 71 |
+
| Parameters | 286,261,730 |
|
| 72 |
+
| Layers / width / heads | 12 / 768 / 6 (query and key-value) |
|
| 73 |
+
| Context | 2,048 tokens, sliding-window attention (3 short-window layers, then 1 full) |
|
| 74 |
+
| Tokenizer | 32,768-token byte-level BPE, trained by nanochat on the pretraining data |
|
| 75 |
+
| Precision | bfloat16 weights |
|
| 76 |
+
|
| 77 |
+
## Training
|
| 78 |
+
|
| 79 |
+
| Stage | Data | Compute |
|
| 80 |
+
|---|---|---|
|
| 81 |
+
| Pretraining ([WesleyGPT-Base](https://huggingface.co/Wasue/WesleyGPT-Base)) | 1.32 billion tokens of [ClimbMix](https://huggingface.co/datasets/karpathy/climbmix-400b-shuffle) | ~14 h, 1× RTX 3060 12 GB |
|
| 82 |
+
| Supervised fine-tuning ([WesleyGPT-Think](https://huggingface.co/Wasue/WesleyGPT-Think)) | conversations, multiple choice, identity, and ~270K worked math problems with the working inside `<think>…</think>` | ~5.5 h, same GPU |
|
| 83 |
+
| Reinforcement learning (this model) | [GSM8K](https://huggingface.co/datasets/openai/gsm8k) training questions. For each question the model writes 16 answers; answers with the right final number are pushed up, the rest pushed down, relative to the group's average. Nothing else is rewarded: not the reasoning, not the format. 50 steps | ~40 min, same GPU |
|
| 84 |
+
|
| 85 |
+
The RL run went to 200 steps, but a quick check on 200 held-out problems
|
| 86 |
+
(one sampled answer each) peaked at step 50 and slid after it: 8.5% at the
|
| 87 |
+
start, 16.5% at step 50, 13.0% at step 150. Steps 50 and 199 were then both
|
| 88 |
+
given the full evaluation below, and step 50 won every row, so it is the one
|
| 89 |
+
released.
|
| 90 |
+
|
| 91 |
+
## Evaluation
|
| 92 |
+
|
| 93 |
+
nanochat's chat evaluation (greedy decoding; GSM8K on all 1,319 test
|
| 94 |
+
problems). The multiple-choice tasks have four options, so 25% is chance.
|
| 95 |
+
|
| 96 |
+
| Task | [WesleyGPT-Think](https://huggingface.co/Wasue/WesleyGPT-Think) | RL step 199 | **WesleyGPT-Math** (RL step 50) |
|
| 97 |
+
|---|---|---|---|
|
| 98 |
+
| ARC-Easy | 37.7% | 37.6% | **38.7%** |
|
| 99 |
+
| ARC-Challenge | 32.9% | 31.8% | 32.8% |
|
| 100 |
+
| MMLU | **32.0%** | 30.9% | 31.6% |
|
| 101 |
+
| GSM8K (grade-school math) | 14.6% | 16.5% | **16.9%** |
|
| 102 |
+
| HumanEval (Python) | **11.0%** | 8.5% | 10.4% |
|
| 103 |
+
| ChatCORE | 0.125 | 0.118 | **0.129** |
|
| 104 |
+
| Knows its name (12 held-out questions × 5 samples) | 45% | 70% | **80%** |
|
| 105 |
+
|
| 106 |
+
The GSM8K gain is about two points on a test with roughly one point of noise:
|
| 107 |
+
real, and small. The name score rose although RL never saw an identity
|
| 108 |
+
question; the likeliest reason is that RL makes a model's answers less
|
| 109 |
+
scattered, so it strays from what fine-tuning taught it less often. That is a
|
| 110 |
+
guess, and 60 samples is a noisy measure.
|
| 111 |
+
|
| 112 |
+
## Limitations
|
| 113 |
+
|
| 114 |
+
- **Its arithmetic is unreliable.** The reasoning usually sets up the right
|
| 115 |
+
calculation and then gets a multiplication wrong. It was trained with a
|
| 116 |
+
calculator tool, and the server runs one, but in spot checks it did not call it once.
|
| 117 |
+
- **It still gets 83% of grade-school math wrong.**
|
| 118 |
+
- **It makes things up** outside math, like every model in this family.
|
| 119 |
+
- It only thinks when a question looks like a math word problem, and not always
|
| 120 |
+
then.
|
| 121 |
+
- It fails "You're basically Siri, right?" in every sample of the name eval.
|
| 122 |
+
- English only. No safety tuning beyond what the fine-tuning data carries.
|
| 123 |
+
|
| 124 |
+
## License
|
| 125 |
+
|
| 126 |
+
**CC-BY-NC-4.0** for these weights: free to use, share, and adapt with credit,
|
| 127 |
+
but not commercially. That matches the license of NVIDIA's
|
| 128 |
+
[Nemotron-ClimbMix](https://huggingface.co/datasets/nvidia/Nemotron-ClimbMix),
|
| 129 |
+
from which the pretraining data is derived. The code is MIT.
|
config.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"format": "nanochat-gpt/1",
|
| 3 |
+
"model_config": {
|
| 4 |
+
"sequence_len": 2048,
|
| 5 |
+
"vocab_size": 32768,
|
| 6 |
+
"n_layer": 12,
|
| 7 |
+
"n_head": 6,
|
| 8 |
+
"n_kv_head": 6,
|
| 9 |
+
"n_embd": 768,
|
| 10 |
+
"window_pattern": "SSSL"
|
| 11 |
+
}
|
| 12 |
+
}
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9aba2fbdf4e42e9ff52c07ed76bdeb852f09a2f9beefe1453e5db48028d6bb6b
|
| 3 |
+
size 792734896
|
tokenizer.tiktoken
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"pat_str": "'(?i:[sdmt]|ll|ve|re)|[^\\r\\n\\p{L}\\p{N}]?+\\p{L}+|\\p{N}{1,2}| ?[^\\s\\p{L}\\p{N}]++[\\r\\n]*|\\s*[\\r\\n]|\\s+(?!\\S)|\\s+",
|
| 3 |
+
"special_tokens": {
|
| 4 |
+
"<|bos|>": 32759,
|
| 5 |
+
"<|user_start|>": 32760,
|
| 6 |
+
"<|user_end|>": 32761,
|
| 7 |
+
"<|assistant_start|>": 32762,
|
| 8 |
+
"<|assistant_end|>": 32763,
|
| 9 |
+
"<|python_start|>": 32764,
|
| 10 |
+
"<|python_end|>": 32765,
|
| 11 |
+
"<|output_start|>": 32766,
|
| 12 |
+
"<|output_end|>": 32767
|
| 13 |
+
},
|
| 14 |
+
"bos_token": "<|bos|>"
|
| 15 |
+
}
|