Upload folder using huggingface_hub
Browse files
README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
language:
|
| 4 |
+
- en
|
| 5 |
+
pipeline_tag: text-generation
|
| 6 |
+
tags:
|
| 7 |
+
- nanochat
|
| 8 |
+
- gpt
|
| 9 |
+
- from-scratch
|
| 10 |
+
- chat
|
| 11 |
+
- reinforcement-learning
|
| 12 |
+
- grpo
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
# WillyGPT
|
| 16 |
+
|
| 17 |
+
A 1.68B-parameter chat model trained from scratch — pretraining, supervised finetuning (SFT), and GRPO reinforcement learning — on the [nanochat](https://github.com/karpathy/nanochat) recipe (MIT). Built by William Yates on a single 8×H100 node.
|
| 18 |
+
|
| 19 |
+
Base pretraining clears the GPT-2 CORE reference (0.3016 vs 0.2565). Two checkpoints are released: an **SFT generalist (default)** and an **RL math-specialist**.
|
| 20 |
+
|
| 21 |
+
- **Full recipe, training scripts, and reproduction:** [github.com/williamyates/WillyGPT](https://github.com/williamyates/WillyGPT)
|
| 22 |
+
- **Architecture:** nanochat `d26` — these weights are *not* Hugging Face Transformers and will not load with `AutoModel.from_pretrained`. Run them with the nanochat code (below).
|
| 23 |
+
|
| 24 |
+
## Files in this repo
|
| 25 |
+
|
| 26 |
+
| Path | Checkpoint | Use |
|
| 27 |
+
|---|---|---|
|
| 28 |
+
| `chatsft_checkpoints/d26/model_000483.pt` | **SFT** (default) | Best all-rounder; chat, identity, spelling |
|
| 29 |
+
| `chatrl_checkpoints/d26/model_000466.pt` | **RL** | GSM8K-specialized; see decoding note below |
|
| 30 |
+
| `tokenizer/` | `tokenizer.pkl`, `token_bytes.pt` | 32,768-token BPE |
|
| 31 |
+
|
| 32 |
+
## Download & run
|
| 33 |
+
|
| 34 |
+
```bash
|
| 35 |
+
# 1. get nanochat
|
| 36 |
+
git clone https://github.com/karpathy/nanochat.git && cd nanochat
|
| 37 |
+
uv sync --extra gpu # or: uv sync --extra cpu (Mac/MPS, slow but works)
|
| 38 |
+
|
| 39 |
+
# 2. download these weights into nanochat's cache (structure is preserved)
|
| 40 |
+
export NANOCHAT_BASE_DIR=$PWD
|
| 41 |
+
hf download williamyates/WillyGPT --local-dir "$NANOCHAT_BASE_DIR/.cache/nanochat"
|
| 42 |
+
|
| 43 |
+
# 3. chat
|
| 44 |
+
python -m scripts.chat_cli -i sft -p "Who are you?" # SFT: generalist (recommended)
|
| 45 |
+
python -m scripts.chat_cli -i rl -p "What is 17 * 23?" # RL: math specialist
|
| 46 |
+
python -m scripts.chat_web # browser UI
|
| 47 |
+
```
|
| 48 |
+
|
| 49 |
+
A 1.68B model runs (slowly) on Apple Silicon via MPS, or on any single modern GPU.
|
| 50 |
+
|
| 51 |
+
**Decoding note for the RL checkpoint:** the RL model places near-certain probability on the end-of-turn token before emitting some answers (see analysis). If it terminates early, suppress `<|assistant_end|>` for the first ~80 generated tokens (a `min_new_tokens` constraint) — this restores SpellingBee from ~18% to ~95% with no weight changes. The SFT checkpoint does not need this.
|
| 52 |
+
|
| 53 |
+
## Model specification
|
| 54 |
+
|
| 55 |
+
| | |
|
| 56 |
+
|---|---|
|
| 57 |
+
| Architecture | GPT-style decoder transformer (nanochat `d26`) |
|
| 58 |
+
| Parameters | 1.68B (189 weight tensors) |
|
| 59 |
+
| Layers / heads | 26 layers · 13 attention heads · 13 KV heads · head dim 128 |
|
| 60 |
+
| Model dimension | 1664 |
|
| 61 |
+
| Context length | 2048 |
|
| 62 |
+
| Attention | Sliding-window (SSSL), Flash Attention 3 |
|
| 63 |
+
| Precision | fp8 training (Hopper / H100) |
|
| 64 |
+
| Tokenizer | 32,768-token BPE, GPT-4 style |
|
| 65 |
+
| Training data | NVIDIA ClimbMix (pretrain); SmolTalk + MMLU + GSM8K + custom identity set (SFT); GSM8K (RL) |
|
| 66 |
+
|
| 67 |
+
## Evaluation
|
| 68 |
+
|
| 69 |
+
Base on the pretraining CORE benchmark; SFT and RL on the nanochat chat suite. Accuracies (0–1) except the CORE/ChatCORE composites.
|
| 70 |
+
|
| 71 |
+
| Metric | Base | SFT | RL | Δ SFT→RL |
|
| 72 |
+
|---|---:|---:|---:|---:|
|
| 73 |
+
| CORE (pretrain) | 0.3016 | — | — | — |
|
| 74 |
+
| ChatCORE | — | 0.3982 | 0.2639 | −13.4 pt |
|
| 75 |
+
| GSM8K | — | 0.1099 | 0.1729 | +6.3 pt |
|
| 76 |
+
| SpellingBee | — | 0.9961 | 0.1836 | −81.3 pt |
|
| 77 |
+
| HumanEval | — | 0.1524 | 0.0915 | −6.1 pt |
|
| 78 |
+
| MMLU | — | 0.3831 | 0.3797 | −0.3 pt |
|
| 79 |
+
| ARC-Easy | — | 0.6843 | 0.6911 | +0.7 pt |
|
| 80 |
+
| ARC-Challenge | — | 0.5307 | 0.5307 | ±0.0 |
|
| 81 |
+
|
| 82 |
+
CORE 0.3016 exceeds the GPT-2 reference of 0.2565. **The SFT checkpoint is the default**; RL is a math-specialized variant.
|
| 83 |
+
|
| 84 |
+
### External comparison (directional — methodologies differ)
|
| 85 |
+
|
| 86 |
+
| Model | CORE | MMLU | ARC-E | ARC-C | GSM8K |
|
| 87 |
+
|---|---:|---:|---:|---:|---:|
|
| 88 |
+
| WillyGPT · 1.68B · '26 | 0.30 | 38.3 | 68.4 | 53.1 | 11.0→17.3 |
|
| 89 |
+
| GPT-2 XL · 1.5B · '19 | ~0.26 | ~26 | — | ~30 | ~0 |
|
| 90 |
+
| nanochat d20 ($100) · 561M | 0.22 | 31.5 | 38.8 | 28.1 | 4.6→7.6 |
|
| 91 |
+
| Qwen2.5-1.5B · '24 | — | 59.8 | 79.1 | 53.4 | 68.5 |
|
| 92 |
+
| SmolLM2-1.7B · '24 | — | 51.9 | 77.8 | 50.3 | 47.7 |
|
| 93 |
+
|
| 94 |
+
At identical parameter count WillyGPT is well ahead of GPT-2 XL; the gap to 2024 1.5B models is specific, not global (ARC-Challenge is level with Qwen2.5-1.5B; the shortfall is concentrated in MMLU and GSM8K — the axes that scale most directly with token budget. Qwen2.5 trained on ~18T tokens vs WillyGPT's 11B).
|
| 95 |
+
|
| 96 |
+
## SFT vs. RL analysis (summary)
|
| 97 |
+
|
| 98 |
+
GRPO improved its single optimization target (GSM8K, +6.3 pt / +57% relative) and left the rest flat or lower — a specialization tax. A logit-level investigation locates a large part of the regression in *when the model stops generating*, not in the underlying skills:
|
| 99 |
+
|
| 100 |
+
- **SpellingBee is masked, not lost.** Raw spelling is identical between SFT and RL (23/24). RL changed termination: `P(<|assistant_end|>)` at the answer position goes 0.000 → 0.999. Suppressing that token for ~80 decode steps recovers ~95% accuracy, inference-only.
|
| 101 |
+
- **HumanEval is genuinely mixed** — roughly half harness/extraction artifact, half real RL mode-collapse (degenerate repetition).
|
| 102 |
+
- **Identity robustness is thin.** Both checkpoints answer "Who are you?" correctly cold; mid-conversation the RL checkpoint can confabulate a false (DeepMind/AlphaGo) origin, while SFT holds. Mitigate with a system prompt.
|
| 103 |
+
- **Interpretability caveat.** An initial weight-diff hypothesis (RL altered "smear" parameters) was falsified by a dose-response ablation — largest relative weight change ≠ functional importance.
|
| 104 |
+
|
| 105 |
+
Full mechanistic writeup and recommendations: [the GitHub README](https://github.com/williamyates/WillyGPT).
|
| 106 |
+
|
| 107 |
+
## Limitations
|
| 108 |
+
|
| 109 |
+
This is a sub-2B model trained on 11B tokens. It is **not a frontier model** and **confidently hallucinates specific facts** (e.g. inventing place names). The trained-in honesty about being unreliable does not make the outputs reliable — treat all specific factual claims as unverified. Knowledge breadth (MMLU) and multi-step math (GSM8K) are the weakest areas, as expected from the token budget.
|
| 110 |
+
|
| 111 |
+
## Provenance
|
| 112 |
+
|
| 113 |
+
Both checkpoints were verified bit-for-bit (SHA-256) between the GPU node and a laptop before teardown, deserialize cleanly on CPU/MPS (189 tensors, ~1.68B params), and run locally on a 32 GB M4 MacBook Air via MPS.
|
| 114 |
+
|
| 115 |
+
## Credits & license
|
| 116 |
+
|
| 117 |
+
MIT-licensed; a derivative of [nanochat](https://github.com/karpathy/nanochat) by Andrej Karpathy (also MIT). The nanochat framework — architecture, training scripts, tokenizer, and eval harness — is Karpathy's work. This release adds the d26 configuration, the identity layer, the GRPO stage, and the accompanying analysis. Pretraining data: NVIDIA ClimbMix. SFT data: SmolTalk, MMLU, GSM8K, plus a custom identity set.
|
chatrl_checkpoints/d26/meta_000466.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_config": {
|
| 3 |
+
"sequence_len": 2048,
|
| 4 |
+
"vocab_size": 32768,
|
| 5 |
+
"n_layer": 26,
|
| 6 |
+
"n_head": 13,
|
| 7 |
+
"n_kv_head": 13,
|
| 8 |
+
"n_embd": 1664,
|
| 9 |
+
"window_pattern": "SSSL"
|
| 10 |
+
}
|
| 11 |
+
}
|
chatrl_checkpoints/d26/model_000466.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f7e32cc73e5f9ddbe120897b7d8f5353756fd996d8e16a758ef3db6beb94ebd8
|
| 3 |
+
size 5200496084
|
chatsft_checkpoints/d26/meta_000483.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"step": 483,
|
| 3 |
+
"val_bpb": 0.2566640397744885,
|
| 4 |
+
"model_config": {
|
| 5 |
+
"sequence_len": 2048,
|
| 6 |
+
"vocab_size": 32768,
|
| 7 |
+
"n_layer": 26,
|
| 8 |
+
"n_head": 13,
|
| 9 |
+
"n_kv_head": 13,
|
| 10 |
+
"n_embd": 1664,
|
| 11 |
+
"window_pattern": "SSSL"
|
| 12 |
+
},
|
| 13 |
+
"user_config": {
|
| 14 |
+
"run": "dummy",
|
| 15 |
+
"device_type": "",
|
| 16 |
+
"model_tag": null,
|
| 17 |
+
"model_step": null,
|
| 18 |
+
"load_optimizer": 1,
|
| 19 |
+
"num_iterations": -1,
|
| 20 |
+
"max_seq_len": null,
|
| 21 |
+
"device_batch_size": 8,
|
| 22 |
+
"total_batch_size": null,
|
| 23 |
+
"embedding_lr": null,
|
| 24 |
+
"unembedding_lr": null,
|
| 25 |
+
"matrix_lr": null,
|
| 26 |
+
"init_lr_frac": 0.8,
|
| 27 |
+
"warmup_ratio": 0.0,
|
| 28 |
+
"warmdown_ratio": 0.5,
|
| 29 |
+
"final_lr_frac": 0.0,
|
| 30 |
+
"eval_every": 200,
|
| 31 |
+
"eval_tokens": 20971520,
|
| 32 |
+
"chatcore_every": 200,
|
| 33 |
+
"chatcore_max_cat": -1,
|
| 34 |
+
"chatcore_max_sample": 24,
|
| 35 |
+
"mmlu_epochs": 3,
|
| 36 |
+
"gsm8k_epochs": 4
|
| 37 |
+
}
|
| 38 |
+
}
|
chatsft_checkpoints/d26/model_000483.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:500d7b14cc7a42c05ac8ff425ffb45707f91fcca040b9f8452d140d97418d893
|
| 3 |
+
size 5200496084
|
tokenizer/token_bytes.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:398732dad177888c6f884c3abb76168a6b54fd7c3f011b2d38371587faca54b7
|
| 3 |
+
size 132649
|
tokenizer/tokenizer.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:387cfc082b0bee45467774fd6f1310a922ad170886a58ccddcb468f275e06a6c
|
| 3 |
+
size 412105
|