Research archive

Synchronous 20M tuning at 128K tokens per batch

Archived reference. Read the current results →

Historical report; retained as an experimental record.

Historical report. Settings and conclusions describe the recorded experiment. See the current documentation for maintained guidance.

Measured on 2026-09-11: all 72 runs completed and passed the configuration, token-budget, full-validation, and final-checkpoint audit. The winning recipe is now the synchronous preset in configs/20m.yaml: LR 0.0056, AdamW beta2 0.98, batch 131,072 tokens, microbatch 128. At context length 1,024, each full update uses one microbatch, without gradient accumulation. Packed presets are unchanged.

Results

Selection minimizes mean final-checkpoint full C4 validation cross-entropy over runtime seeds 42, 43, and 44, breaking exact ties by lower LR, then lower beta2. Error bars and ± values are the sample standard deviation across seeds, not confidence intervals.

Learning-rate sweep with beta2 curves and seed variation

The left panel includes every LR/beta2 combination. The right panel shows the same statistics for learning rates up to 0.0056 on a narrower loss scale. The star marks the selected recipe. Download the PDF or PNG.

RankLearning rateBeta2Mean loss (nats)Sample SD
10.00560.983.5586890.004887
20.00400.983.5628370.004298
30.00560.953.5656630.002401
40.00400.953.5690910.003603
50.00400.9993.5762060.002682

The winner lies inside the tested LR and beta2 ranges. Its 0.004148-nat advantage over LR 0.0040 at the same beta2 is comparable to the observed seed variation; this ranking alone does not establish a statistically reliable improvement. Higher LRs generally worsen loss and can increase seed variation. Those poor outcomes are retained in the results; all runs completed with finite losses.

The earlier 32K-token synchronous winner measured 3.564370 ± 0.003590 at LR 0.0028 and beta2 0.999. The new winner is lower by 0.005681 nats, but this compares separately tuned campaigns, not an isolated batch-size experiment. Both campaigns use validation for selection, with no independent test estimate. These results establish the best tested recipe in this grid, not batch-size optimality.

Search and fixed protocol

SettingValue
Learning rates0.0014, 0.0028, 0.0040, 0.0056, 0.0080, 0.0112, 0.0160, 0.0224
Beta20.95, 0.98, 0.999
Runtime seeds42, 43, 44
Model20,403,520 unique parameters; 8 layers, width 320, 5 heads, FFN width 896
Vocabulary / context32,000 / 1,024
Batch / microbatch131,072 prediction targets / 128 sequences; no accumulation
Training budget408,071,168 targets; 40 virtual epochs; 3,120 optimizer updates
Other AdamW settingsBeta1 0.9, epsilon 1e-8, weight decay 0.1, gradient clipping 1.0
Schedule5% token-based linear warmup, cosine decay to 10% of peak LR
Epoch validationFixed 1,024-block subset, validation seed 12345
Final validationFull C4 split: 197,411,295 prediction targets per run
ExecutionBF16 autocast, FP32 parameters, compiled SDPA, fused AdamW, 8 CPU threads
CheckpointsFinal only: one final.pt per run

Epoch-ending updates are shortened to preserve the existing virtual epoch boundaries and exact training budget; they use their actual target counts. The schedule follows consumed tokens. Dataset preprocessing shuffle seed 42 and validation seed 12345 stay fixed while the runtime seed varies. deterministic=false allows fast kernels and does not promise bitwise replay.

Each run used one NVIDIA GH200 120GB, Python 3.12.13, PyTorch 2.14.0, and CUDA 13.0. The full-budget pilot was job 2309169_0; the remaining runs were array 2309171, capped at 24 concurrent GPUs with a 30-minute limit per allocation. All jobs exited successfully, including the slower 2309171_59. The cancelled microbatch-32 pilot and its dependent array are excluded.

Artifacts and reproduction

  • Per-run CSV: all 72 losses, seeds, job IDs, durations, and archive-relative run directories.
  • Summary CSV: all 24 combinations, sorted by mean loss, with three seeds and sample SD for each.
  • Results and provenance: audited run metrics, grouped results, source hashes, cache identity, and environment.
  • Plot script: regenerates the figure from the adjacent summary CSV, without needing the large training archive.

The preset matches the measured winner, including pinned C4 and tokenizer revisions, with portable data/c4 and runs/20m paths. After preparing the cache as described in the README, reproduce a seed with:

uv run tiny-llm train --config configs/20m.yaml \
  --set runtime.seed=42 --set runtime.output_dir=runs/20m-128k-seed42

Repeat with seeds 43 and 44 in separate output directories for the three-seed comparison. Regenerate the plot from the repository root with:

uv run python doc/data/recipe_sweep_20m_128k/plot.py

The gitignored archive runs/sync-20m-batch128k-micro128-20260911/ retains the sweep scripts, frozen trainer, all 72 configs, logs, and checkpoints. Its source commit is 12dea70ca74a31f368d13e88267377a7198bb0b1; cache identity is 8cf0c4883c19d26f378623f91bfe079bc8ebf8f23e51814821f4c8c28c4b8151. The preset update does not alter those archived recipes or results.

View Markdown source ↗
Search current documentation

Historical reports are available in the archive.