Tracker & Eval Pro (v0.43.0)

--tracker allowlist

Closed allowlist: wandb | tensorboard | mlflow | swanlab | trackio | none.

bash
soup train --tracker mlflow

Mutually exclusive with legacy --wandb / --tensorboard via resolve_report_to.

Telemetry: opt-in, hardware-only, and still sending nothing

v0.43.0 landed a telemetry schema and the environment variables that would configure it, and for many releases that was all there was: the primitives existed and no command called them. v0.75.0 wired it, together with the public privacy policy that had been the stated precondition.

Three things have to be true before a byte leaves your machine, and as shipped the third one is false.

1. You have to opt in. It is off unless SOUP_TELEMETRY=1 (or true, yes, on). Unset, or set to anything else including 0, means no payload is built and the disk is never touched.

2. You can turn it off per invocation. --no-telemetry is an option of the root soup command, so it goes before the subcommand: soup --no-telemetry train --config soup.yaml. After the subcommand it is refused with No such option '--no-telemetry' and exit code 2; upstream's telemetry document prints it after the subcommand (soup train --config soup.yaml --no-telemetry), which does not work. It overrides the environment variable. It is checked twice, once as the parsed option and once as a raw scan of argv, so it still holds if callback parsing never ran.

3. The bundled project key is a placeholder, and the code refuses it. The key compiled into the wheel is phc_soup_public_write_only, which the sender tests for by name. On a match it writes Notice: telemetry is not yet live. to stderr and returns without opening a socket. So the shipped binary transmits nothing even for a user who opted in. An operator who wants their own collection sets SOUP_POSTHOG_KEY and SOUP_POSTHOG_ENDPOINT together, and that endpoint must be HTTPS and must pass the same SSRF policy the rest of the CLI uses.

What the payload would carry, if all three held, is seven fields and nothing else:

text
soup_version       the running version
command            the top-level command, checked against the registered
                   command list and masked to "(unknown)" otherwise
python             major.minor only
os                 platform.system()
arch               platform.machine()
duration_seconds   how long the command took
distinct_id        a random UUID4 generated locally, stored at
                   ~/.soup/telemetry_id purely to deduplicate events

The published policy also states what is never collected: dataset paths or contents, model names or architectures, config contents or hyperparameters, usernames or local paths, IP addresses, tokens or credentials. Delete ~/.soup/telemetry_id and a new one is generated on the next opt-in. The upload is a fire-and-forget HTTPS POST at command exit with a one-second connect and read timeout, and every network and filesystem exception is swallowed, so telemetry cannot fail or delay a run.

The authoritative text is upstream's own privacy policy, a section of the backends and ops document rather than a separate file, plus the network-egress section of SECURITY.md.

NLG metrics

Pure-Python BLEU + ROUGE-1/2/L + effective_tokens_per_second. Closed allowlist NLG_METRICS = frozenset({"bleu","rouge_1","rouge_2","rouge_l"}).

KL-divergence calibration (library only, no CLI)

soup_cli.eval.calibrate.run_calibration(baseline_logits, quantized_logits) compares next-token logits from a full-precision and a quantized model over a small fixed prompt set. You load both models and collect one logit row per prompt yourself; the function is pure math and takes at most 10,000 prompts. A mean KL below 0.05 is OK, below 0.20 is MINOR, and 0.20 or more is MAJOR.

python
from soup_cli.eval.calibrate import run_calibration

# baseline_logits / quantized_logits: one next-token logit row per prompt, aligned
report = run_calibration(baseline_logits, quantized_logits)
print(report.delta_status, report.mean_kl)

No command calls it. soup eval quant-check is a different check: it runs a tasks file through two model directories and classifies the drop in task score, with absolute thresholds of 0.02 and 0.05. See Quant-check.

Model Arena (Elo)

An A/B tournament with Elo ratings: K=32 default, 256-model cap, 1M-match cap, and Tournament.ratings returns a MappingProxyType so a caller cannot mutate the table.

Library only, no CLI surface. It ships as soup_cli.eval.arena and is used from Python. There is no soup eval arena subcommand; soup eval registers benchmark, custom, judge, auto, compare, leaderboard, human, gate, quant-check, design, discover, lock, coverage, against, gate-install, unlearning, behavior, capability, checklist, irt-subset, citation and aider (v0.74.0). For a pairwise verdict from the CLI, use soup ship --task-mode pairwise.

New benchmarks

ceval and cmmlu route through lm-evaluation-harness. aider_polyglot is a recognised benchmark name with no lm-eval mapping, and the v0.43.1 release that was meant to add a runner for it was never cut. The live runner is soup eval aider, added in v0.74.0, which needs a locally built aider-benchmark Docker image and a prepared Polyglot exercises checkout.

Profiling helpers

  • memory_snapshot_context — CUDA torch.cuda.memory._record_memory_history wrapper
  • detect_anomaly_context — torch.autograd.set_detect_anomaly wrapper
  • nccl_bandwidth_check — reference table for h100 / a100 / v100 / rtx40-series (OK ≥80% / MINOR ≥50% / MAJOR <50%)

VS Code launch.json writer

Writes .vscode/launch.json with cwd containment and a symlink TOCTOU guard. It ships as a library helper with no CLI surface: soup_cli.utils.vscode_setup.write_launch_json has no caller in the shipped code, and soup doctor's own flags are --nccl, --disk and, since v0.75.0, --config — none of which writes a launch.json. Treat it as available to a script, not as a command.

soup data demo

4-bundle frozen registry: alpaca_demo / sharegpt_demo / dpo_demo / grpo_demo. Atomic copy via sibling temp file + os.replace.

bash
soup data demo alpaca_demo --output ./train.jsonl

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.