Skip to content

Commit 14ace3e

Browse files
Audit and strengthen baseline training recipes (#26)
Audit every baseline recipe, strengthen MNIST and CIFAR-10 ViT training protocols, preserve the accepted one-head nanoGPT and pinned nanochat references, and add source-backed documentation and regression tests.
1 parent 6aa2e55 commit 14ace3e

19 files changed

Lines changed: 2428 additions & 2035 deletions

baseline/BASELINE_RECIPE_AUDIT.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# Baseline recipe audit
2+
3+
This document records the August 2026 audit of every control experiment under
4+
`baseline/`. The objective is a **strong, reproducible reference recipe**, not
5+
a claim that a finite hyperparameter grid proves a globally optimal setting.
6+
Any future tuning must use training/validation data only; the protected test set
7+
must not select hyperparameters, schedules, checkpoints, or stopping times.
8+
9+
## Audit summary
10+
11+
| Baseline | Data audit | Optimizer/schedule audit | Status after this revision |
12+
|---|---|---|---|
13+
| MNIST / MLP3 | Canonical MNIST train/test files and standard normalization | Fixed learning rates were replaced by optimizer-specific warm-up/cosine schedules; the Muon arm now uses the reference auxiliary-AdamW partition | **Corrected** |
14+
| CIFAR-10 / small ViT | Canonical CIFAR-10 with a fixed 45k/5k training/validation split and protected test set | Upgraded to the full DeiT-style augmentation/regularization stack, optimizer-specific schedules and nonzero floors, validation-selected checkpoints, and restartable runs | **Corrected** |
15+
| One-head nanoGPT / FineWeb-Edu | Pinned FineWeb-Edu `sample-10BT`, exact document-disjoint 10M/1M/1M GPT-2-BPE splits, file hashes | AdamW follows nanoGPT; Muon follows the reference hidden-matrix/auxiliary-AdamW split; every optimizer has warm-up and cosine decay | **Accepted** |
16+
| nanochat d12 | Pinned upstream nanochat data/tokenizer pipeline | Runs the pinned upstream d12 recipe unchanged, including native initialization, Muon/AdamW groups, scaling rules, warm-up, warmdown, momentum, and weight-decay schedules | **Accepted as upstream reference** |
17+
18+
## 1. MNIST / MLP3
19+
20+
### Data
21+
22+
The baseline uses the official torchvision MNIST training and test sets with
23+
the conventional normalization:
24+
25+
```text
26+
mean = 0.1307
27+
std = 0.3081
28+
```
29+
30+
The dataset is appropriate for a cheap dense-network control. It is not meant
31+
to establish broad architectural generality.
32+
33+
### Corrected optimizer recipes
34+
35+
All three runs now use 30 epochs, batch size 128, gradient clipping at 1.0, a
36+
short linear warm-up, and cosine decay to a nonzero floor.
37+
38+
| Optimizer | Peak LR | Floor | Warm-up | Other settings |
39+
|---|---:|---:|---:|---|
40+
| SGD + Nesterov | 0.05 | 5e-4 | 2 epochs | momentum 0.90, matrix-only weight decay 1e-4 |
41+
| AdamW | 1e-3 | 1e-5 | 1 epoch | betas (0.90, 0.999), matrix-only weight decay 1e-2 |
42+
| Muon matrices | 0.02 | 0.002 | 2 epochs | momentum 0.95, Nesterov, 5 Newton-Schulz steps, weight decay 0.01 |
43+
| Muon auxiliary AdamW | 3e-4 | 3e-5 | 2 epochs | betas (0.90, 0.95), weight decay 0.01 on auxiliary matrices only |
44+
45+
The historical result key `sgd_momentum_muon` remains in file paths so old
46+
baseline stores stay discoverable, but the corrected implementation is
47+
**Muon + auxiliary AdamW**, not Muon + auxiliary SGD.
48+
49+
The Muon partition follows the reference implementation: hidden 2-D matrices
50+
receive Muon; classifier/head parameters, embeddings where present, gains, and
51+
biases receive AdamW.
52+
53+
Primary references:
54+
55+
- nanoGPT training defaults:
56+
<https://github.com/karpathy/nanoGPT/blob/master/train.py>
57+
- reference Muon implementation and parameter partition:
58+
<https://github.com/KellerJordan/Muon>
59+
60+
## 2. CIFAR-10 / small ViT
61+
62+
### Data and selection policy
63+
64+
The official CIFAR-10 training set is split once with a fixed split seed:
65+
66+
```text
67+
optimization/train: 45,000 examples
68+
validation: 5,000 examples
69+
test: 10,000 examples
70+
```
71+
72+
All optimizer arms and seeds use the same train/validation identities.
73+
Validation loss selects `checkpoint_best.pt`. Test loss and accuracy may be
74+
plotted by epoch, but they are explicitly monitoring-only and never influence
75+
training or selection.
76+
77+
### Corrected model/training recipe
78+
79+
The model remains the intended small ViT:
80+
81+
```text
82+
patches: 4x4
83+
width: 192
84+
blocks: 6
85+
heads: 3
86+
MLP ratio: 4
87+
```
88+
89+
The strong reference now uses 300 epochs and the full DeiT-style regularization
90+
stack:
91+
92+
```text
93+
dropout: 0.0
94+
stochastic depth: 0.10
95+
RandAugment: 2 operations, magnitude 9
96+
color jitter: 0.30
97+
random erasing: 0.25
98+
mixup alpha: 0.80
99+
CutMix alpha: 1.00
100+
label smoothing: 0.10
101+
gradient clipping: 1.0
102+
```
103+
104+
The augmentation stack matters for ViT/Muon comparisons: weak regularization
105+
can change both generalization and gradient spectral structure, so an optimizer
106+
comparison should not be built on an under-regularized ViT recipe.
107+
108+
### Corrected optimizer schedules
109+
110+
| Optimizer | Peak LR | Floor | Warm-up | Other settings |
111+
|---|---:|---:|---:|---|
112+
| SGD + Nesterov | 0.10 | 0.001 | 5 epochs | momentum 0.90, weight decay 5e-4 |
113+
| AdamW | 1.25e-4 | 1e-5 | 5 epochs | betas (0.90, 0.999), weight decay 0.05 |
114+
| Muon matrices | 0.02 | 0.002 | 5 epochs | momentum 0.95, Nesterov, 5 Newton-Schulz steps, weight decay 0.01 |
115+
| Muon auxiliary AdamW | 3e-4 | 3e-5 | 5 epochs | betas (0.90, 0.95), weight decay 0.01 |
116+
117+
The AdamW peak is the DeiT reference LR `5e-4` linearly scaled from effective
118+
batch 512 to the committed effective batch 128:
119+
120+
```text
121+
5e-4 * 128 / 512 = 1.25e-4
122+
```
123+
124+
The implementation now saves exact restart state every epoch, including model,
125+
optimizer, data-loader generator, Python/NumPy/Torch RNG state, protocol
126+
fingerprint, and best validation loss.
127+
128+
Primary references:
129+
130+
- DeiT training recipe:
131+
<https://github.com/facebookresearch/deit/blob/main/main.py>
132+
- Muon reference implementation:
133+
<https://github.com/KellerJordan/Muon>
134+
- recent optimizer/recipe interaction study for Muon in ViTs:
135+
<https://arxiv.org/abs/2605.24770>
136+
137+
## 3. One-head nanoGPT / FineWeb-Edu
138+
139+
### Data
140+
141+
This is not a Tiny Shakespeare demonstration. The preparation script streams a
142+
pinned revision of:
143+
144+
```text
145+
HuggingFaceFW/fineweb-edu
146+
configuration: sample-10BT
147+
revision: 593b3a867298afb8ce42625a270ef20ddcad28f9
148+
```
149+
150+
It creates exact, document-disjoint splits:
151+
152+
```text
153+
train: 10,000,000 tokens
154+
validation: 1,000,000 tokens
155+
test: 1,000,000 tokens
156+
```
157+
158+
The GPT-2 BPE tokenizer is retained deliberately for comparability and simple
159+
decoding of continuation BLEU. The 50,257-token embedding is large relative to
160+
a one-block transformer; therefore parameter-count scaling claims must exclude
161+
or separately report embedding parameters. This does not invalidate the
162+
optimizer control because Muon is applied only to the six hidden transformer
163+
matrices and every arm shares the identical embedding.
164+
165+
### Accepted optimizer recipes
166+
167+
The committed recipes are already aligned with the primary references:
168+
169+
| Optimizer | Peak LR | Floor | Warm-up |
170+
|---|---:|---:|---:|
171+
| SGD + Nesterov | 0.05 | 0.005 | 10% |
172+
| AdamW | 6e-4 | 6e-5 | 1% |
173+
| Muon matrices | 0.02 | 0.002 | 5% |
174+
| Muon auxiliary AdamW | 3e-4 | 3e-5 | 5% |
175+
176+
AdamW uses `(0.9, 0.95)` betas, weight decay `0.1`, gradient clipping at `1.0`,
177+
and nanoGPT initialization. Muon uses the reference hidden-matrix partition,
178+
momentum `0.95`, Nesterov, five Newton-Schulz steps, and auxiliary AdamW.
179+
180+
The run is restartable and uses validation loss for best-checkpoint selection.
181+
The test set is monitoring-only.
182+
183+
Primary references:
184+
185+
- nanoGPT: <https://github.com/karpathy/nanoGPT>
186+
- Muon: <https://github.com/KellerJordan/Muon>
187+
188+
## 4. nanochat d12
189+
190+
The d12 control is intentionally different from the home-computer one-head
191+
baseline. It is the **native upstream nanochat reference**, pinned to:
192+
193+
```text
194+
92d63d4e8bb4df75c3b71618f31ddde2378b2bcd
195+
```
196+
197+
The wrapper does not replace upstream architecture or optimization logic. It
198+
preserves:
199+
200+
```text
201+
depth: 12
202+
width: 768
203+
context: 2048
204+
target data ratio: 12 tokens per scaling parameter
205+
embedding LR: 0.30
206+
unembedding LR: 0.008
207+
matrix LR: 0.020
208+
scalar LR: 0.50
209+
cautious Muon weight decay: 0.28
210+
warm-up: 40 steps
211+
warmdown: final 65% of training
212+
final LR fraction: 0.05
213+
```
214+
215+
This recipe is accepted because nanochat performs its own depth/batch transfer,
216+
parameter grouping, initialization, LR/momentum/weight-decay scheduling, data
217+
packing, and tokenizer preparation. Updating the pinned nanochat commit creates
218+
a new baseline version and requires a new audit.
219+
220+
Primary reference: <https://github.com/karpathy/nanochat>
221+
222+
## WeightWatcher contract
223+
224+
Every baseline that runs in this repository must preserve the raw output of:
225+
226+
```python
227+
watcher.analyze(
228+
ERG=True,
229+
randomize=True,
230+
...
231+
)
232+
```
233+
234+
The baseline must not invent a fallback `alpha`, proxy `num_traps`, or
235+
synthesized `ERG_gap`. Missing or unsupported required measurements fail
236+
visibly in strict reference runs. WeightWatcher analysis may run on CPU copies
237+
to keep unsupported SVD/RMT operations off Apple MPS.
238+
239+
## What “optimized” means here
240+
241+
The committed defaults are now source-backed, internally consistent reference
242+
recipes. They still require actual target-hardware runs before any performance
243+
claim. A genuine hyperparameter optimum is empirical and must be selected on
244+
validation data with a preregistered search; it cannot be inferred solely from
245+
literature defaults. The test set remains untouched by that search.

0 commit comments

Comments
 (0)