Quant-Lobotomy Checker
Quantization — 16-bit → 4-bit, say — often destroys niche capability you care about while the aggregate score looks fine. soup eval quant-check runs one JSONL task file through a before model and an after model and renders a single OK / MINOR / MAJOR verdict for the pair, so you can catch a stealth regression before you ship it. It scores one average over the whole file, not one verdict per task or category; see "What can make an OK meaningless" below.
Run it
soup eval quant-check \
--before ./output/merged \
--after ./output/merged-awq \
--tasks critical_eval.jsonlEach side is loaded with AutoModelForCausalLM.from_pretrained, so each must be a Hugging Face-format model directory that transformers can load, such as a merged model or an AWQ or GPTQ export directory, and it must sit under the current working directory. A GGUF file cannot be loaded this way. Either side can instead be registry://<id> pointing at a registry entry; that resolves to the first artifact recorded on the entry, whatever its kind.
Output
One row, named default, whatever the category values in the tasks file:
Quant check
┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━━━┓
┃ Task ┃ Before ┃ After ┃ Delta ┃ Verdict ┃
┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━━━┩
│ default │ 0.540 │ 0.310 │ -0.230 │ MAJOR │
└─────────┴────────┴───────┴────────┴─────────┘What can make an OK meaningless
The score is one average over the whole tasks file: category is not split out, so run the command once per task file if you want a verdict per area.
If either side fails to load, the command prints Live model load failed (...); using deterministic stub. and carries on. It then replaces both models with a stub that returns the same canned text for every prompt, so the table shows default | 0.000 | 0.000 | +0.000 | OK and the exit code is 0. A GGUF file, a JSON file, an empty directory or a missing dependency all take this path. Read the lines above the table before trusting an OK: a stub run measured nothing.
Verdict thresholds
The classifier uses absolute drops in score:
OK— drop< 0.02(or the score actually improved)MINOR—0.02 ≤ drop < 0.05MAJOR—drop ≥ 0.05
Output formats
--format accepts table (default, Rich-rendered), json, or markdown. Pipe the output to a file if you want to persist the report:
soup eval quant-check --before X --after Y --tasks t.jsonl --format json > report.jsonTasks file
Reuse any custom eval JSONL:
{"prompt": "Solve: ...", "expected": "42", "category": "math.competition_hard", "scoring": "exact"}
{"prompt": "Capital of France?", "expected": "Paris", "scoring": "contains"}The file name must end in .jsonl and hold at most 10,000 rows. prompt is required; expected defaults to empty, category to default and scoring to exact. scoring is one of exact, contains, regex, semantic, tool_call_match, tool_call_name_match or tool_call_args_subset; any other value is refused with the line number. soup eval custom and soup ship --task-eval read the same format.
See also
- Export — GGUF / AWQ / GPTQ
- Evaluation
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.