github MakazhanAlpamys/Soup v0.76.0
v0.76.0 - settings Soup accepted and never applied now stop the load

4 hours ago

490 pull requests have merged since 2026-09-12, the day v0.75.0 shipped, and 418 of them came from 80 people outside the maintainer. What they found is the release: settings that Soup validated, documented and accepted, and then read nowhere on the path they claimed to configure, so a soup.yaml could ask for one thing and quietly train another. This release refuses the settings that never took effect, warns about the rest and names the release that will refuse them, evaluates the validation split Soup always held out and never used, and applies the grpo_beta KL penalty to every GRPO variant. It also adds soup adapters check, soup bench train, soup data clean, soup recipes verify and soup rewind, and the layer-streaming disk tier now reads on a background thread, through direct I/O, and can stripe across NVMe drives. A config that loaded on v0.75 can stop loading: run soup doctor --config soup.yaml before you train.

What's New

Breaking changes (read these first)

  • A setting that never took effect is refused at load. Each message names the field and what to change. Among them: training.quantization_aware: true (#1222; it never ran quantization-aware training), training.use_longlora (#1240), training.ebft_variant (#1230), training.gdpo_variant (every non-null value), training.rope_scaling_type where no setup reads it (#1697), training.freeze_layers / freeze_ratio outside the text sft / tts path on the transformers backend (#1497, #1581), training.auto_mixed_precision outside sft / tts (#1618), and backend: unsloth on seven further tasks that have no unsloth setup (#1357). Other refusals follow the same rule, for example expand_layers, freeze_trainable_layers, loraplus_lr_ratio and moe_lora combinations that no trainer applies; the changelog lists every one. Settings that are unread but still tolerated for one more release (lr_groups, early_stop_patience, forgetting_eval_steps and 26 other staged fields) warn at load now and are refused from v0.77.
  • Validation loss is now evaluated, and grpo, ppo and online_dpo no longer hold rows out. data.val_split held rows out of training on every run, and no trainer on the transformers backend evaluated them (#1223, #1313). Every task that gets a split now evaluates it at the end of each epoch, or every N steps with the new training.eval_steps, and records the val loss; runs take a few percent longer. grpo, ppo and online_dpo evaluate by generating, so by default they neither evaluate nor withhold rows: data.val_split is ignored with a note and every row trains, which changes the rows a default config trains on.
  • Every non-standard grpo_variant applies the grpo_beta KL penalty (#1232, #1249). gspo, dapo, dr_grpo, bnpo, two_sided and rft validated grpo_beta and dropped it, so existing variant configs will not reproduce prior runs. grpo_beta: 0 now runs KL-free and skips the reference forward pass (#1247, #1295).
  • Exit codes of gate and verdict commands follow one taxonomy: 0 pass, 2 gate failure, regression or drift, 3 usage or input error (#813, #921). soup eval gate and soup eval against fail with 2 (was 1), soup lock check drift is 2 (was 3), soup expect suite failure is 2 (was 3), soup data validate input errors are 3 (was 1), and a mistyped flag on these commands is 3. A CI script that compares the exit code needs a look.
  • Other behaviour changes. training.loraplus_lr_ratio now applies on every LoRA task instead of only sft, pretrain and embedding, so those runs produce different weights (#745, #1080). soup export --format torchao and training.nvfp4 resolve their torchao classes from the module that defines them and the [qat] extra now needs torchao>=0.18.0 (#826, #1066). An FP8 request that cannot run, or whose conversion fails, stops the run instead of training in bf16 (#835, #1154; #1152, #1333). soup data preprocess stops on a chat row it cannot tokenize instead of dropping it (#1180, #1182). ReLoRA restarts follow the paper contract and need an explicit quantization: none (#693, #1133). data.mask_history now keeps only the last assistant turn in the loss and requires data.train_on_responses_only: true (#761, #1101). soup data recipe --execute refuses silent placeholder generation (#817, #922). soup bench is now a group: soup bench infer is the old inference benchmark and soup bench <model> still runs it.

New commands and options

  • soup adapters check scans a LoRA adapter for silent failure (a near-zero weight delta, dead layers, an all-zero lora_B, orphaned projections) and ends in one contract line, alive or inactive: <reason>, without needing PyTorch (#1721, #1738). soup adapters audit compares what a finished run recorded against the config that started it, and exits 2 on a divergence (#762, #763).
  • soup bench train trains a fixed number of steps in a scratch directory and exits 1 when the model was not training (no trainable parameters, a zero or non-finite gradient norm, parameters that did not change). It covers task: sft on the transformers backend (#836, #1146).
  • soup data clean sanitizes and repairs a dataset without touching the input file: control characters, zero-width spaces and BOMs by default, and heuristic repairs behind explicit opt-in flags (#718, @Deadpool2000).
  • soup recipes verify checks on the meta device, with no weights downloaded, that every shipped recipe, template and example can attach a LoRA adapter, and --config soup.yaml checks one before a long download (#1116, #1117).
  • soup rewind names the dataset rows behind a loss spike. An SFT run writes <output>/rewind.jsonl (training.rewind_log, default on) and the command ranks a spike step's rows by their share of its token loss; on an 8 GB M1 it put a poisoned row at 100% of step 58 (#1000, #1018).
  • soup infer --batch-size is opt-in batched inference (the default stays 1). soup infer --cuda-graphs and soup bench infer --cuda-graphs are experimental and need PyTorch 2.14 or newer: on one RTX 5070 Laptop (unpinned, Qwen2.5-1.5B in FP16) the slowest run with graphs decoded 2.9x faster than the fastest without; the record is benchmarks/gate-v0.76.0-cuda-graph-decode.md.
  • soup ab runs a two-sided, variance-robust test and reaches accept_h0 about twice as soon when there is no difference; --beta is deprecated and ignored, and refused from v0.77 (#1227, #1265, #1418). soup draft measure reports the break-even acceptance rate and the best draft length (#843, #1042).
  • Sigstore keyless signing: soup adapters sign --backend sigstore and soup attest emit --sign sigstore, with verification against an out-of-band certificate identity and OIDC issuer (pip install "soup-cli[sigstore]"; #1114, #1115).
  • soup train --nodes / --node-rank / --master-addr / --master-port for multi-node Accelerate launches (#40, #853). soup doctor reports GPU architecture and precision capability (#829, #947) and the MLX backend (#659, #660).
  • Recipes and training options: 170 ready-made recipes (recipes that could not load their model were fixed or removed, #1398), with kimi-k2.5, deepseek-v4-pro, minimax-m3, mistral-large-3, qwen3.5-35b-a3b and qwen3.6 DPO / GRPO additions; token-chunked checkpointed KL distillation (training.distill_chunk_size, #743); the PEFT LoRA-FA optimizer (#962); an experimental QuEST mixed-route SFT path whose retained result is evaluation-only (#1105); Arabic, Japanese and Simplified Chinese READMEs (#1100, #1733).

Layer streaming (opt-in, still BETA)

The disk tier reads on a background thread, through direct I/O, and can stripe across NVMe drives. On a 36 GB 70B-shaped NF4 store larger than RAM (one RTX 5070 Laptop 8 GB box), a cold step went from 110.5 s on the synchronous read to 16.2-17.3 s, and from 17.4 s to 9.97 s across two drives with SOUP_LAYER_STREAM_STRIPE_DIRS (a sustained-load probe measured 1.28x and 1.41x in two rounds and reached no formal verdict). A store that fits RAM is still faster on the RAM tier, which stream_source: auto picks. The streamed CUDA NF4 forward now follows bitsandbytes' own fused-versus-dequantized dispatch (#842, #1143), and the post-repair 8B NF4 throughput row on a 4 GB card is recorded (#361). Records: direct I/O, striping, sustained probe.

Full list: CHANGELOG.md.

Install/Upgrade

pip install -U soup-cli           # a fresh install with pipx: pipx install soup-cli
pip install -U "soup-cli[train]"  # the training stack
  • Run soup doctor --config soup.yaml first. After upgrading and before you train, it loads your config with the new rules and lists every setting that is now refused or warned about, with what to change. A config that must load on both v0.75 and v0.76 needs the refused key removed, not renamed.
  • Python 3.10 to 3.12 only (requires-python = ">=3.10,<3.13").
  • click is now declared and bounded: click>=8.0.0,<8.5. click 8.5.0 drops the description of every positional argument from every soup <command> --help page, so a fresh install that resolved the newest click showed ADAPTER TEXT [required] with nothing after it (#1790). If another package in your environment needs click 8.5 or newer, install Soup in its own environment (pipx does this).
  • typer is declared >=0.9.0,<0.21.0, but only typer 0.15.4 and newer start on every click the metadata admits (#1802). pip install -U soup-cli does not upgrade a dependency that already satisfies its range, so an environment that already holds an older typer fails on every command, soup --help included, with Type not yet supported: int | None. Fix it with pip install -U "typer>=0.15.4,<0.21".

Security

  • No new security advisory is published with this release. Two were published earlier and are already public: GHSA-63h4-gvp4-r26g, fixed in 0.75.1, and GHSA-9f49-hqpf-c849 (outbound endpoint validation), fixed in 0.75.2. Both fixes are carried in 0.76.0, so a user still on 0.75.0 or 0.75.1 should upgrade. The supported version for security fixes is 0.76.x.
  • Hardening found by this release's own review round, in commands that ship for the first time in 0.76.0 (so no earlier release is affected):
    • soup bench train -o and soup rewind --json check their destination before any work starts: it must stay under the working directory and may not be a symlink, a junction or a directory, and the file is written atomically. A refused path exits 2.
    • soup rewind and soup data clean print dataset rows, log values and error text through the terminal-safe path, so control sequences stored in a dataset cannot reach your terminal.
    • soup data clean --strip-boilerplate: a long crafted row could make one of its sign-off patterns run for a very long time. The pattern no longer rescans from every offset; results for normal rows are unchanged.
    • soup adapters check refuses a weights file larger than 2 GiB, checked before the file is opened, instead of accumulating an untrusted file in memory.
  • Also in this release: soup ui no longer keeps its token in sessionStorage or on window (#1136, #1190) and keeps a session across reloads with an HttpOnly cookie on a loopback bind (#1191, #1474); the Web UI caps YAML and chat request bodies (#897, #915; #948).

Deprecations

All of these work as before in 0.76.0 and are refused or removed from v0.77. The warnings below ship for the first time in 0.76.0, so this release is the one minor of notice.

  • soup export --format awq and --format gptq (and soup quantize --to awq|gptq) will be removed in v0.77 (#338, #1690; removal tracked in #1710). Both upstream projects (AutoAWQ and AutoGPTQ) are archived, neither extra installs next to [train], and auto-gptq has no Python 3.12 wheel. The command now starts with a Deprecated: notice that names the formats to move to: gguf, onnx, tensorrt, bitnet, tq1_0.
  • 29 staged config fields warn at load and are refused from v0.77 (#808, #1106): for example training.lr_groups, early_stop_patience, citation_recall_threshold, forgetting_eval_steps, forgetting_benchmark, forgetting_stop, checkpoint_eval_*, grace_codebook*, convergence_*, long_context_grpo, vision_grpo, quantize_ref_model, and the data.video_*, data.image_*, data.split_thinking, data.resize_vocab, data.extend_conversation and data.skip_prepare_dataset fields.
  • Three deprecated values warn and are ignored now, and are refused from v0.77: data.remove_unused_columns: true (the default is now false; #759), an explicit training.quantization: 4bit or 8bit on a task whose trainer never quantizes (#795), and soup ab --beta (#1418). Each warning ends with "Soup v0.77 will refuse it."

Gate record and preprint

Gate record. Every gated piece of work in this window is published as written under benchmarks/ and linked from benchmarks/README.md; nothing was left unpublished. The four records named for this release: gate-v0.76.0-cuda-graph-decode.md, gate-v0.76.0-tool-call-discrimination.md, gate-v0.76.0-arithmetic-discrimination.md and gate-v0.76.0-common-sense-discrimination.md. Alongside them: gate-971-async-nvme-source.md, gate-974-disk-tier-direct-io.md, gate-two-drive-striping.md, gate-901-14b-on-8gb.md, gate-1702-arena-packing.md, gate-836-bench-train-contract.md, gate-725-lorafa-operating-point.md, gate-674-quest-mixed-route.md with quest-674-postfit-development-results.md, gate-1227-ab-burn-in.md, gate-1265-ab-nig.md, gate-1418-ab-cs-accept.md, the probe-rtx5070-*.md records and probe-moe-expert-coverage.md, gpu-test-runs.md, and the post-repair NF4 row added to gate-v0.72.2-nf4.md. The two-drive sustained-load probe reached no formal verdict, and says so.

Preprint (concept DOI 10.5281/zenodo.21771064; current version v3, 10.5281/zenodo.21918325). The paper is explicitly scoped to the version it measured, Soup v0.73.0. No measured number the paper states is altered by this release, and none was re-measured to a different value. This window supersedes three of its statements:

  1. "The laptop configuration has not been re-run on the repaired code" is false since the post-repair NF4 row in benchmarks/gate-v0.72.2-nf4.md (Llama-3.1-8B NF4, 208.6 tok/s, 2.40 GB peak at 1935 MHz; the paper's 119.6 tok/s was measured at 952 MHz before the repair, so the two are not directly comparable; #361, #1014, #1103).
  2. The statement that the repaired streamed path always dequantises no longer describes the shipped code: since #1143 the streamed NF4 forward follows bitsandbytes' own fused-versus-dequantized dispatch, as resident NF4 does (the backward still dequantises, because bitsandbytes exposes no transposed 4-bit GEMM).
  3. The disk tier, which the paper lists as unmeasured, is now shipped and measured, on a second laptop (RTX 5070 Laptop 8 GB): gate-971-async-nvme-source.md, gate-974-disk-tier-direct-io.md, gate-two-drive-striping.md.

A new preprint version that restates these is future work.

Known Limitations

  • Not every declared config field reaches a consumer yet (#1814). The goal that every field in soup.yaml is read by something is not fully met: the guard test pins KNOWN_UNCONSUMED at 36 fields. 29 are the staged fields above (warn in 0.76, refused in 0.77; #808). The other seven are not in the staged table, and only two of them are plainly unwired: training.warmup_auto (read only by autopilot when it writes a config; no trainer reads it) and training.forgetting_threshold (its description says it is staged, but it is missing from the staged table, so it loads without a warning). The other five are accounted for: data.remove_unused_columns is deprecated (an explicit true warns and is ignored, and it is refused from v0.77), training.packing_cross_doc_attn_mask is already refused at load, and training.llm_int8, training.load_in_16bit and training.unsloth_bnb_4bit are aliases that the schema rewrites or asserts in a validator. The guard test has no "refused" or "alias" category for the last four of these yet, so it still counts them.
  • soup doctor --config knows three of the 19 (task, backend, modality) combinations that the 170 shipped recipes use (#1815). Its declared tables cover 23 recipes; for the other 147 it reports nothing rather than guessing (the largest gaps are sft, grpo and dpo on the transformers backend with text).
  • Several error messages are less helpful than they should be. A config rejected by a model-level (cross-field) validator prints an empty field location, and an unknown config key with no near match names the key but suggests nothing to do (#1816). Some rejections arrive only after a slow import or model load: soup bench train with --warmup not below --steps, soup recipes verify with a missing or unparseable --config (about 14 s against 0.5 s for an out-of-range option, on the maintainer's laptop), and soup infer --cuda-graphs on a setup it refuses (#1817). soup data clean and soup ab report a vague message on rows of an unknown shape, and soup rewind --json writes NaN / Infinity for a non-finite loss, which is not strict JSON (#1818).
  • The response from an endpoint you choose is not size-capped (#1819). The judge and data-generation calls (soup eval judge, soup data generate and the vLLM, Ollama and Anthropic providers) read the whole response body before parsing it, and the endpoint is chosen by whoever wrote the soup.yaml or the suite. Do not run a soup.yaml you do not trust.
  • net_guard checks IP literals, not names, by design. It validates IP literals only and does not resolve a name, so a hostname is passed through unresolved. That design was agreed in the #593 and #598 threads, is recorded in #599 (closed) and is written in the net_guard docstrings. SECURITY.md lists SSRF in the synthetic-data providers, the inference server and the hub and endpoint validators as in scope.
  • typer>=0.9.0, the declared floor, is not a working floor; 0.15.4 is (#1802). Soup uses X | None option annotations (soup train --node-rank, --master-addr and --master-port, and soup doctor --config), which typer 0.9.0 to 0.12.3 reject on every command with Type not yet supported: int | None. Typer 0.12.4 to 0.15.3 start only with click 8.1.x, because they declare no click ceiling and a resolver can pair them with click 8.2 or newer. Typer 0.15.4 is the lowest release that starts with whatever click the resolver picks, because it caps click<8.2 itself; 0.16.0 to 0.20.1 work with click 8.0.0 through 8.4.2. A normal pip install resolves a current typer, so only an environment that already holds an older typer, a constraints file or lowest-version resolution is affected.
  • The four README translations still show the v0.75.0 What's New (the translation sync gate exempts that section), and the policed README text still says "re-measurement pending in issue #361" although #361 closed on 2026-09-27. Both wait for translators; the English correction is draft PR #1699.
  • v0.77.0 flips every refusal: the staged fields (#808, open until the flip), data.remove_unused_columns, training.quantization on tasks that do not quantize, soup ab --beta, and the AWQ / GPTQ removal (#1710). The deadline is not a promise on paper: STAGED_FIELD_REJECTION_VERSION and DEPRECATED_VALUE_REJECTION_VERSION are "0.77", and the deadline tests (TestTheDeadline) go red when the version reaches it, which forces each flip. Expect more configs to stop loading in that release; soup doctor --config shows them now.
  • Layer streaming remains BETA and opt-in (stream_layers: true), and --cuda-graphs is experimental.

Contributors

418 of the 490 pull requests merged since 2026-09-12 came from outside the maintainer, from 80 people. Counting only the 483 merged after the v0.75.0 release pull request, it is 412 of 483, from the same 80. The count after each name is that person's merged pull requests in the window (six of the 418 were merged on the morning of the v0.75.0 release, before its release pull request, and were credited there too); the clause is what they found or fixed. Every one of these is a defect or a gap a user would have hit first. Thank you.

  • @Srinivasan8888 (50) — soup adapters audit (#763), soup rewind (#1018), soup recipes verify (#1117), soup bench train (#1146), soup draft measure (#1042), data.mask_history finally applied (#1101), moe_lora on the trainers that ignored it (#1074, #1148, #1179), one FP8 hardware gate (#1044, #1154), target_modules: auto on every shipped MoE family (#1102), the preprocess-cache BOS and stop-token fixes (#1096) and the pytest -m gpu marker (#1050).
  • @kok-o (45) — token-chunked checkpointed KL distillation (#743), the 0/2/3 exit-code taxonomy for gate and verdict commands (#921), KL-free GRPO with grpo_beta: 0 (#1295), FP8 on the SFT audio path (#1155), DoRA refused where no backend applies it (#1657), DPO beta-schedule crashes (#1294), soup train --profile actually writing traces (#1639), the Lambda SSH keepalive (#1506), MCP symlink refusals (#1171, #1492) and the deepseek-v4-pro recipes (#1297).
  • @Amix29 (29) — Sigstore keyless signing for adapter manifests and attestations (#1114, #1115), streamed NF4 following bitsandbytes' fused dispatch (#1143), a size cap on Web UI YAML bodies (#915), data.chat_template applied consistently across trainers (#919), one shared PEFT LoRA builder so rank_pattern works everywhere (#923), soup eval against reading real eval results (#914), the Llasa live codec and the Sesame CSM refusal (#1112) and the qwen3.5-35b-a3b-grpo recipe (#956).
  • @abdulwaarith0 (16) — the doubled BOS on the SFT path (#788) and in the vLLM, SGLang and MII engines (#867, #995, #996), LoRA+ applied on every LoRA trainer (#1080), the variance-robust soup ab statistic and the retired --beta (#1265, #1418), soup data clean fixes for nested tool calls (#1453, #1493) and the freeze_layers refusals (#1532, #1649).
  • @taljeon (16) — a fabricated 0.0000 -> 0.0000 loss delta on short runs (#908), length bias in the shipped preference examples (#940), diverged sweep arms ranked last (#946), unreachable providers reported as success in data recipes (#969), the gdpo_variant refusal, unmeasured benchmark results stored as zero, and exact quant-check verdict boundaries (#1743).
  • @dchaudhari7177 (14) — a test that fails when a typer command is called with a parameter left unfilled (#757), distillation gradients scaled by accumulation steps (#742), a row on both sides of a streaming val_split (#729), the pinned MLX harness step count (#727), rank_pattern tests on every adapter-building trainer (#963), an empty streamed adapter reported as success (#1031) and an untied streamed checkpoint taking a preference step (#1061).
  • @ybai08 (12) — use_dora refused on GPTQ, AWQ, AQLM and EETQ bases (#1555), mxfp4 loading with its own config and the VRAM pre-flight covering pre-quantized formats (#1558, #1655, #1729), a down judge adding 3 s of backoff per row (#1563), direct I/O staying on for an unaligned arena (#1621), the rope_scaling_type refusal (#1730), the fp8 transformers floor (#1745) and the backend: unsloth tip (#1746).
  • @Samearth17 (11) — GPU architecture and precision diagnostics in soup doctor (#947), modern CUDA driver headers (#883), the NF4 resident reference compute path (#857), soup infer --batch-size (#1083) and an interrupted re-shard that could leave a stale cache index (#1747).
  • @wanjinhao1 (11) — ten optimizer names refused at load instead of crashing inside the trainer, autopilot configs that soup train itself refused (#1257), soup data doctor --mask-history (#1259), the LLaMA Pro and freeze_trainable_layers refusals (#1390, #1399), destination checks before expensive steps (#1469) and the dormant auto_quant module removed (#1262).
  • @AmirF194 (9) — request-body caps on /api/chat/send and /api/data/inspect (#948), deploy_to_canary reporting a fabricated OK verdict (#982), use_flash_attn / use_liger scoped to the trainers that read them (#983) and accuracy / verifiable/math scoring 0.0 on common MATH answer spellings (#1371).
  • @Areen-09 (9) — the kimi-k2.5 (#872) and qwen3.6-35b-a3b (#978) DPO and GRPO recipes and an AcceleratorError OOM classifier that can be tested without a GPU (#1047).
  • @drakeo338 (8) — per-layer config lists sliced with the pruned layers (#1256), the #808 guard asserted under forced colour (#1377) and the #361 harness resolving its source SHA from soup_cli's own tree (#1382).
  • @SID-6921 (8) — setup errors reaching fail_run with the run's pid recorded (#767), the MLX teacher worker verified by nonce instead of PID (#950) and the documented --minillm-* flags that raised No such option (#998).
  • @umran666 (8) — the post-#331 8B NF4 re-measurement protocol and its recorded row (#1014, #1103), --find-lr refusing instead of writing a curve nobody measured (#1334), preference_loss_weights refusing a blend it cannot compute (#1513) and task: ppo refusing flags it cannot feed (#1514).
  • @Ercaner1988 (7) — the Arabic and Japanese README translations behind the sync gate (#1100), the re-stamp gap in the translation gate (#870) and exempting What's New from it (#1020, #1064).
  • @Nari-Ab (7) — PIL images and image structs accepted in vision SFT (#1601), preference rows deduplicated against --dedup-with and within the run (#1605) and llm_int8_skip_modules=[] for the 4bit_forced save format (#1606).
  • @AaronProbha18 (6) — a pinned Rich Console so escape-absence assertions survive forced colour (#993), the soup data preprocess cache that trained on prompt tokens (#1120) and soup bench sampling the SM clock during the counted steps (#1177).
  • @akkupratap323 (6) — the MiniMax M3 and Mistral Large 3 DPO recipes (#933), the Qwen3.6 27B DPO and GRPO recipes (#1015) and live canary routing with rollback (#1104).
  • @Guts1005 (6) — the staged-field warnings with a named v0.77 deadline (#1106), Hugging Face repo IDs preserved on Windows (#1118), the GPU test marker gated on visible devices (#1134) and descriptors closed before unlinking staged offline datasets (#1753).
  • @maximilianfeix (6) — the vocabulary guards and shard non-retention pinned (#1400), the untied DPO/KTO head copy stated (#1402) and one source_sha() shared across the harnesses (#1403).
  • @Momoyeyu (6) — mps resolved in the streamed builders (#1375), the reasoning template's answer markers pinned (#1471), custom tasks scored by the stated answer (#1490) and the Simplified Chinese README (#1733).
  • @Shutaru (6) — the measured mixed QuEST W4/A4 route (#1105), hardened QuEST CLI output (#1159) and a portable local base identity that does not weaken resume (#1176).
  • @VanshSharmaPES (6) — nine private terminal-escaping copies consolidated onto one (#907), the proof-4gb notebook repinned and re-run on a T4 (#910), the T4 forecast re-measured with the old figure marked stale (#967) and orphaned BitNet helpers removed (#1034).
  • @jagadeepmamidi (5) — soup ship judge numerics stamped (#746), offline MiniLLM rejected at teacher mix 0 (#977), distill harness closures derived instead of bound (#1008) and ReLoRA restarts following the paper contract (#1133).
  • @MohammadHijjawi97 (5) — the KL metric logged for GRPO variants (#1293), canaries spread through the file so the val split cannot hold them (#1386) and a metric column whose spread a float cannot carry now named (#1392).
  • @vaputa (5) — unlearn runs that died with KeyError 'duration' (#1537), --format soup-serve refusing a single file (#1557) and grad-accum pressure measured against the card (#1625).
  • @Blizzeq (4) — the preprocess cache keyed on data.chat_template (#1082) and on every row-set input (#1253), and a clean exit on an unregistered template (#1175).
  • @bobbonauta (4) — the trainable adapter dtype kept across a checkpoint resume (#1504) and Hugging Face snapshots whose blobs live in the shared store materialised (#1510, #1512).
  • @chiliec (4) — a non-zero exit when a [train] package is beyond its ceiling (#877), backend: unsloth refused at load for distill (#1193), exception text printed through the terminal-safe path (#1202) and expand_layers refused unless unquantized (#1308).
  • @Faisal-Fayaz (4) — the login URL that carries the auth token opened and printed (#1307), use_liger / use_flash_attn refused under stream_layers (#1716) and the held base identity reused on a v1 resume (#1728).
  • @mohdUwaish59 (4) — the Web UI auth token held in a closure instead of sessionStorage (#1190), a session cookie that survives reloads (#1474), --find-lr sized to the rows it has (#1244) and LoRA+ refused with model-only optimizers and GaLore (#1255).
  • @putramkti (4) — the MCQ boxed letter read through the shared answer scan (#1365), the auth phrasing read out of the whole exception chain (#1366) and the trainer wrapper resolved through one dispatch shared with sweep (#1397).
  • @qwist1233-cpu (4) — assistant_masks pinned on unpacked runs and trl's Liger column selection (#1376), alpha + beta >= 1 and overflowing standardised effects refused (#1378) and the ROI table printed when --probe-model implies --probe (#1521).
  • @be-student (3) — JSONL detected by structure (#730) and reverse KL and JS stabilised (#736).
  • @commit-msuyog (3) — nested parquet data preserved (#1292), auto-eval run after training (#1546) and vision image paths resolved relative to the dataset (#1604).
  • @developerjillur (3) — the live behaviour battery scored by behaviour instead of the label word (#1335), judge, keyword and recipe-judge verdicts read by their structure (#1472) and unaligned student positions left out of aligned ULD (#1541).
  • @harshitthek (3) — a gradient watchdog that skips non-finite optimizer steps (#1084), clamped importance ratios in the GRPO variants (#1610) and soup adapters check (#1738).
  • @Rayan-and-beyond (3) — soup data doctor format validation (#952), unwired BitNet training rejected (#981) and unavailable loss reported for MLX and unlearn (#986).
  • @Ru0k3 (3) — the newest evaluation score kept per benchmark (#1291, #1459) and the CI fork badge (#1458).
  • @wangzhengzhuo05 (3) — terminal control bytes stripped from Langfuse --pull errors (#893) and unknown config keys refused in soup plan and soup apply (#909).
  • @anyingiit (2) — registry baselines taken from the newest eval row per benchmark (#1260) and soup data forge no longer writing empty-answer rows for failed judge calls (#1261).
  • @Ashutosh-Panda2004 (2) — trl PPO per-step loss read from loss/policy_avg (#1416) and the parent site-packages linked into the worker venv (#1495).
  • @bakdauletbaktygaliyev (2) — unmeasured probes reported as NOT_RUN instead of OK (#1489) and live probe inputs read through the training converters (#1526).
  • @Deadpool2000 (2) — soup data clean (#718) and the interactive prompt for a missing model, data or goal in soup autopilot (#1577).
  • @ege-arhan (2) — the Turkish translation polished for v0.75.0 (#957) and the sft table widened to the remaining four CUDA-only fields (#961).
  • @geoggrigori (2) — the shape behind "an 8B base fits a 4 GB card" stated (#1719) and the accept-time rollout check and outage refusal pinned (#1754).
  • @HarshRajSinghania (2) — missing [train] packages named on a partial stack (#884) and shrink cwd-containment checks kept off the Hub (#1077).
  • @MugdhoAI (2) — draft model names escaped in a Rich panel (#1053) and Transformers 5 BatchEncoding handled in sequence distillation (#1243).
  • @Nick-800 (2) — a note that --backend has no effect on training (#1678) and --registry-id / --deploy wired across the non-GGUF export formats (#1679).
  • @UroojFatima-052 (2) — windows-latest train() tests run instead of skipped (#1401) and contains scoring made linear again (#1540).
  • @Yi-111-a (2) — FP8 gate stubs kept package-safe (#1284) and config gaps reported only when set to active values (#1336).
  • @yunaremaia (2) — the accept hold named when it is what keeps a verdict at continue (#1585) and a disqualifying local base refused before hashing it (#1588).
  • @00200200 (1) — digits preserved in backend-support warning fields (#966).
  • @1cbyc (1) — generated config validation errors reported (#904).
  • @abhinyaay (1) — JSON, JSONL and CSV output through typer.echo instead of the Rich console (#1470).
  • @akshatshahh (1) — one shared loopback set for every outbound gate (#1554).
  • @chaitanya-y20 (1) — format detection from a bounded prefix, not only the first row (#1496).
  • @deximple (1) — sweep setup failures marked as failed (#1640).
  • @feiiiiii5 (1) — MLX-unread CUDA-only fields reported and the all-clear scoped (#911).
  • @fukalous (1) — memorization detected in long rows (#1481).
  • @harryc295 (1) — the recipe count synced across the documentation sites (#1051).
  • @here-2007 (1) — the proof-4gb notebook made reproducible (#1545).
  • @Hitesh-XS (1) — non-Latin scripts tokenized and empty symbol answers skipped (#1559).
  • @jamalkamaladdin (1) — Axolotl orpo, ipo and simpo mapped to their Soup tasks (#1254).
  • @jarik2014 (1) — the control-strip guard failing when a scanned file does not parse (#951).
  • @johncoplin (1) — friendly-error patterns for HTTP 401/403 optimized (#1594).
  • @Konuktor (1) — Langfuse --pull bounds and filtering hardened (#881).
  • @MrBeldum (1) — 23 missing commands covered in docs/commands.md (#855).
  • @ousamabenyounes (1) — evidence decoding shared across the CLI and MCP (#768).
  • @parnika0110 (1) — invalid recipe Hugging Face repo IDs repaired (#1132).
  • @PranavD2905 (1) — the private-address refusal now saying what to do (#1582).
  • @rishcx (1) — GPU names matched on word boundaries and current cards recognised by run_cost (#1081).
  • @sajjadlabx (1) — committed Git conflict markers detected (#1130).
  • @shubhambhar007 (1) — rejected choices reported with the live allowed values (#954).
  • @sloemo01 (1) — a fast-LoRA single-projection autograd kernel and its tests (#1087).
  • @sup3dev (1) — 401/403 classified from the exception object instead of bare digits (#1268).
  • @tristangrech (1) — multi-node Accelerate launcher support for soup train (#853).
  • @ump45nose (1) — the MLX backend wired into soup doctor with its real version (#660).
  • @webdevsamran (1) — optional PEFT LoRA-FA optimizer support (#962).
  • @xiechimon (1) — a symlink at the run-log path refused when spawning a child (#1150).

Don't miss a new Soup release

NewReleases is sending notifications on new releases.