Alfredvc commited on
Commit
38550e5
·
verified ·
1 Parent(s): 3efe887

Add files using upload-large-folder tool

Browse files
README.md CHANGED
@@ -132,107 +132,6 @@ branch final at `T`, LR at zero).
132
  | 150,000 | 30.7B | 55.03 | **56.88** | +1.86 | 1.3031 | `700m/trunk/checkpoint-000120000.pt` | `700m/anneal/T150000/checkpoint-000149999.pt` |
133
  | 300,000 | 61.4B | 55.29 | **57.15** | +1.86 | 1.2917 | `700m/trunk/checkpoint-000240000.pt` | `700m/anneal/T300000/checkpoint-000299999.pt` |
134
 
135
- ## Training curves
136
-
137
- The tables above give endpoints. `training-curves/` holds the runs behind them: every
138
- metric the training loop logged, for all 18 runs in this repo, as plain CSV.
139
- Nothing in the files is downsampled or smoothed, and the smoothing below happens only in
140
- the plots.
141
-
142
- ![Validation loss over training](figures/training-loss.png)
143
-
144
- Each anneal branch resumes its trunk at `0.8·T` and decays the LR to zero. Every endpoint
145
- in the next plot is a checkpoint you can download:
146
-
147
- ![Anneal branches leaving the trunk](figures/training-anneal.png)
148
-
149
- All three sizes run the same LR schedule, with Muon 5× hotter than AdamW. Below that, the
150
- gradient norms that schedule produces:
151
-
152
- ![Learning-rate schedule](figures/training-lr.png)
153
-
154
- ![Gradient norm before clipping](figures/training-grad-norm.png)
155
-
156
- Throughput on one `1x NVIDIA H100 NVL`. The wall-clock section below rests on these measurements.
157
- Bigger models use more of the GPU per step, so ranking the sizes by time and by FLOPs
158
- gives different answers:
159
-
160
- ![Training throughput](figures/training-throughput.png)
161
-
162
- ### What is in the CSVs
163
-
164
- Two logging cadences share one table: eval metrics every `eval_interval` steps, the rest
165
- every `log_interval` steps (500 and 100 for these runs). A cell is empty where the run
166
- logged nothing for that metric at that step, so read every column against `step` rather
167
- than against a row index.
168
-
169
- | column | cadence | meaning |
170
- | --- | --- | --- |
171
- | `step` | every logged step | optimizer step, absolute (a branch starts at 0.8·T) |
172
- | `tokens` | derived | `step × tokens_per_step`, the x-axis of every card curve |
173
- | `wall_clock_s` | every logged step | seconds since the run started |
174
- | `train_loss` | eval | next-token NLL on a held-out slice of the training shards |
175
- | `val_loss` | eval | next-token NLL on the held-out validation shard |
176
- | `valid_prob_mass` | eval | probability mass the model puts on legal moves |
177
- | `game_end_accuracy` | eval | accuracy on the game-terminating token |
178
- | `game_end_top1_accuracy` | eval | top-1 accuracy on the game-terminating token |
179
- | `batch_train_loss` | log | loss on the current microbatch, noisy by construction |
180
- | `lr` | log | AdamW learning rate |
181
- | `muon_lr` | log | Muon learning rate |
182
- | `unclipped_grad_norm` | log | ‖g‖ *before* `grad_clip = 1.0` is applied |
183
- | `tokens_per_second` | log | instantaneous, from the last iteration's duration |
184
- | `avg_tokens_per_second` | log | averaged over the interval since the last log |
185
- | `samples_per_second` | log | sequences/s, i.e. `tokens_per_second / 200` |
186
- | `t_flops` | log | the run's own FLOP/s estimate (TiFLOP/s, 1024⁴ scaling) |
187
- | `shard_idx` | log | index into `data_config.shards`, the dataset cursor |
188
- | `shard_sample_idx` | log | position within that shard |
189
-
190
- `step` is absolute. An anneal branch's history starts at `0.8·T` rather than at 0, because
191
- it continues its trunk.
192
-
193
- | run | steps logged | step range | tokens at the end | history |
194
- | --- | --- | --- | --- | --- |
195
- | 91M trunk | 6,001 | 0 → 600,000 | 122.9B | `training-curves/91m/trunk.csv` |
196
- | 91M anneal T=18,750 | 38 | 15,100 → 18,750 | 3.8B | `training-curves/91m/anneal-T018750.csv` |
197
- | 91M anneal T=37,500 | 75 | 30,100 → 37,500 | 7.7B | `training-curves/91m/anneal-T037500.csv` |
198
- | 91M anneal T=75,000 | 150 | 60,100 → 75,000 | 15.4B | `training-curves/91m/anneal-T075000.csv` |
199
- | 91M anneal T=150,000 | 300 | 120,100 → 150,000 | 30.7B | `training-curves/91m/anneal-T150000.csv` |
200
- | 91M anneal T=300,000 | 600 | 240,100 → 300,000 | 61.4B | `training-curves/91m/anneal-T300000.csv` |
201
- | 350M trunk | 6,001 | 0 → 600,000 | 122.9B | `training-curves/350m/trunk.csv` |
202
- | 350M anneal T=18,750 | 38 | 15,100 → 18,750 | 3.8B | `training-curves/350m/anneal-T018750.csv` |
203
- | 350M anneal T=37,500 | 75 | 30,100 → 37,500 | 7.7B | `training-curves/350m/anneal-T037500.csv` |
204
- | 350M anneal T=75,000 | 150 | 60,100 → 75,000 | 15.4B | `training-curves/350m/anneal-T075000.csv` |
205
- | 350M anneal T=150,000 | 300 | 120,100 → 150,000 | 30.7B | `training-curves/350m/anneal-T150000.csv` |
206
- | 350M anneal T=300,000 | 600 | 240,100 → 300,000 | 61.4B | `training-curves/350m/anneal-T300000.csv` |
207
- | 700M trunk | 5,204 | 0 → 520,400 | 106.6B | `training-curves/700m/trunk.csv` |
208
- | 700M anneal T=18,750 | 38 | 15,100 → 18,750 | 3.8B | `training-curves/700m/anneal-T018750.csv` |
209
- | 700M anneal T=37,500 | 75 | 30,100 → 37,500 | 7.7B | `training-curves/700m/anneal-T037500.csv` |
210
- | 700M anneal T=75,000 | 150 | 60,100 → 75,000 | 15.4B | `training-curves/700m/anneal-T075000.csv` |
211
- | 700M anneal T=150,000 | 300 | 120,100 → 150,000 | 30.7B | `training-curves/700m/anneal-T150000.csv` |
212
- | 700M anneal T=300,000 | 600 | 240,100 → 300,000 | 61.4B | `training-curves/700m/anneal-T300000.csv` |
213
-
214
- ### Load them into your own W&B
215
-
216
- `training-curves/replay_to_wandb.py` loads these CSVs into your own W&B project, so you
217
- can plot your run against ours on the same axes. It needs `wandb` and nothing else:
218
-
219
- ```bash
220
- pip install wandb
221
- python training-curves/replay_to_wandb.py --project my-project
222
-
223
- # or just the runs you want ("91m" means every 91M run)
224
- python training-curves/replay_to_wandb.py --project my-project --runs 91m/trunk 350m/anneal-T300000
225
-
226
- # log locally now, upload whenever
227
- WANDB_MODE=offline python training-curves/replay_to_wandb.py --project my-project
228
- wandb sync --sync-all
229
- ```
230
-
231
- The script keeps the original step numbers and loads each run's `config.json` as its W&B
232
- config, so the run-comparison filters work the way they do on a run you trained yourself.
233
- It logs `tokens` as a metric too; pick that as the x-axis to compare by data seen rather
234
- than by step.
235
-
236
  ## Architecture
