mixle.models.eval_harness module¶
General-capability eval harness: per-checkpoint receipts + regression tracking across a checkpoint sequence.
Roadmap F10. Mirrors the .report()-style receipt convention of
mixle.utils.parallel.training_health.TrainingHealthMonitor (F4) and
mixle.evolve.population.OperatorBandit / GenerationReport: no I/O, pure in-process accounting,
JSON-serializable output.
The eval suite is a small, honest SYNTHETIC proxy, not a real published benchmark. It does not claim to
measure MMLU-style world knowledge or HellaSwag-style commonsense; it measures four narrow, well-defined
capability axes a decoder-only mixle.models.transformer.CausalLM can plausibly discriminate on at
toy scale, each generated from a fixed, seedable procedure so scores are exactly reproducible and comparable
across checkpoints:
held-out perplexity – cross-entropy against sequences drawn from a fixed order-1 Markov chain over the model’s vocabulary (a stand-in for “does the model fit a held-out next-token distribution”, not any particular pretraining corpus).
modular-arithmetic reasoning –
a + b = ?under a small modulus, a single next-token prediction; a minimal, unambiguous proxy for symbolic/algorithmic reasoning.parity (counting) reasoning – the XOR parity of a random bitstring, a second algorithmic axis deliberately orthogonal to arithmetic (it requires tracking a running count, not a lookup table).
in-context induction – a synthetic induction-head probe (
... A B ... A -> ?, correct answerB): plant a bigram once in the context, then ask the model to complete it after seeing the first token again. This is the standard synthetic proxy for in-context learning (Olsson et al.’s induction heads).
One command per checkpoint (F10’s acceptance bar): evaluate_checkpoint() takes a model and returns a
complete EvalReport – no multi-step manual orchestration.
Regression tracking across rungs and across the J2 compression ladder: track_regression() takes a
sequence of EvalReport (successive training rungs, or successive steps of a not-yet-built J2
checkpoint-to-family compression ladder – e.g. one report per rung of mixle.models.qat /
mixle.task.quantize.quantize_mlp() applied progressively) and flags any metric that moved measurably
worse than its best-so-far value, beyond a stated relative threshold.
Integration points for later roadmap items (neither is required to exist for F10 to be useful today):
E7 (long-context referee) – a not-yet-built long-context judge would slot in as one more task in
_TASKS(or a second harness whoseEvalReportmerges into this one viaEvalReport.tasks); nothing here assumes a fixed task count.EvalReport.metadatais free-form so a referee verdict can ride alongside these four scores without a schema change.J2 (compression ladder) –
track_regression()takes an arbitrary ordered sequence of reports, so a ladder of checkpoints (fp32 -> QAT int8 -> QAT int4, or successive distillation students) is scored by callingevaluate_checkpoint()once per rung and handing the list straight totrack_regression(); thecheckpoint_idon each report is exactly the label J2 would assign to a ladder rung.
- class TaskResult(name, score, higher_is_better, n_examples, details=<factory>)[source]
Bases:
objectOne capability-axis score: a name, a scalar, and which direction is “better” for regression math.
- class EvalReport(checkpoint_id, tasks, seed, metadata=<factory>)[source]
Bases:
objectThe per-rung receipt: every task’s score for one checkpoint, JSON-serializable via
report().
- class RegressionFlag(task, checkpoint_id, checkpoint_index, current_score, reference_score, reference_checkpoint_id, reference_index, relative_delta, threshold)[source]
Bases:
objectOne metric that regressed beyond
thresholdrelative to its best-so-far value in the sequence.
- class RegressionReport(flags, n_checkpoints, threshold, reference)[source]
Bases:
objectThe regression-tracking receipt over an ordered sequence of
EvalReport.
- evaluate_checkpoint(model, *, checkpoint_id='checkpoint', seed=0, n_examples=256, metadata=None)[source]
Run the full synthetic capability suite on
modeland return one structuredEvalReport.modelis a real (or toy)mixle.models.transformer.CausalLM– anything exposing.vocab,.block, and__call__(x) -> (batch, vocab)next-token logits works. This is the single entry point: no separate setup per task, no manual orchestration – the “one command per checkpoint” F10 asks for.
- track_regression(reports, *, threshold=0.05, reference='best')[source]
Flag metrics that regressed by more than
threshold(relative) across a sequence of checkpoints.reportsis an ordered sequence – successive training rungs, or successive steps of a J2 compression ladder. For each task, each report (from the second onward) is compared against either the best score seen so far in the sequence (reference="best", the default – catches slow drift, not just one-step drops) or the immediately-prior report (reference="prior"– catches only step-to-step drops). A task is flagged when it moved worse than the reference by more thanthresholdas a fraction of the reference’s magnitude, direction-aware (a drop for accuracy-like metrics, a rise for perplexity-like metrics).
- markov_transition_matrix(vocab)[source]
The fixed order-1 Markov chain the perplexity task scores against.
Keyed only on
vocab(via a module-level constant seed), not on the caller’s sampleseed– the benchmark distribution is a fixed property of the eval suite (like a real held-out benchmark), while the per-callseedonly controls which samples from it are drawn for a given run. This is what lets a training loop legitimately learn this chain (it is a fixed, nameable distribution) while individual eval runs still draw fresh, unseen sequences from it.