Training Intelligence

v0.25.0 added config options for two training-time subsystems: catastrophic forgetting detection and checkpoint intelligence. The forgetting signal later became leg 2 of soup ship's SHIP / DON'T-SHIP verdict.

Status at v0.76.0: these options are accepted by the schema, but nothing in v0.76.0 reads them during training. Setting forgetting_detection, checkpoint_intelligence, early_stop_on_regression or convergence_detection does not start a forgetting probe, a checkpoint-quality eval or an early stop. soup train prints a yellow note saying they are "set but not enforced during training in this build" and points at the live alternatives: soup train --gate <suite.yaml> (eval-gated training), soup eval or soup diagnose after training, and soup ship. The sections below describe what the options are meant to do, so you can read an existing config; they are not a description of what a run does today.

New in v0.76.0: ten of the tunables warn at load, and upstream says it will refuse them from v0.77. Set one to a value other than its schema default and the loader prints Warning: training.<name> is accepted but read by nothing; v0.77 will refuse it and carries on (exit 0). A field left at its default is silent. Upstream states the v0.77 deadline in that message and pins it with a test; delete the key to keep a config loading once that release arrives. The list is in the table below.

What is wired and what is not

OptionAt v0.76.0
forgetting_detection, checkpoint_intelligence, early_stop_on_regression, convergence_detectionAccepted by the schema, and not warned about at load. soup train reads them only to print the "not enforced" note above. soup autopilot stopped writing the first three in v0.76.0 (it wrote them as true until v0.75.2), so a config it generated earlier still carries them.
forgetting_thresholdAccepted by the schema, but nothing in v0.76.0 reads it. A non-default value is named in the same soup train note, and gets no load-time deadline warning. It is training.forgetting_threshold, not the eval.ship.forgetting_threshold that soup ship reads, which is live.
forgetting_eval_steps, forgetting_benchmark, forgetting_stopAccepted by the schema, but nothing in v0.76.0 reads them. A non-default value warns at load (v0.77 will refuse it, per upstream).
checkpoint_eval_steps, checkpoint_eval_metric, checkpoint_eval_tasks, checkpoint_keep_top, early_stop_patienceAccepted by the schema, but nothing in v0.76.0 reads them during training. A non-default value warns at load (v0.77 will refuse it, per upstream).
convergence_window, convergence_rel_tolAccepted by the schema, but nothing in v0.76.0 reads them. A non-default value warns at load (v0.77 will refuse it, per upstream).
The mini benchmarks (mini_mmlu, mini_common_sense, mini_instruction)Live, but not as a training-time probe: they score leg 2 of soup ship after training, and the type: benchmark tasks of an eval gate at epoch boundaries.
training.eval_gate / soup train --gateLive during training: runs the gate suite at epoch boundaries and can stop the run.

Catastrophic forgetting detection (accepted, not enforced)

The design: run a mini benchmark on the base model before training, repeat it every N steps on the current checkpoint, and warn, or stop, when general-knowledge accuracy drops more than a threshold. None of that happens during soup train at v0.76.0. The same measurement does run as a gate: against a finished model in soup ship and soup eval gate, and at epoch boundaries when your --gate suite includes a type: benchmark task.

Forgetting-detection config (accepted, not enforced)

yaml
training:
  forgetting_detection: true
  forgetting_eval_steps: 100
  forgetting_threshold: 0.10       # warn if accuracy drops >10%
  forgetting_benchmark: mini_mmlu  # mini_mmlu | mini_common_sense | mini_instruction
  forgetting_stop: false           # auto-stop on severe forgetting

Built-in benchmarks

Each is a hand-authored set embedded in the source, no external downloads: 26 items in mini_mmlu, 40 in mini_common_sense (24 before v0.76.0) and 24 in mini_instruction. soup ship and soup eval gate also bundle mini_arithmetic (40), mini_tool_call, mini_format_json, mini_safety and mini_over_refusal (40 each); they are not valid values of forgetting_benchmark. The sets are small on purpose: each has more than 20 items, so one flipped item moves a score by 0.025 to 0.042, which is visible instead of rounded away, but it takes more than one flipped item to reach the default 0.05 threshold. They are worth reading before you reason about what a delta means.

  • mini_mmlu — diverse MMLU coverage (STEM / humanities / social sciences)
  • mini_common_sense — common-sense reasoning
  • mini_instruction — instruction-following quality

Checkpoint intelligence (accepted, not enforced)

HF Trainer's "best checkpoint" is the one with lowest loss. But lower loss does not mean a better model: overfitted checkpoints hit low loss with bad real-world quality. Checkpoint intelligence is meant to run a quality eval during training and tag a best_quality checkpoint separately from best_loss. At v0.76.0 it does not. No code in soup train scores or ranks checkpoints, and the string best_quality appears nowhere in the source. To compare checkpoints by quality today, run soup eval or an eval gate on each one.

Checkpoint-intelligence config (accepted, not enforced)

yaml
training:
  checkpoint_intelligence: true
  checkpoint_eval_steps: 200
  checkpoint_eval_metric: composite   # judge | mmlu | custom | composite
  checkpoint_eval_tasks: eval.jsonl   # optional custom eval
  checkpoint_keep_top: 3              # delete the rest
  early_stop_on_regression: true
  early_stop_patience: 2

The design called for a dashboard block like the one below and, after training, a best_quality checkpoint linked at ./output/best_quality/. The live dashboard prints neither, and no run creates that link.

Epoch 2/3 ████████ loss: 0.89  step 450/720
  → Loss best:     step-450 (loss 0.89)
  → Quality best:  step-300 (judge 8.2/10) ⭐
  → Gen knowledge: 91.2% (baseline 95.0%, -3.8% ⚠)
  → Last eval:     +0.4 judge points (improving)

Storage (tables exist, nothing writes to them)

The experiment tracker (~/.soup/experiments.db) creates two tables for these subsystems:

  • checkpoint_quality(run_id, step, metric, score, is_best, created_at)
  • forgetting_eval(run_id, step, benchmark, accuracy, baseline, delta, warning_level)

At v0.76.0 no code inserts into either, so they stay empty.

Safety

  • Benchmark data is embedded in code — no external file loading at runtime.
  • The schema bounds the eval intervals, and the two floors differ: forgetting_eval_steps is 10 to 10,000 (default 100), checkpoint_eval_steps is 50 to 10,000 (default 200). A value of 20 is inside one range and refused by the other (checked at v0.76.0: checkpoint_eval_steps: 20 fails with Input should be greater than or equal to 50). The bounds are checked at config load even though nothing reads the values afterwards.

Defaults

Until v0.75.2 soup autopilot wrote forgetting_detection: true, checkpoint_intelligence: true and early_stop_on_regression: true into the config it generated, and soup train then reported them as not enforced. Since v0.76.0 it no longer writes or advertises them, because nothing enforces them (#927); a config it generated earlier keeps them, and keeps printing the note. All four parent switches default to false. For protection that runs during training, use --gate (see eval-gated training).

Soup is free and Apache-2.0. If it saved you a training run, starring the repo costs nothing and helps most. You can also fund the GPU time behind the work a 4 GB laptop cannot reach.