237
 
238
  All three share one decoder-only transformer: discrete move-token embedding,
@@ -418,6 +317,107 @@ The full training corpus is at
418
  sets (the Allie/Maia benchmark test data) are at
419
  [`Alfredvc/chess-autocomplete-eval-datasets`](https://huggingface.co/datasets/Alfredvc/chess-autocomplete-eval-datasets).
420
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  ## License
422
 
423
  apache-2.0. The Lichess data is CC0.
 
132
  | 150,000 | 30.7B | 55.03 | **56.88** | +1.86 | 1.3031 | `700m/trunk/checkpoint-000120000.pt` | `700m/anneal/T150000/checkpoint-000149999.pt` |
133
  | 300,000 | 61.4B | 55.29 | **57.15** | +1.86 | 1.2917 | `700m/trunk/checkpoint-000240000.pt` | `700m/anneal/T300000/checkpoint-000299999.pt` |
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  ## Architecture
136
 
137
  All three share one decoder-only transformer: discrete move-token embedding,
 
317
  sets (the Allie/Maia benchmark test data) are at
318
  [`Alfredvc/chess-autocomplete-eval-datasets`](https://huggingface.co/datasets/Alfredvc/chess-autocomplete-eval-datasets).
319
 
320
+ ## Training curves
321
+
322
+ The tables above give endpoints. `training-curves/` holds the runs behind them: every
323
+ metric the training loop logged, for all 18 runs in this repo, as plain CSV.
324
+ Nothing in the files is downsampled or smoothed, and the smoothing below happens only in
325
+ the plots.
326
+
327
+ ![Validation loss over training](figures/training-loss.png)
328
+
329
+ Each anneal branch resumes its trunk at `0.8·T` and decays the LR to zero. Every endpoint
330
+ in the next plot is a checkpoint you can download:
331
+
332
+ ![Anneal branches leaving the trunk](figures/training-anneal.png)
333
+
334
+ All three sizes run the same LR schedule, with Muon 5× hotter than AdamW. Below that, the
335
+ gradient norms that schedule produces:
336
+
337
+ ![Learning-rate schedule](figures/training-lr.png)
338
+
339
+ ![Gradient norm before clipping](figures/training-grad-norm.png)
340
+
341
+ Throughput on one `1x NVIDIA H100 NVL`. The wall-clock section above rests on these measurements.
342
+ Bigger models use more of the GPU per step, so ranking the sizes by time and by FLOPs
343
+ gives different answers:
344
+
345
+ ![Training throughput](figures/training-throughput.png)
346
+
347
+ ### What is in the CSVs
348
+
349
+ Two logging cadences share one table: eval metrics every `eval_interval` steps, the rest
350
+ every `log_interval` steps (500 and 100 for these runs). A cell is empty where the run
351
+ logged nothing for that metric at that step, so read every column against `step` rather
352
+ than against a row index.
353
+
354
+ | column | cadence | meaning |
355
+ | --- | --- | --- |
356
+ | `step` | every logged step | optimizer step, absolute (a branch starts at 0.8·T) |
357
+ | `tokens` | derived | `step × tokens_per_step`, the x-axis of every card curve |
358
+ | `wall_clock_s` | every logged step | seconds since the run started |
359
+ | `train_loss` | eval | next-token NLL on a held-out slice of the training shards |
360
+ | `val_loss` | eval | next-token NLL on the held-out validation shard |
361
+ | `valid_prob_mass` | eval | probability mass the model puts on legal moves |
362
+ | `game_end_accuracy` | eval | accuracy on the game-terminating token |
363
+ | `game_end_top1_accuracy` | eval | top-1 accuracy on the game-terminating token |
364
+ | `batch_train_loss` | log | loss on the current microbatch, noisy by construction |
365
+ | `lr` | log | AdamW learning rate |
366
+ | `muon_lr` | log | Muon learning rate |
367
+ | `unclipped_grad_norm` | log | ‖g‖ *before* `grad_clip = 1.0` is applied |
368
+ | `tokens_per_second` | log | instantaneous, from the last iteration's duration |
369
+ | `avg_tokens_per_second` | log | averaged over the interval since the last log |
370
+ | `samples_per_second` | log | sequences/s, i.e. `tokens_per_second / 200` |
371
+ | `t_flops` | log | the run's own FLOP/s estimate (TiFLOP/s, 1024⁴ scaling) |
372
+ | `shard_idx` | log | index into `data_config.shards`, the dataset cursor |
373
+ | `shard_sample_idx` | log | position within that shard |
374
+
375
+ `step` is absolute. An anneal branch's history starts at `0.8·T` rather than at 0, because
376
+ it continues its trunk.
377
+
378
+ | run | steps logged | step range | tokens at the end | history |
379
+ | --- | --- | --- | --- | --- |
380
+ | 91M trunk | 6,001 | 0 → 600,000 | 122.9B | `training-curves/91m/trunk.csv` |
381
+ | 91M anneal T=18,750 | 38 | 15,100 → 18,750 | 3.8B | `training-curves/91m/anneal-T018750.csv` |
382
+ | 91M anneal T=37,500 | 75 | 30,100 → 37,500 | 7.7B | `training-curves/91m/anneal-T037500.csv` |
383
+ | 91M anneal T=75,000 | 150 | 60,100 → 75,000 | 15.4B | `training-curves/91m/anneal-T075000.csv` |
384
+ | 91M anneal T=150,000 | 300 | 120,100 → 150,000 | 30.7B | `training-curves/91m/anneal-T150000.csv` |
385
+ | 91M anneal T=300,000 | 600 | 240,100 → 300,000 | 61.4B | `training-curves/91m/anneal-T300000.csv` |
386
+ | 350M trunk | 6,001 | 0 → 600,000 | 122.9B | `training-curves/350m/trunk.csv` |
387
+ | 350M anneal T=18,750 | 38 | 15,100 → 18,750 | 3.8B | `training-curves/350m/anneal-T018750.csv` |
388
+ | 350M anneal T=37,500 | 75 | 30,100 → 37,500 | 7.7B | `training-curves/350m/anneal-T037500.csv` |
389
+ | 350M anneal T=75,000 | 150 | 60,100 → 75,000 | 15.4B | `training-curves/350m/anneal-T075000.csv` |
390
+ | 350M anneal T=150,000 | 300 | 120,100 → 150,000 | 30.7B | `training-curves/350m/anneal-T150000.csv` |
391
+ | 350M anneal T=300,000 | 600 | 240,100 → 300,000 | 61.4B | `training-curves/350m/anneal-T300000.csv` |
392
+ | 700M trunk | 5,204 | 0 → 520,400 | 106.6B | `training-curves/700m/trunk.csv` |
393
+ | 700M anneal T=18,750 | 38 | 15,100 → 18,750 | 3.8B | `training-curves/700m/anneal-T018750.csv` |
394
+ | 700M anneal T=37,500 | 75 | 30,100 → 37,500 | 7.7B | `training-curves/700m/anneal-T037500.csv` |
395
+ | 700M anneal T=75,000 | 150 | 60,100 → 75,000 | 15.4B | `training-curves/700m/anneal-T075000.csv` |
396
+ | 700M anneal T=150,000 | 300 | 120,100 → 150,000 | 30.7B | `training-curves/700m/anneal-T150000.csv` |
397
+ | 700M anneal T=300,000 | 600 | 240,100 → 300,000 | 61.4B | `training-curves/700m/anneal-T300000.csv` |
398
+
399
+ ### Load them into your own W&B
400
+
401
+ `training-curves/replay_to_wandb.py` loads these CSVs into your own W&B project, so you
402
+ can plot your run against ours on the same axes. It needs `wandb` and nothing else:
403
+
404
+ ```bash
405
+ pip install wandb
406
+ python training-curves/replay_to_wandb.py --project my-project
407
+
408
+ # or just the runs you want ("91m" means every 91M run)
409
+ python training-curves/replay_to_wandb.py --project my-project --runs 91m/trunk 350m/anneal-T300000
410
+
411
+ # log locally now, upload whenever
412
+ WANDB_MODE=offline python training-curves/replay_to_wandb.py --project my-project
413
+ wandb sync --sync-all
414
+ ```
415
+
416
+ The script keeps the original step numbers and loads each run's `config.json` as its W&B
417
+ config, so the run-comparison filters work the way they do on a run you trained yourself.
418
+ It logs `tokens` as a metric too; pick that as the x-axis to compare by data seen rather
419
+ than by step.
420
+
421
  ## License
422
 
423
  apache-2.0. The Lichess data is CC0.
figures/anneal.svg CHANGED
figures/frontier.svg CHANGED
figures/isoflop.svg CHANGED
figures/isotime.svg CHANGED
figures/projection.svg CHANGED
figures/training-anneal.svg CHANGED
figures/training-grad-norm.svg CHANGED
figures/training-loss.svg CHANGED
figures/training-lr.svg CHANGED
figures/training-throughput.svg CHANGED
index.json CHANGED
@@ -355,7 +355,7 @@
355
  {
356
  "path": "README.md",
357
  "size": 20962,
358
- "sha256": "f3f3e151b8c816f6b77374c9361475a052d26da870c322dc6efd8433bce253ac"
359
  },
360
  {
361
  "path": "figures/anneal.png",
@@ -365,7 +365,7 @@
365
  {
366
  "path": "figures/anneal.svg",
367
  "size": 61148,
368
- "sha256": "5742255e75a78c84b122d03b4135097994f0f2d4b42a0c262579b887303bd60b"
369
  },
370
  {
371
  "path": "figures/frontier.png",
@@ -375,7 +375,7 @@
375
  {
376
  "path": "figures/frontier.svg",
377
  "size": 120161,
378
- "sha256": "e1bb1ca8f8a6e1f7dee261b7d2a1f89fe7b8edbb890d49e81e940e8120ef919b"
379
  },
380
  {
381
  "path": "figures/isoflop.png",
@@ -385,7 +385,7 @@
385
  {
386
  "path": "figures/isoflop.svg",
387
  "size": 67456,
388
- "sha256": "f16ada10f6771d84ec3903a33f3b776927671518b82959d260eaedeee7db10bd"
389
  },
390
  {
391
  "path": "figures/isotime.png",
@@ -395,7 +395,7 @@
395
  {
396
  "path": "figures/isotime.svg",
397
  "size": 74233,
398
- "sha256": "63fc2cc7e41b1793939f531cbc0cd7dd002115cc546447fa20a3e313625980ab"
399
  },
400
  {
401
  "path": "figures/projection.png",
@@ -405,7 +405,7 @@
405
  {
406
  "path": "figures/projection.svg",
407
  "size": 80775,
408
- "sha256": "9aa3811a3001bb124a5b844b22bdea4dd7d5f9ef80c02e6e872c8b0a5948f999"
409
  },
410
  {
411
  "path": "figures/training-anneal.png",
@@ -415,7 +415,7 @@
415
  {
416
  "path": "figures/training-anneal.svg",
417
  "size": 179061,
418
- "sha256": "5fa7a9cf5e15c79162f0048963338c6e5cea1c2bfafca0ef12e19ca9a4e04285"
419
  },
420
  {
421
  "path": "figures/training-grad-norm.png",
@@ -425,7 +425,7 @@
425
  {
426
  "path": "figures/training-grad-norm.svg",
427
  "size": 376514,
428
- "sha256": "4de88fc608028173d293398e48dd84552377f260b12ce474208bad8951571a15"
429
  },
430
  {
431
  "path": "figures/training-loss.png",
@@ -435,7 +435,7 @@
435
  {
436
  "path": "figures/training-loss.svg",
437
  "size": 281513,
438
- "sha256": "8f1acab85d3e0d8c2da07a90680ac17b573fa844aff1ca57b5f2d875f849944f"
439
  },
440
  {
441
  "path": "figures/training-lr.png",
@@ -445,7 +445,7 @@
445
  {
446
  "path": "figures/training-lr.svg",
447
  "size": 71508,
448
- "sha256": "a4d3f6fbaa810c67a4c4568ed5bbfd02054fa51be014b580c7e6760cf752ef3b"
449
  },
450
  {
451
  "path": "figures/training-throughput.png",
@@ -455,7 +455,7 @@
455
  {
456
  "path": "figures/training-throughput.svg",
457
  "size": 191838,
458
- "sha256": "6850de57f92f576f196e68a170629bb53794501388806e887893cfd4f314ed90"
459
  },
460
  {
461
  "path": "metrics.csv",
 
355
  {
356
  "path": "README.md",
357
  "size": 20962,
358
+ "sha256": "7322ea8bfa25caf0ffc47adc42efab7d5bb3863777998a117deb3077ee74173e"
359
  },
360
  {
361
  "path": "figures/anneal.png",
 
365
  {
366
  "path": "figures/anneal.svg",
367
  "size": 61148,
368
+ "sha256": "28228bca73a0150a207b3edc7a067a549bdb43f11473acd50c685698e6876440"
369
  },
370
  {
371
  "path": "figures/frontier.png",
 
375
  {
376
  "path": "figures/frontier.svg",
377
  "size": 120161,
378
+ "sha256": "227cba68154bd02f321fe8c463c07b5ba5e3ca0c06a4b36e8097b678b2fe4ae4"
379
  },
380
  {
381
  "path": "figures/isoflop.png",
 
385
  {
386
  "path": "figures/isoflop.svg",
387
  "size": 67456,
388
+ "sha256": "ccd277749642ffe171fa9a46cea9bb301ba71fb12f650cbb638dd78d0dea34f5"
389
  },
390
  {
391
  "path": "figures/isotime.png",
 
395
  {
396
  "path": "figures/isotime.svg",
397
  "size": 74233,
398
+ "sha256": "ab1dc3b16108b76f70b77eb6a38d2ccacbc56c80aa30eb3d7ea703bb00ae2697"
399
  },
400
  {
401
  "path": "figures/projection.png",
 
405
  {
406
  "path": "figures/projection.svg",
407
  "size": 80775,
408
+ "sha256": "7f4c883a0bb175ca078b25a8e40639e6c0ae1d56a303d871222f1881756fdb74"
409
  },
410
  {
411
  "path": "figures/training-anneal.png",
 
415
  {
416
  "path": "figures/training-anneal.svg",
417
  "size": 179061,
418
+ "sha256": "aa2c3d538766b9d228826805ab65d5b70b54d10a8de7075e26e0cd7a9aa1a5c3"
419
  },
420
  {
421
  "path": "figures/training-grad-norm.png",
 
425
  {
426
  "path": "figures/training-grad-norm.svg",
427
  "size": 376514,
428
+ "sha256": "5a88ae0b23704a40488749c2cb23906d652ec488a3e23953aaf0e534f5d9ae60"
429
  },
430
  {
431
  "path": "figures/training-loss.png",
 
435
  {
436
  "path": "figures/training-loss.svg",
437
  "size": 281513,
438
+ "sha256": "a8ae3a3f55259ad6b37dc5024e0a098832f6ed3ebb54aea0908cb3fe9ed8a8c9"
439
  },
440
  {
441
  "path": "figures/training-lr.png",
 
445
  {
446
  "path": "figures/training-lr.svg",
447
  "size": 71508,
448
+ "sha256": "bd0d3ce0a2dd6eb9c266bf6d1db51ae34b3bd864949ed8833016a806b4d6b721"
449
  },
450
  {
451
  "path": "figures/training-throughput.png",
 
455
  {
456
  "path": "figures/training-throughput.svg",
457
  "size": 191838,
458
+ "sha256": "d88ce4a668b8708c61b66a8810e613614881f3213a6ea0f41cc7980aaefa1fe6"
459
  },
460
  {
461
  "path": "metrics.csv",