What's new across v0.71 to v0.77
One page for everything that shipped since the v0.71 install split, newest first. The current flagship, layer streaming, has its own pages: Layer streaming for the mechanism and the measured numbers, Scaling a streaming run for architectures, batches, resume and the disk tier, Layer streaming disk tier for the direct-I/O reader added in v0.76.0, Streaming a Mixture-of-Experts base for the DeepSeek-V3 family added in v0.77.0, Preference losses over streaming for DPO, ORPO, SimPO and KTO, and Validation on hardware we do not own for what the method does at 8B through 72B on someone else's cards.
Every line below names the release it shipped in. Where a number is quoted it was measured; where none is quoted, none was measured.
The v0.77 line
- v0.77.0 refuses what v0.76 warned about. Upstream gave it no codename and titled it with a sentence: "what v0.76 warned about is now refused". The 31 staged fields (the 29 v0.76.0 warned about, and two staged after it) set away from their defaults,
data.remove_unused_columns: true,training.quantization: 4bitor8biton a task that never quantises, andsoup ab --betanow stop the load or the command, and so do fourteen of the fifteen settings on upstream's list that v0.76 accepted without a word and never applied (the fifteenth, a malformed KTO label, drops the row at data load), so a config that loaded on v0.76 can stop loading: runsoup doctor --config soup.yamlbefore you upgrade. Python 3.10 is no longer supported (>=3.11,<3.14, so 3.13 is), AWQ and GPTQ export are removed, and onsoup serve,/v1/tools/pythonand/v1/tools/bashanswer 401 without--tool-auth-tokenon every bind, loopback included; pinsoup-cli[train]<0.77to keep Python 3.10, AWQ and GPTQ export need v0.76.x and its[awq]or[gptq]extra, and 0.76.x receives security fixes only, until 0.78.0.training.gradient_checkpointingnow reaches the trainer, sogrpo,ipo,bco,reward_modelandonline_dpotrain with checkpointing off at the defaultfalse. DPO, ORPO, SimPO and KTO train natively on Apple Silicon (backend: mlx, Soup's own loop on TRL's objectives), MLX text SFT gains DoRA,eval_steps, the loss watchdog and seeded runs, andlora.use_rslorais now applied on MLX and Unsloth, where it was ignored. Layer streaming reaches DeepSeek-V3-family MoE models, with Kimi-K2-Base and -Instruct admitted behind a field-by-field check verified on CPU with a tiny K2-shaped checkpoint only (nothing has been trained on K2 itself);soup ship --require-provenancechecks evidence against what it was stamped with; and GRPO can score with an LLM judge,training.reward_fn: judge_rank(task: grpoonly; prompts and completions are sent to the judge host you configure). Some finished runs trained something other than their config said, among them adpo,ipoorgrporun resumed from a checkpoint: the Re-run table. 151 of the 226 pull requests came from 44 people outside the maintainer, in the release body's count. No security advisory is published with it, the preprint is unchanged, and the catalog is 171 recipes. The release page.
The v0.76 line
- v0.76.1 is a backport patch, and the bundled DPO examples train again. On v0.76.0,
task: dpo,ipo,bcoandpreferencefailed inside trl, after the model had loaded, onexamples/data/dpo_sample.jsonl,examples/data/chat_preferences.jsonland any dataset written the same way (a stringpromptbesidechosen/rejectedmessage lists that repeat the user turn). Thedpoandktoconverters now hand the trainer every preference row in one layout, and a row that cannot be written that way is dropped at load with a reason that names the field, so a dataset can shrink at load, with a warning, never silently. The one fix that touches a finished run: on those same rows,reward_model"no longer trains on a text with the question in it twice" (verified on v0.76.0; the code that produced it is unchanged at every earlier tag the audit read, back to v0.40.0), so re-train such a reward model if it matters to you. Every YAML file Soup reads now goes through one loader with a 100-level nesting limit, an expansion limit and a size cap per reader, so asoup.yamlover 1 MiB or nested deeper than 100 levels stops the load with one line naming the file: runsoup doctor --config soup.yamlfirst, as for v0.76.0. Soup declarestyper>=0.15.4, so upgrading upgrades an older Typer or names the conflict;data.train: teknium/OpenHermes-2.5loads from the Hub instead of failing withData file not found; and the audit log masks the values of--slack-urland--discord-url(lines already in the log were not rewritten until v0.77.0, which masks them once, the next time the log is written). Upstream's README and performance docs now print the 8B NF4 figure with its clock beside the post-#331 row, measured by @umran666 (#1103), and the two are not directly comparable. All seven changes are maintainer pull requests; there is no security advisory and no gate record, the preprint is unchanged, and test files go from 875 to 883. The release page. - v0.76.0 stops the load on settings that never took effect. Upstream gave it no codename and titled it with a sentence: "settings Soup accepted and never applied now stop the load". Dozens of combinations that loaded on v0.75 are now refused with a message that names the field and what to change, and 29 declared-but-unread fields warn at load, with upstream saying that v0.77 will refuse them. (It did: they are refused at load since v0.77.0.) Run
soup doctor --config soup.yamlbefore you train. 490 pull requests were merged between v0.75.0 shipping and the v0.76.0 tag, 418 of them from 80 people outside the maintainer. The release page; the refusals and warnings. - The exit codes of eleven gate and verdict commands moved to 0 pass, 2 gate failure, 3 usage or input error (
soup ship,soup expect,soup eval gate,soup lock checkand seven more). A CI step that tests for the old number, such as exit 1 fromsoup eval gate, now passes a failing gate. The table of what moved. - Validation loss is evaluated on the transformers backend for the first time.
data.val_splitheld rows out on every run and no trainer on the transformers backend evaluated them;training.eval_stepsis new.grpo,ppoandonline_dpono longer hold rows out, so every row trains. Every GRPO variant now appliesgrpo_beta, so an existing variant config will not reproduce an earlier run. - Dozens of fixes mean a run you already finished may have been wrong, most of them with a normal-looking loss curve: packing that trained prompt tokens, doubled BOS tokens, distillation gradients scaled by accumulation, GRPO rewards that scored every correct answer 0.0, Online DPO labels from a judge that could not rank a pair, and more. The Re-run this table lists them with upstream's wording and pull request numbers.
- New commands:
soup adapters checkandaudit,soup bench trainandbench infer,soup data clean,soup rewindandsoup recipes verify. Sigstore keyless signing is a real backend forsoup adapters signandsoup attest emit(shipped in v0.76.0; upstream's tests mock the signer).soup export --format awq|gptqandsoup quantize --to awq|gptqare deprecated, with removal tracked for v0.77. (Removed in v0.77.0.) - Layer streaming: the disk tier reads on a background thread through direct I/O and can stripe across NVMe drives, measured on one RTX 5070 Laptop with a synthetic store and with every caveat on its page. A post-repair row for the 8B configuration was recorded by @umran666 on a different 4 GB laptop (#1103) and is printed with its clock beside the older row, on Layer streaming; upstream's reading is that the raw 1.74x gain is the clock, not a speedup.
- Security: no new advisory. The supported version for security fixes is now 0.76.x. (Since v0.77.0, 0.76.x receives security fixes only, until 0.78.0.) On a loopback bind
soup uikeeps its token out ofsessionStorageand uses an HttpOnly cookie, and third-party plugin code loads only aftersoup plugins enable. - Counts at the tag: 170 recipes (9 added, 6 removed), 78 top-level commands, 29 command groups, 37 extras, 24 optimizer names, and 20 values in the
data.formatlist.
The v0.75 line
- v0.75.2 is a security patch with one change in it, and nobody outside the maintainer wrote it. Several outbound endpoint checks refused plain
httpto a remote host but accepted anyhttpsURL, including one naming a private, link-local or reserved IP address, so a configuration file that set a judge URL could make the machine that ran it POST to an internal HTTPS service addressed by IP. It is advisory GHSA-9f49-hqpf-c849, rated medium and reported by an outside contributor, affecting 0.3.0 through 0.75.1.soup data generate --api-base, the vLLM provider, judge URLs, eval-gate suites,soup ship --judge-model,training.online_dpo_judge(now checked when the config loads) and the Web UI chat proxy now refuse such an address on both schemes; loopback still works andhttp://0.0.0.0is no longer local. There is nothing to re-run and nothing to rotate; a config that names a private, link-local or reserved IP address fails loudly and should name a hostname instead. Hostnames are still not resolved. No measurement and no gate record; the preprint is unchanged. - v0.75.1 is a security and correctness backport, and the first release in four that nobody outside the maintainer wrote. It is the fix for advisory GHSA-63h4-gvp4-r26g, rated high, covering eight issues across 0.7.0 to 0.75.0, with three credentials to rotate: the Hugging Face token was resolved for every hub and handed to ModelScope or Modelers,
OPENAI_API_KEYwent as a Bearer token to anyhttpsjudge host whatever it was, and credential option values were written to the audit log. Four fixes mean something you already ran was lost, and the sharpest is that a layer-streamed LoRA adapter saved on peft 0.21 or newer is a 40-byte file holding zero tensors, with nothing raised at save time and no way to recover it. Also:soup runs clean --keep-weightsdid the opposite on Click 8.1 and deleted whole checkpoints, Modal runs lost their outputs with the container, and Ctrl+C during a Lambda submit could leave the paid instance running. No gate record and the preprint is unchanged, both stated by upstream rather than left implicit.
- v0.75.0 is the release where MLX started honouring the config it had been accepting. Training options were validated by the schema, documented in these pages and read by nothing on
backend: mlx(upstream counts six, and its fix entries name eight settings), so the samesoup.yamltrained a different recipe on Apple Silicon than on a CUDA box: response-only masking reached nothing, so every MLX run trained on the prompt; the optimizer, scheduler, warmup ratio and weight decay were dropped, so every run built a bare AdamW at a constant learning rate;max_grad_normclipped nowhere; and gradient accumulation and checkpointing silently took mlx-lm's defaults. All 60 of its pull requests came from outside the maintainer, by 22 people, and fourteen of its fixes mean a finished run was wrong. Breaking: an unknown config key now refuses the load at the deadline v0.74.0 named, andgrpo_variant: gspois the published sequence-level objective rather than a column-centering heuristic, so existing gspo configs will not reproduce prior runs. Validation loss was computed on every backend and thrown away; it is now its own series, with an un-evaluated step recordingNULLrather than a fabricated zero. (Corrected in v0.76.0: on the transformers backend the held-out split was never evaluated at all until v0.76.0.)torch>=2.6.0closes the limitation v0.74.0 published rather than hid. Also here: inference prompts stop sending a doubled BOS acrosssoup chat,serve,infer,bench,diff,ship,diagnoseandadvise;soup ingest --source langfuse --pullfetches traces live;soup doctor --confignames the settings your backend does not read; Web UI read endpoints and SSE require authentication; and four recipes take the catalog to 167. Opt-in, hardware-only telemetry is wired behindSOUP_TELEMETRY=1, and as shipped it sends nothing. No maintainer gate: three contributor records landed instead, one of them a gate that failed and was published as written.
The v0.74 line
- v0.74.0 found the frozen base being loaded in fp32 the whole time. A LoRA run freezes the base, so its only job is to hold the checkpoint's own numbers, and all three supervised load paths passed no dtype at all: measured on an H100 with Llama-3.1-8B and LoRA, peak memory falls from 48,241 MiB to 18,658 MiB, 2.59x on an unchanged config, with the same defect standing in twelve more trainers. 116 of the release's 120 pull requests came from outside the maintainer, by 25 people, and ten of its fixes mean a run you already finished was wrong, starting with unknown config keys that were silently dropped. The training stack moves to Transformers 5.16.1, TRL 0.29 and PEFT 0.20, so
pip install "soup-cli[train,mlx]"resolves for the first time; the free notebook tier could not stream at all until now, for a second reason after v0.73.1's; layer streaming admits a tenth architecture and stops keeping an untied embedding and LM head both resident; andsoup mcp servegains sse and http transports behind a mandatory bearer token, with gated execution refused over a listener. Breaking:soup serveexits 2 rather than warning on a non-loopback host without--tool-auth-token, and the SGLang backend finally obeys--trust-remote-code. No new throughput was measured; the two new records are a second-box VRAM verification and a partial Apple Silicon gate.
The v0.73 line: borrowed hardware
- v0.73.3 was a contributor release. All 24 pull requests came from outside the maintainer, from eight contributors, five of them appearing for the first time, and what they found was four flags that the schema validated, the docs described, and nothing read. Two findings are the project's signature failure shape: assistant-only loss masking built its label mask from a tokenizer mapping's key strings, so a run trained on zero tokens behind a normal-looking loss curve, and on Apple Silicon
quantization: 4bitwas silently rewritten tononebecause device detection did not know MLX. The one new capability is thatsoup mcp serve --allow-executestopped being a reserved gate and now runs a planned training or export behind a single-use, server-generated confirmation token, taking the server from 16 tools to 18. Also here: thesoup shipnoise floor is measured in the judge task modes rather than metric alone,soup env checkflags an installed package that violates Soup's own declared bounds, and layer streaming stops refusing a fast virtio disk as if it were a spinning one. No new measurement was made and no benchmark record was added, which upstream states rather than leaves implicit. - v0.73.2 repaired the release gate itself. Two of
soup ship's behavioural suites ranked by the wrong thing, so a stub answering every item correctly scored 0.000 and an 8B naming the right tool 40 times out of 40 scored 0.225. A whole failure direction, a model that refuses everything, had no detector untilmini_over_refusaljoined as the eighth bundled suite. New CLI flagsoup ship --noise-floor Nmeasures what the instrument itself can resolve before any delta is called significant. Any verdict issued before this release is suspect, and a stored--baselineis on a different scale. - v0.73.1 repaired the GPU tier most people actually have. bf16 was assumed on every CUDA card in fourteen places, so every pre-Ampere card (T4, P100, V100, GTX 16xx) failed on every task, not only on streaming. The same release caught the streaming VRAM pre-flight under-predicting at long sequence, against a contract that says it never does, and shipped
training.stream_vram_probe. Three more classes of finished-but-wrong run were closed: MLX adapters that loaded as a silent no-op,backend: mlxnever dispatching to MLX at all, and periodic checkpoints underuse_fsdp2_compilestill loading dead. - v0.73.0 is the release that came out of three days on an 8x H100 box. It repaired the NF4 gradient defect that only a resident reference could have found, plus four backends that had never executed once: the multi-GPU launcher, DeepSpeed with LoRA, SGLang serving and the Liger kernel. Two capabilities are new, both config keys:
training.seedand full fine-tuning aslora.r: 0. Python narrows to 3.10 through 3.12 (3.11 through 3.13 since v0.77.0). Six fixes mean a completed run of yours may be wrong, including a supervised path that silently capped every run at 1024 tokens and asoup shipgate whose suites scored zero on a capable model. The changelog and the re-run list. (v0.73.0)
The v0.72 line: layer streaming
- Validated on hardware nobody here owns. Three borrowed days on an 8x H100 box, the first machine able to hold a resident reference for a model worth streaming, so the correctness check that had only ever run on 3-layer fixtures finally ran against real checkpoints. The streamed forward is exact against a matched resident reference at 8B, 14B, 32B and 72B; peak VRAM stays flat from 3,397 MiB to 4,845 MiB while the model grows fourfold; the 4 GB laptop's headline, measured on v0.72.2 before the repair, reproduces at a median 113.00 tok/s against its 119.6; and a streamed model converges indistinguishably from a resident one over five paired runs. It also found a defect: in NF4 above roughly 165 MiB per decoder layer, the backward produced silently wrong gradients while the forward stayed exact and the loss looked healthy. That affects 32B and up, was present in every release from v0.72.0 to v0.72.4, and is repaired in v0.73.0, gated at both affected sizes against a control that reproduced it. The whole record.
- DPO, ORPO, SimPO and KTO run against a streamed base. Streaming used to mean supervised fine-tuning only. DPO's reference model is the same streamed base with its adapters switched off, so it costs no extra weights: on a 365M-parameter synthetic fixture, streamed DPO peaked at 0.914x the streamed SFT peak, where forcing a real second instance in the same harness cost 730.44 MB, exactly one copy of them. All four are bit-exact against a resident run of the same loss. The reference is free in memory, not in time: DPO reads the layer stack 1.52x as often per step. KTO needs
batch_sizeof 2 or more. (v0.72.4) - A packaging defect that predates the release: six preference trainers passed a field TRL removed across several of its own versions, so
soup train with task: orpocould fail at import on a fresh install. The dependency bound was settled by constructing all six configs against each candidate version rather than by reading source, and a contract test now calls the realsetup()for all six. The first bound shipped too tight, and the reason is worth keeping: some of those config classes had moved into TRL's experimental namespace while still being re-exported publicly with the field intact, and a relocation read as a removal. Constructing the object is what distinguishes the two; reading a diff is not. Corrected in v0.73.0, which widens support totrl>=0.14.0,<0.29(since moved: v0.74.0 requirestrl>=0.29.0,<1.0.0) behind a capability-probe layer rather than a version table, verified by constructing and training all six on three different trl versions. (v0.72.4) - The measurement records behind the whole v0.72 line are published in the repository's benchmarks directory, failures and discarded numbers included, and the work has a preprint: 10.5281/zenodo.21771064, summarised on the paper page. (v0.72.4)
soup doctor --diskreports the detected media type, because the streaming disk tier needs NVMe and refuses a SATA SSD, a spinning disk, or media it cannot identify rather than guessing. Opt-in, because the probe costs about 9 seconds cold and 2.4 seconds warm. (v0.72.3)[mcp]is pinned below 2.0. The MCP SDK's 2.0.0 removed an APIsoup mcp serveround-trips through, which broke its round-trip tests for anyone installing fresh. (v0.72.3. Since lifted: v0.74.0 requiresmcp>=1.10.0,<3and picks the API by probing the server constructor rather than reading a version string, so both majors work.)soup adapters arithmetic --rank N: mixed-rank LoRA algebra is exact rather than refused. Stacking the factors reproduces the sum of deltas by construction, and an SVD truncates to the rank you ask for. (v0.72.0)
The v0.71 line: lean install and live wiring
soup reward synth golds.jsonl -o reward.pyplussoup reward stress: Reward Forge. Synthesize a deterministic verifier from your gold outputs, refusing to emit a degenerate one, then attack it with empty, padded, repetitive and sentinel-spam junk to prove it cannot be gamed. (v0.71.40 and v0.71.41)soup ship --emit-evidenceplus--config soup.yamlplus--push owner/repo#N: the verdict becomes CI for weights, a provenance-bound gate you commit and render on every PR. (v0.71.39)- The
soup shipregression leg grew teeth: answer-extraction scoring over seven bundled offline suites (MMLU, arithmetic, tool-call, JSON, safety and more), not fifteen substring-matched trivia prompts. Verdicts can flip, because the old gate reported false negatives. (v0.71.38) soup data dedup --semanticplustopics,canaryandtrain --replay: Data Moat II, a semantic layer over your data plus tools for what a fine-tune forgets and leaks. (v0.71.36)soup init --template hipaa|soc2|eu-ai-act|sr-11-7plussoup cardandsoup ci init: the compliance pack. A regulation-shaped config, a provenance-carrying model card, and a PR gate that blocks a merge on DON'T SHIP. (v0.71.35)soup export --format ggufis validated end to end on Windows (q4_0, q4_k_m, q8_0, f16, plus an Ollama round-trip), fixing four bugs including an export that downgraded your CUDA torch. (v0.71.35)soup adapters arithmetic "coder + 0.5*math - toxic": task-vector algebra over LoRAs. Add, scale, and actually negate a delta rather than performing the no-op a naive coefficient gives. (v0.71.34)training.lisa_enabled: LISA re-samples which layers train every N steps, reaching for full fine-tune quality without a full fine-tune's memory. Since measured at 3B and 8B: it beats full fine-tuning on held-out loss, and it trains an 8B on one 80 GB card where full fine-tuning cannot run at all, but it costs more memory than LoRA rather than less (1.22x at 3B, 1.51x at 8B, both measured before v0.74.0 stopped loading a frozen LoRA base in fp32, so the real gap is wider). The numbers. (v0.71.34)soup trainwithtask: asrplussoup infer --task asr: Whisper fine-tuning with built-in WER and CER. Tiny and base fit a 4 GB card. (v0.71.32)soup train with task: online_dpoplussoup data best-of-nandevolve: an LLM judge in the loop across training and data. (v0.71.31)task: grpoplustraining.prm_reward: a Process Reward Model grades every reasoning step, the o1-era process-supervision signal. (v0.71.30)soup shrink --drop-ratio 0.25: depth-prune the least-useful layers, distill-heal the damage, and get a SHIP / DON'T-SHIP perplexity verdict. (v0.71.29)soup mcp serve: drive Soup from Claude Code, Cursor, Cline or Continue. Stdio only when it shipped; sse and http transports arrived in v0.74.0. (v0.71.28)soup data doctorandsoup data lint: 8 chat-template checks including the "never stops generating" EOS bug, plus a preference-data linter. Pre-flight, zero GPU. (v0.71.27)--reward-hack-mitigation kl_control|pid_lagrangian: detect reward hacking mid-run and self-correct by raising KL, shaping the reward and rolling back, instead of only halting. (v0.71.26)soup ship: one SHIP / DON'T-SHIP verdict fusing a task win with no catastrophic forgetting. Exit 0 or 2 for CI. (v0.71.25)soup recipes use whisper-tiny-asr: Whisper ASR and the 2026 model families (Qwen 3.5 and 3.6, DeepSeek-V4, GLM-5.1, Kimi K2.6, MiniMax M3). (v0.71.24 and v0.71.32. The catalog is 170 recipes at v0.76.0, 171 at v0.77.0. Since removed: the Mistral Large 3 recipe v0.71.24 added,mistral-large-3-sft, because Mistral publishes that model without aconfig.json, whichAutoConfigcannot read (#1398).)soup spectrum scan --top-percent 50: rank layers by singular-value SNR and fine-tune only the high-signal ones, with no model load. (v0.71.23)
See also
- Layer streaming — the current flagship: the mechanism, the measured numbers and the full refusal table.
- Scaling a streaming run — architectures, batch versus gradient accumulation, the VRAM pre-flight, resume and the NVMe disk tier.
- Preference losses over streaming — DPO, ORPO, SimPO and KTO against a streamed base.
- v0.77.0: what v0.76 warned about is now refused: the current release, which refuses at load what v0.76 warned about, drops Python 3.10 and removes AWQ and GPTQ export.
- v0.76.1: the bundled DPO examples train again: the backport patch before it with one reward-model re-run row for one row shape, one layout for preference rows and limits on every YAML file Soup reads.
- v0.76.0: settings that never took effect now stop the load — the minor release v0.76.1 patches: refusals at config load, new exit codes and the re-run table.
- Settings Soup refuses at load — the refusals grouped, with the start of each message.
- v0.75.2: endpoint URLs can no longer name a private address — the release before it: a one-change security patch, with nothing to re-run and nothing to rotate.
- v0.75.1: an adapter with nothing in it — the release before it: a hardening backport, and the layer-streamed adapter that saved with zero tensors.
- v0.75.0: MLX honours its config — the contributor release before that, where unknown config keys started refusing the load.
- v0.74.0: loaded in fp32 — the release before v0.75.0, and the ten things it means you should re-run.
- v0.73.3: four flags that did nothing — the release before it, contributed end to end.
- v0.73.2: the release gate — why any ship verdict issued before it is suspect.
- v0.73.1: the free GPU tier — the pre-Ampere repair, and the VRAM pre-flight caught under-predicting.
- v0.73.0 Borrowed Hardware — three days on an 8x H100 box, and what it means you should re-run.
- Lean install and live wiring — the full v0.71 line in narrative form.
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.