Reproducing the training set¶
None of this is needed to use emu_pk — the trained weights and the
correction table ship inside the package. It is here so the result is
reproducible, and because a reader who wants to retrain on a different box
needs the same machinery.
The short version¶
pip install 'emu_pk[gen,train]'
# One shard of CLASS solves. The design is regenerated from the seed, so a
# shard is reproducible from its indices alone.
python -m emu_pk.generate --mode emu --shard 0 --n-per-shard 100 \
--n-total 150000 --out shards
# ... many shards later ...
python -m emu_pk.assemble --mode emu --shards shards --out training_set.npz
python -m emu_pk.train --dataset training_set.npz --out weights.npz
python -m emu_pk.validate --weights weights.npz --json validation.json
What it costs¶
Measured, not estimated:
CLASS solves in the design |
150 000 |
seconds per solve, production settings |
~6.5 |
core-hours |
~271 |
training rows (31 redshifts per solve) |
~4.6 million |
training, 240 epochs on 32 CPU cores |
~2.5 hours |
assembled training set on disk |
~9 GB |
Generation is embarrassingly parallel across shards and is the only part that needs a cluster. Training is a 4×512 network and fits comfortably on a CPU node; a GPU is not required.
The properties that make it restartable¶
Three, and every one of them is load-bearing on a preemptible queue:
A shard skips if its output exists, so a killed job re-runs and costs only the work it had not finished.
Shards write every 50 cosmologies, not at the end, so a kill loses minutes rather than hours.
Training checkpoints every epoch, including the optimiser state and the learning-rate schedule’s position, so a preempted run resumes where it was rather than reinitialising Adam and rewinding the schedule to its peak.
Where CLASS refuses¶
About 0.02 % of solves fail, all CosmoComputationError out of
perturbations_solve, and they are not scattered: they sit in the corner where
w0 is near \(-0.5\) and wa is positive, so w(a) climbs toward zero at early
times and dark energy behaves like matter before recombination.
assemble.build_training_set reports the missing design indices rather than
filling them. A training set with silent gaps trains perfectly well and is
wrong exactly where CLASS refused, which is the part of the box a forecast is
most likely to wander into.
Reproducibility and the solver version¶
Everything here is reproducible from a seed and an index given the same CLASS
version. CLASS changes; its precision settings and its pk_lin interpolation
change with it, so two runs of the commands above against different classy
builds are not guaranteed to agree at the accuracy this package is scored at.
The shipped weights were trained against CLASS v3.3.4. That version is not
stamped into the .npz files, so it cannot be recovered from them: if you
regenerate, record the classy version alongside your own weights. It is the
one input to this pipeline that a seed and an index do not capture.
Cluster scripts¶
The oarsub/ directory in the repository holds the job scripts used on the
GRICAD clusters (OAR resource manager). They are site-specific and will not
transfer unchanged, but they document the structure of a production run — gate
on a measured solve rate before sizing anything, run a --devel smoke before
committing array elements, and keep every step restartable.