151 of the 226 pull requests in this release came from 44 people outside the maintainer.
Thank you: the Contributors section below names each of them and what they found or built.
v0.77.0 is a cut of main. It ends the one-release notice v0.76 gave: the config fields and
values that v0.76 loaded with a "Soup v0.77 will refuse it" warning now stop the load, and so do
fifteen settings that v0.76 accepted without a word and never applied. A config that loaded on
v0.76 can stop loading on v0.77, so before upgrading a working setup, run:
soup doctor --config soup.yamlWhat's New
- DPO, ORPO, SimPO and KTO train natively on Apple Silicon.
task: dpo,orpo,simpoand
ktowithbackend: mlxrun Soup's own MLX loop on TRL's objectives (DPO's sigmoid loss with
dpo_beta; ORPO and SimPO with no reference model; KTO withkto_betaagainst a reference
precomputed once from the base). MLX text SFT gains native DoRA (lora.use_dora: true),
training.eval_stepscounted in optimizer updates, the loss watchdog, and seeded runs
(training.seedandtraining.data_seedare applied, so a run reproduces).
lora.use_rslorais now applied on MLX and Unsloth (it was ignored there). - Layer streaming reaches DeepSeek-V3-family MoE models. Layer streaming, Soup's
implementation of layer-to-layer streaming of a frozen base (L2L, Pudipeddi et al. 2020),
now admitsmodel_type: deepseek_v3, gated on resident-vs-streamed parity forward and
backward. DeepSeek-V3's FP8 block-quantised checkpoints are dequantised at shard time, and
Kimi-K2-Base / Kimi-K2-Instruct configs are admitted behind a field-by-field check (a tiny
K2-shaped checkpoint streams bit for bit on CPU; nothing has been trained on K2 itself).
training.stream_expert_layout: per_expertstreams one routed expert at a time: on one RTX
5070 Laptop 8 GB, the same Moonlight-16B LoRA config peaked at 1.0 GB of GPU memory against
3.1 GB fused (NF4 experts against bf16, different cache tiers), at about 2.7x the step time
(one run each; the record's controlled pair reads 1.9 GB against 3.9 GB at about 2x,
record).
training.stream_recompute: off | autokeeps streamed activations instead of recomputing
them in the backward, with bit-identical gradients: on the same card's RAM tier a Mistral-7B
NF4 step is 22% / 17% / 8.5% faster at 512 / 1024 / 2048 tokens, with no gain on a read-bound
disk tier (record);
the defaultonkeeps the shipped behaviour. Also new:training.stream_loss_chunk(head
and loss in token chunks,sft) andtraining.stream_nf4_scale_cache(bit-identical, off
by default). Opt-in (stream_layers: true) and still BETA. - Provenance you can check.
soup registry push --data <file>records the training file's
SHA-256 and--idempotency-keymakes a push safe to retry;soup trainrecords the SHA-256
of a local training file at startup; on the transformers backend, resident, layer-streamed
and multi-GPU runs record the Hub commit of the base they loaded;soup ship --require-provenancechecks evidence against the adapter, task and source bytes, suite
version and verdict policy it was stamped with. - GRPO can score with an LLM judge.
training.reward_fn: judge_ranksends all of a prompt's
completions to one judge call and scores each against the others; the run must state
training.grpo_judge_max_calls, and a run that could exceed it is refused before the model
loads. Prompts and completions are sent to the judge host you configure. - Data, speech, recipes and the CLI.
pip install "soup-cli[documents]"provides the PDF
and DOCX readers forsoup data ingest;soup merge --low-memorymerges a plain LoRA
adapter into a safetensors base one tensor at a time, with values identical to the regular
merge; user-supplied files with a UTF-8 BOM load across the commands that read them; Sesame
CSM fine-tunes from raw transcript/audio pairs;qwen3.5-4b-dpoandqwen3.5-2b-dporecipes;
a RunPod controller behindsoup train --cloud runpod(not yet live-validated);
soup --version; and two reference pages generated from the code,
docs/config-reference.md
anddocs/cli-reference.md,
which the test suite keeps equal to what the code does.
The preprint (DOI 10.5281/zenodo.21771064) is
unchanged: no number it states was re-measured or corrected, and its measurements stay scoped to
the Soup versions it names. This release's DeepSeek-V3-family, FP8-source, per-expert,
chunked-loss and no-recompute streaming are outside what it measured; the next preprint version
covers them and cites L2L (Pudipeddi et al. 2020).
Breaking changes and upgrade notes
These are the CHANGELOG's [0.77.0] Upgrade notes, with the details.
1. Staged fields and deprecated values are refused at load. v0.76 warned; v0.77 stops the
load with one line per setting. soup train and every other command that reads a config exit
1 with Config validation error: (soup doctor --config exits 2), and
load_config_from_string raises ValueError with the same refusals (a value refusal keeps
Pydantic's Value error, prefix there). A config that leaves these unset, or writes them at
their defaults, loads as before. A config that sets both kinds gets both in one report, the
staged-field lines first.
- 31 staged fields (validated, read by nothing), each refused when set away from its
default, endingrefused as of v0.77. Delete the line.:training.long_context_grpo,
vision_grpo,quantize_ref_model,grace_codebook,grace_codebook_size,
grace_codebook_dim,lr_groups,early_stop_patience,citation_recall_threshold,
forgetting_eval_steps,forgetting_benchmark,forgetting_stop,checkpoint_eval_steps,
checkpoint_eval_metric,checkpoint_eval_tasks,checkpoint_keep_top,
convergence_window,convergence_rel_tol,rl_checkpoint_include_ref_model,
rl_checkpoint_include_rollout_buffer, anddata.video_dir,video_fps,video_maxlen,
image_min_pixels,image_max_pixels,image_resize_algorithm,split_thinking,
eval_on_each_dataset,resize_vocab,extend_conversation,skip_prepare_dataset.
None of them changed what a run did, so deleting them changes no result. For regression
gating and early stopping, usesoup train --gate <suite.yaml>. Asoup sweep --paramthat
sets one of them in any arm is refused the same way: the command exits1before the first
arm starts. When a staged field's own check fails too (for examplegrace_codebook: true
without a size and a dimension), only the staged line is shown, so no message asks for a line
that the next load refuses. - Two of them were never warned about.
training.rl_checkpoint_include_ref_modeland
rl_checkpoint_include_rollout_bufferwere staged after v0.76.0 and were in no release, so
v0.77.0 refusestruewith no warning release in between. An explicitfalseloads. data.remove_unused_columns: true. No trainer ever read it; configs written by
soup autopilotand run-config dumps from v0.75 and earlier carry it. Delete the line.training.quantization: 4bit/8bit, orload_in_8bit: true, on a task that never
quantises (distill,classifier,reranker,cross_encoder,prm,
moe_lora_routing,unlearn,asr). Delete the line or setquantization: none.soup ab --beta(andMsprtConfig(beta=...)): exits2. Remove it; lower--alphafor a
stricteraccept_h0.
2. Fifteen settings that v0.76 accepted silently and never applied are refused too. Each
message names the setting and what to change:
training.use_mod: trueon a route that never installs a Mixture-of-Depths router (#1752)- a non-default
training.moe_aux_loss_coeffonbackend: unslothor withstream_layers
(#1749) training.expand_layers(LLaMA Pro) with a LoRA rank (#1783), and ontask: pretrain(#1875)lora.r: 0ontask: pretrain(#1875)training.citation_faithfulontask: pretrain(#1843)training.neftune_alphaon the 14 tasks that never apply it (#1883)training.relora_stepswhere the loss has a frozen reference (dpo,ipo,kto,bco,
grpowithgrpo_betaabove 0, and blends naming them) (#1891)quantization: 8bitwithbackend: unsloth(#1946)- vision/audio
task: distill(#2014) - vision/audio SFT on
backend: unsloth(#2015) training.stream_layerswithtraining.use_cut_ce(#2023)llava/sharegpt4vrows ondpo,ipo,simpo,orpo,bcoandpreference
(thepixtral-dporecipe is retired) (#2064)lora.rank_patternorlora.alpha_patternwithbackend: mlx(#1996)lora.rank_patternorlora.alpha_patternwithbackend: unsloth(#2153)- a KTO
labelthat is not a boolean, one of the documented strings or exactly-1,0or
1(#2126; reported bysoup data validateandsoup train --dry-runbefore any model loads)
The CHANGELOG's Fixed entries describe a few more refusals of the same kind, each with the
fix in its message: training.reasoning_effort and train_on_eot on tasks whose formatter never
reads them (they now load on sft, tts and distill); data.chat_template with
backend: mlx; the known Kimi K2 Hub bases loaded resident on the transformers backend
(refused at load with Resident Kimi K2 is unsupported on Transformers 5.x, and Base and
Instruct are pointed at the stream_layers: true route; the two resident kimi-k2-* recipes
are marked unavailable and soup recipes use refuses them with exit 3);
training.freeze_layers / freeze_ratio with LoRA on a shape peft cannot restrict by layer (a
string lora.target_modules such as a regex or all-linear, lora.target_parameters,
lora.use_vera, or a plan that freezes every layer), refused when the model is built; an
eval-gate suite with no tasks or with a task name used twice; an ambiguous registry name:tag;
and an output path that is also an input of soup ingest, soup prune-prompt, soup ra-dit
or soup data best-of-n.
3. A LoRA target on a streamed embedding or head is refused when the model is built. Under
training.stream_layers, v0.76 checked only the literal names lm_head and embed_tokens at
load, so a regex or dotted spelling loaded (a regex then failed at its first save, or in peft
under task: dpo). On an untied checkpoint any spelling is now refused before a streaming
buffer is allocated; on a tied checkpoint, where v0.76 refused the literal names too, it now
trains and saves (#2082).
4. Python 3.11–3.13. requires-python is >=3.11,<3.14: Python 3.10 reached end of life
on 2026-10-01, and pip on 3.10 keeps installing v0.76.x. Python 3.13 is now supported; CI runs
it in the nightly and release runs, not in pull-request runs.
5. AWQ and GPTQ export are removed. soup export --format awq / gptq and
soup quantize --to awq / gptq now fail with a non-zero exit that names the formats that
remain (for soup export: gguf, onnx, tensorrt, bitnet, tq1_0, torchao,
gguf-ud); soup export lost --bits, --group-size and --calibration-samples (scripts
passing them exit 2), and the [awq] and [gptq] extras are gone. Both upstream projects are
archived. If you still need AWQ or GPTQ export, stay on v0.76.x. Related:
soup deploy autopilot --target rtx-4090-24gb now plans 4-bit QLoRA with vLLM instead of
writing quantization: awq, and its --measure-candidates examples read 4bit,8bit,fp8.
6. soup serve tool routes. POST /v1/tools/python now answers HTTP 501 without running
anything unless the host provides OS-level isolation, as POST /v1/tools/bash already did: it
runs where os.unshare can create the namespaces (Linux, Python 3.12+) or sandbox-exec is
available (macOS), and answers 501 on Windows and on Linux with Python 3.11. Both routes now
require --tool-auth-token on every bind, loopback included, and answer 401 without it.
--tool-auth-token also reads SOUP_TOOL_AUTH_TOKEN, which keeps the token off the command
line. To keep calling the two routes, start the server with the token and send
Authorization: Bearer <token> with each request. The isolation cuts the network; the code
still runs as the server's user, so use a long random token and see
docs/serving-and-export.md
for running the server for callers you do not fully trust. soup serve still starts without a
token on loopback, and the generation, adapter, web_search and thumbs routes are unchanged.
7. Behaviour that changes results, memory or exit codes.
training.gradient_checkpointingnow reaches the trainer. With the defaultfalse,grpo,
ipo,bco,reward_modelandonline_dpotrain with checkpointing off (TRL's own
default used to apply), and onbackend: unslothfalsenow disables Unsloth's checkpointing.
Settraining.gradient_checkpointing: trueto keep the memory you had. The shipped recipes,
templates and examples for those tasks already set it.distill,classifier,reranker,
cross_encoder,asrandunlearnnow honourtruetoo (their default is unchanged).lora.use_rsloraandtraining.freeze_layers/freeze_ratiowith LoRA are now applied
(they were ignored): rsLoRA runs on MLX and Unsloth train at the rsLoRA scale, and a frozen
layer gets no adapter, so such a run trains fewer layers than before, as the option always
documented. Their results change.- MLX SFT runs are seeded; a run started before this release cannot be reproduced.
- A
dpo,ipoorgrporun resumed from a checkpoint trained a freshly initialised adapter
before this release; re-run any such resumed training. prmand RAFTsftruns under gradient accumulation logged and clipped losses that were
gradient_accumulation_stepstimes too large; they now match the other trainers.training.unlearn_alpha: 0.0is now pure forget loss, as documented (it ran as 1.0).task: simpoon the transformers backend now caps the prompt todata.max_length // 2
tokens, as DPO and ORPO do.- The bundled eval scorers moved to provenance revision 7 and
mini_mmlugrew to 40 rows, so
a baseline written by v0.76 is not compared silently on the new scale: write it again. soup trainwith no TTY on stdin and no--yesnow refuses up front (pipingyno longer
answers the prompt).soup sweep, CMA-ES merge,soup drift-alarm,soup eval autoand
soup loop watch --detachexit non-zero when nothing succeeded;soup data validatecounts
rows the loader skipped as invalid;soup doctorchecks the config before it prints its
environment summary.- A streamed
soup trainon Linux (WSL2 included) now sets
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:Truebefore CUDA starts, unless you exported a
value of your own. - The Docker image is Ubuntu 24.04 + Python 3.12 on a CUDA 12.8 runtime and installs exactly
this release; the host needs a driver that supports CUDA 12.8 (570 or newer on GeForce). - The first layer-streamed run on a Hub base after upgrading re-shards into a new
<slug>@<commit>cache slot (disk space and time); the old slot is left in place. - The layer-streaming disk pre-flight now sizes the cache from the checkpoint's headers. A
dense base underquantization: 4bitis charged more, because embeddings, head and norms stay
at the stream dtype (Llama-3.1-8B 4.14 GB -> 5.70 GB), so a run that passed by less than that
margin is now refused before sharding; a fused MoE base is charged what it really writes.
Install / Upgrade
pip install -U soup-cli # or: pipx upgrade soup-cli
soup --version # soup v0.77.0
soup doctor --config soup.yaml # before the first run of an existing config- Python 3.10: pip and pipx stay on v0.76.x there. If pipx built Soup's environment with
Python 3.10, reinstall it on a newer interpreter, for example
pipx install --force --python python3.12 "soup-cli[train]". - AWQ / GPTQ export, or Python 3.10: pin
soup-cli<0.77, e.g.
pip install "soup-cli[train]<0.77"(v0.76.x supports Python 3.10 to 3.12), or export from a
separate environment with the upstream tools. v0.76.x receives security fixes only, until 0.78.0 is released
(SECURITY.md). - PDF / DOCX ingest:
pip install "soup-cli[documents]"; Markdown and TXT need no extra. soup servetool routes: start the server with--tool-auth-token <token>(or set
SOUP_TOOL_AUTH_TOKEN) and sendAuthorization: Bearer <token>to/v1/tools/pythonand
/v1/tools/bash.- Docker:
docker pull ghcr.io/makazhanalpamys/soup:0.77.0(alsolatest); the host
driver must support CUDA 12.8.
Security
This release tightens six behaviours: two on the soup serve tool routes (Upgrade notes,
item 6), one in the RunPod controller, and three that the CHANGELOG lists under Security (a
dependency floor, a size bound on judge and generation replies, and terminal-output
sanitising). Upgrading is enough for the last four; the tool routes need the token described
above.
Known Limitations
training.rl_checkpoint_include_ref_model/rl_checkpoint_include_rollout_buffergo from
accepted to refused with no warning release in between (they were staged after v0.76.0).- AWQ and GPTQ export are gone; pin
soup-cli<0.77if you need them. task: simpoon the transformers backend cuts a prompt longer thandata.max_length // 2
tokens even when the whole row would fit, until #1196 lands (#1185).training.fast_lorais verified on CPU (float32 and float64 against peft) only; the
bf16/fp16, NF4 and streamed-CUDA checks have not been run and no speedup is claimed (#792).training.stream_loss_chunkhas not been measured on a GPU; the peak-VRAM table is still
open (#1693).training.stream_recomputeis SFT only;autoworks on the RAM tier only; on a read-bound
disk tier it gains nothing, and at a high VRAM fill it is slower (measured on one RTX 5070
Laptop).- Kimi K2 admission is verified on CPU with a tiny K2-shaped checkpoint only; nothing has been
trained on K2. Its tokenizer needs--trust-remote-codeandpip install tiktoken. On a
full-size K2, setup briefly allocates about 22.5 GB of CPU commit per MoE layer before moving
it to meta (#2154). Resident K2 loads are refused at load, and Kimi-K2-Thinking and
Kimi-K2-Instruct-0905 have no supported route yet (#2104). stream_expert_layout: per_expertcovers the DeepSeek-V3 family only and costs step time
(about 2x to 2.7x on Moonlight-16B, see the record); a non-NVMe cache volume is warned about.- After upgrading, the first pinned layer-streamed run re-shards into a new
<slug>@<commit>
cache slot; the old slot stays on disk and nothing names or removes it (#2196). - The RunPod controller has not been run against a real RunPod account yet (#2098). It makes
one attempt, copies the results once with a 15-minute limit into a new directory next to the
output path, and deletes the Pod afterwards; a failed or timed-out copy removes that directory
when it is empty and names it in the error otherwise. Local input files are not uploaded, so the
base and the data must be reachable from the Pod. soup export --format ggufstill clones llama.cppb5270, which cannot convert Qwen3.5. Since
this release it refuses before cloning and names--llama-cpp <dir>; moving the pin is open
(#1911).- Base-revision binding covers the transformers backend; Unsloth and MLX loads, and local or
cached-path hints, are not bound yet (#1902). lora.rank_pattern/alpha_patternare refused on MLX and Unsloth until those trainers
apply them (MLX: #1996).freeze_layers/freeze_ratiowith LoRA need a list oflora.target_modules; a regex,
all-linear,lora.target_parametersand VeRA are refused when the model is built.soup merge --low-memoryrefuses adapters it cannot reproduce exactly (DoRA,
modules_to_save, rank or alpha patterns, embedding adapters) and names the regular merge instead.soup serve's/v1/tools/pythonis unavailable (501) on Windows and on Linux with
Python 3.11, as/v1/tools/bashalready was. Where it runs, a failure inside the submitted
code is reported astimed_out: truewith an emptystderr, as in v0.76.- On MLX,
task: preferencestays refused. - Still open from v0.76.0: fields that reach no consumer outside the staged table (#1814),
soup doctor --configcoverage (#1815), config-error wording (#1816) and vague messages for
rows of an unknown shape (#1818). - Layer streaming remains BETA and opt-in;
--cuda-graphsremains experimental.
Contributors
Grouped by person, in order of merged pull requests; each line says what they found or built.
Nurkhan Esenbek (@kok-o), 34
- #1749:
training.moe_aux_loss_coeffloaded on Unsloth and under layer streaming, where nothing applies it; now refused (#1412, reported by @maximilianfeix) - #1750: layer streaming re-copied decoder layer 0 at each step even when it was still resident; the copy is gone (#1354)
- #1842: removed expired release promises from the unlearning code and guarded every error message against new ones (#1405)
- #1843:
citation_faithfulloaded ontask: pretrain, whose trainer never applies it; now refused (#1406) - #1845: corrected a comment that claimed
model_copyre-runs validators (#1801) - #1847: Linux disk detection described an unrelated NVMe disk instead of the cache's own volume (#1800)
- #1848: trace and ingest parsers share one conversation renderer, so unrelated answers no longer pair up (#1809)
- #1926: a custom-eval file with a non-string
scoringnow names the field and line - #1927: a CI cell installs the declared core dependency floors and starts the CLI on them (#1802)
- #1928: an empty judge prompt file scored 0.0 without judging anything; it now fails closed (#1910)
- #1929: bounded the size of judge and generation replies (#1819)
- #1954: datasets with a UTF-8 BOM in JSON, CSV and TXT load (#1922, report by @VincentTLe)
- #1955: GGUF export names an architecture the pinned converter cannot handle before any work (#1911)
- #1957: merged Qwen3.5 text models exported to a GGUF that would not load; export now handles absent MTP tensors (#1912, reported by @feloau)
- #1958: ship scorers generate in bounded batches (#1759)
- #1972: resident transformers runs record the Hub commit of the base they loaded (#1902)
- #2013: the CLI works with standalone Click and with the Click that newer Typer vendors (#1803)
- #2014: vision/audio distillation was accepted and ignored by the text-only trainer; now refused (#1186)
- #2015: Unsloth vision/audio SFT silently ran on transformers; now refused (#1186)
- #2023:
stream_layerswithuse_cut_cenever installed CCE; now refused (#1206) - #2024:
soup trainrecords the training file's SHA-256 at startup (#1764) - #2025: ship evidence is bound to its adapter, task, suites and policy, checked by
--require-provenance(#1765) - #2037: six data quality commands scanned alpaca, preference and ShareGPT rows as empty and reported them clean (#1427)
- #2038: re-stamped evidence failed
--require-provenanceunless suites were alphabetical (#2035, reported by @abdulwaarith0) - #2079: the gate
soup ci initwrites passed a file with nine broken rows out of ten - #2081: the RunPod controller for
soup train --cloud runpod(#264) - #2093: a preference file with a
messagesprompt was auto-detected as chat and lost its pairs (#2090) - #2094: layer-streamed runs bind to the recorded Hub commit (#1902)
- #2096: PDF and DOCX ingest had no extra that installs its readers;
soup-cli[documents]does (#2057) - #2126: malformed KTO labels (null, floats, lists) trained silently; now refused (#2119)
- #2127: distributed workers resolve the base commit once and compare it (#1902)
- #2129: the
qwen3.5-4b-dporecipe (#275) - #2130: resident Kimi K2 configs failed only after the remote code loaded; now refused at load, with the streamed route named (#2104)
- #2160: the
qwen3.5-2b-dporecipe (#275)
Nariman Abdikarim (@Nari-Ab), 14
- #1602: square brackets in replies, prompts and dataset keys were read as Rich markup and could end
soup chat,diff,eval humananddata inspect/validate(#1596) - #1767:
copy_bundle_totakes a containmentrootfor apps with their own workspace (#1762) - #1831: descriptions for seven undocumented
soup.yamlfields (#1794) - #1840: seven help strings lost bracketed text such as
[deprecated]to Rich; escaped, with a ratchet over the live command tree (#1792) - #1841: bad
bench train,recipes verifyand--cuda-graphsinvocations are refused before the heavy imports (#1817) - #1868: model and output paths in
chat,diffandevalprint through the terminal sanitizer (#1864) - #1951: removed the deprecated AWQ and GPTQ export formats and extras (#1710)
- #1956:
soup compilenever handed the eval signal to DSPy, TextGrad and GEPA; wired through, with--task-lm,--reflection-lmand--engine(#1810) - #1971: loss-spike recovery attempts are counted across relaunches (#808)
- #2040: on Apple Silicon, transformers' threaded weight loading crashed
soup train(#2076, reported by @feloau) - #2041:
soup profilesized every run as LoRA; full fine-tunes now get their gradient and optimizer budget (#1423) - #2105:
soup --version(#2101) - #2106:
soup doctorprinted "All checks passed!" before refusing the config; the config is checked first (#2100) - #2114: an explicit
unlearn_alpha: 0.0silently became 1.0 (#2108)
Yang Bai (@ybai08), 12
- #1785: a
preference_loss_weightsblend led bydpooripostopped at step 0; it trains (#1425) - #1797: resumed
dpo,ipoandgrporuns trained a fresh adapter (#1768, reported by @bobbonauta) - #1828: a
dpo/ipoterm under asimpo/orpoprimary trains (#1425) - #1880:
training.stream_loss_chunk, the streamed head and loss in token chunks (#1693) - #1891:
relora_stepsmoved the frozen reference of the preference losses; measured and refused (#1835, their own report) - #1973:
training.fast_loraswitches the Fast-LoRA kernels on (#792) - #2082: a LoRA on the streamed embedding or head is refused at build whatever its spelling, and tied checkpoints load (#1048)
- #2102: the
stream_loss_chunkpeak-VRAM harness, with a CPU self-test (#1693) - #2117: the GRPO
judge_rankscoring function (#2047) - #2140:
gradient_checkpointingwas ignored by distill, classifier, ASR and unlearn; honoured (#797) - #2156: streamed runs never got the
expandable_segmentsallocator hint because CUDA started first; set before device detection (#2149) - #2175: the checkpointing test checks that the step trains, and covers ASR LoRA (#797)
@dryn85-max, 8
- #1846: native DPO on Apple Silicon
- #1855: MLX SFT ignored
training.seed, so no run reproduced; both RNGs are seeded (#1850, their own report) - #1857: MLX crashed on a split smaller than one batch (#1851)
- #2073: native ORPO on Apple Silicon (#2004)
- #2074:
training.eval_stepson MLX SFT (#1990) - #2097: native SimPO on Apple Silicon (#1999)
- #2111: native KTO on Apple Silicon (#2000, requested by @Amix29)
- #2116: SimPO on the transformers backend let a long prompt run past
data.max_length(#2112)
@ndablizov, 8
- #1899:
lora.use_rslorawas ignored on MLX and Unsloth (#1853) - #1901:
soup migratedropped the validation split and re-defaulted LoRA settings (#1807) - #1905: five commands exited 0 when nothing succeeded (#1808)
- #1906: Mistral's
consolidated.safetensorswas counted beside the shards, doubling downloads and parameter counts (#1806) - #1908:
soup data validatedid not count rows the loader skipped (#1887) - #1946:
quantization: 8biton Unsloth loaded in 16-bit with no word (#1811) - #1947: Liger was reported as applied on model types it has no kernels for (#1811)
- #1948: tests that name the refused and alias config fields and load every shipped config (#1814)
AmixDigital (@Amix29), 6
- #1769: native Sesame CSM speech fine-tuning from raw audio (#265)
- #1776: public prompt-encoding helpers for live eval and
soup ship --chat-template-kwargs(#1758, reported by @abdulwaarith0) - #1777: GGUF export reports its phases, streams the converter with
--verbose, and gains--no-install-deps(#1760) - #1778:
training.gradient_checkpointingnever reached seven TRL/HF trainers (#797) - #1920: native DoRA for MLX text SFT (#1918)
- #2115: the loss watchdog for native MLX SFT (#1989)
苏俊杰 (@Momoyeyu), 5
- #1771: PRM and RAFT logged and clipped losses G times too large under gradient accumulation (#1444)
- #1836: clearer Simplified Chinese wording for the 8B figure
- #1837: polished the Simplified Chinese v0.76.0 What's New
- #1924: MCQ scoring gave no credit to a bolded or quoted letter (#1442)
- #2067: polished the Simplified Chinese README (#1838)
Abdulwaarith Zakariyya (@abdulwaarith0), 5
- #1783: LLaMA Pro block expansion with LoRA trained only the original layers; refused (#1326)
- #1875:
task: pretrainwithlora.r: 0or LLaMA Pro failed inside peft; refused at load (#1813) - #1907:
soup registry push --datarecords a training file's SHA-256 (#1764) - #1934: an ambiguous registry
name:tagresolved silently to the newest entry (#1763) - #1964:
--idempotency-keymakes a registry push safe to retry (#1763)
Samarth Mukhija (@Samearth17), 5
- #1172: the pinning-cost harness (#379)
- #1287: the depth-versus-bytes reconstruction harness (#379)
- #1288: the repeated-backward reconstruction harness (#379)
- #1289: the layer-count control sweep across the 48-to-64 layer boundary (#379)
- #1962: layer streaming reports each drive's direct-I/O state (#1615)
@vaputa, 4
- #1839:
soup uichecks the Host header on a loopback bind (#1829) - #2051:
data.chat_templatewas silently ignored on MLX; refused (#2075, reported by @feloau) - #2052:
soup trainwaited for an answer nothing could give when stdin is not a TTY (#2077) - #2155: the agent, tokenizer, bench, draft, edit, shrink, diagnose, can, generate and autopilot readers mishandled a UTF-8 BOM in user files; accepted (#2136, reported by @yunaremaia)
Srinivasan R (@Srinivasan8888), 4
- #1832:
soup loop watchlearns fromsoup serve --record-thumbsfeedback (#1440) - #1966: the loop checks the thumbs table's columns before it starts (#1440)
- #1968: one- and two-pair loop harvests train instead of exiting (#1909)
- #1980: RL checkpoint manifests claimed reference-model and rollout-buffer state no save wrote (#808)
Pernav Jain (@here-2007), 3
- #1779: a NaN or infinite baseline let
soup eval gatepass (#1773, reported by @taljeon) - #1780: KL calibration under-reported large divergences (#1772, reported by @taljeon)
- #2060: the GRPO gradient watchdog names the parameters that went non-finite, with @harshitthek (#342)
Tal (@taljeon), 3
- #1821:
soup eval gatepassed a suite with no tasks (#1798, their own report) - #1863: leaderboard CSV broke on names with commas or quotes (#1834, their own report)
- #1893: duplicate gate task names overwrote baseline evidence (#1824)
Dipak Chaudhari (@dchaudhari7177), 2
- #1184:
soup loop watchcould not present thesoup servetool token, so its deploy stage was refused;--tool-auth-tokenadded (#1139) - #1587:
reasoning_effortandtrain_on_eotwere refused ontts, where they apply, and accepted on tasks that ignore them (#806)
Younes Beriane (@drakeo338), 2
- #1709: the streaming disk pre-flight sized a reusable cache as if it were rewritten (#1703)
- #2063:
soup adapters checkanddiffcrashed on bfloat16 adapters (#2058)
Faisal Fayaz (@Faisal-Fayaz), 2
- #1756: tool-call scorers credited a JSON number as a boolean (#1755)
- #1770:
registry.call_toolfor MCP callers without a server (#1761)
Areen Agrawal (@Areen-09), 2
- #1774: a failed Lambda run prints its remote log tail before the instance is terminated (#1705)
- #2120: the DPO and KTO row layouts documented as tables the tests read back (#2086)
Aditya Pratap Singh (@akkupratap323), 2
- #1791:
soup doctor --configreported differently on a config and its full dump (#1330, after @Yi-111-a's #1336) - #1873: non-object JSON rows crashed five data commands (#1860)
Vincent Le (@VincentTLe), 2
- #1923: the shipped GRPO, IPO, BCO,
reward_modeland online-DPO configs set gradient checkpointing explicitly - #2043: the shipped-config test pins its task list (#1862)
Shivansh Shukla (@ShivanshShukla), 2
- #1952: the Web UI left one temporary config file per run (#1464)
- #1960:
soup can runleft its extraction directory behind on failure (#1464)
Abhishek Jha (@SpinachDigital), 2
- #1981: Unsloth ignored
gradient_checkpointing: false - #2062: the dpo and ipo blend terms are pinned to their own config fields (#1645)
Rahul Seervi (@Rahul-cs50), 2
- #2059:
rollout_backend: rulerpointed at a package that is not on PyPI (#2046) - #2110:
soup ui --publicopened0.0.0.0, which Windows cannot reach (#2054)
One pull request each
- Sohaib Kamash (@Nick-800), #1708: out-of-memory hints now suggest lowering
data.max_length(#1694) - Batyrkhan (@Batyrkhantzy111), #1732:
soup serve --backend sglanganswered from the base model instead of the adapter (#1724) - Matt Van Horn (@mvanhorn), #1757:
training.use_modloaded where no router is installed; refused (#1752) - Tanmay Garg (@Tanmay9223), #1775: PRM, MoLE and PPO use the shared warmup, and PPO honours
--deepspeed(#805) - Vladimir Babin (@chiliec), #1782: tests that keep the Unsloth tip to tasks with an Unsloth setup (#1186)
- Nehal K (@sloemo01), #1784: a dropout opt-in for the single-projection Fast-LoRA kernel (#839)
- Aykut Güney (@KeuqS), #1795: two commands and twenty options had no
--helptext; written, with a completeness test (#1793) - Emre K. (@kocaemre), #1822: dataset previews and review panels print through the terminal sanitizer (#1812)
- Abhinay Kumar (@abhinyaay), #1833: gate commands name the missing file and the
[train]extra (#1830) - Alexis (@bernalalexis-try), #1872:
soup shiperrors strip control bytes before printing (#1869) - @DBVamsi, #1883:
training.neftune_alphais refused on the 14 tasks that never apply it (#1820) - @dipesh-singh07, #1903: oversized integer baselines raised
OverflowErrorinstead of a usage error (#1865) - George Tonmoy Roy (@george07-t), #1930: one warning per skipped row flooded the console (#1888)
- Aaditya Desai (@aadityad12), #1953: terminal output also strips bidi controls and invisible separators (#1861)
- Kuanysh (@kuanysh228), #2006:
soup merge --low-memorymerges a LoRA adapter tensor by tensor, identical to the regular merge - Mohammad Hijjawi (@MohammadHijjawi97), #2007:
soup sweep --strategy randomhung on a value listed twice - martin (@Martini147), #2018: four commands could overwrite an input with their output (#1422)
- @Shutaru, #2042: the QuEST development follow-up record, failed gates in front (#674)
- Vishal Kumar Singh (@Vishalkumarsingh6428), #2064: vision rows on preference tasks failed after the model loaded; refused (#1867)
- Aaron Probha (@AaronProbha18), #2113:
mini_mmlusat at 1.000; it now has 40 rows and a balanced key (#1192) - Vansh Sharma (@VanshSharmaPES), #2145:
freeze_layers/freeze_ratiodid nothing under LoRA; the freeze now reaches peft (#1432), continuing @AmirF194's #1494 with both of its commits kept - Daivik Awasthi (@daivikawasthi01), #2176: two test assertions read raw console output and failed whenever Rich emitted colour (#2173)
Reports that led to fixes in this release: @feloau (#1912, #1913), @bobbonauta (#1768),
@maximilianfeix (#1412), @Ercaner1988 (#1677), @VincentTLe (#1922), @abdulwaarith0 (#1758,
#1760, #2035), @taljeon (#1772, #1773), @yunaremaia (#2136), @Amix29 (the #2000 request),
@akkupratap323 (the #1953 reproduction), @abdulbasit-ogunrinu (the agreed #1427 plan),
@Yi-111-a (#1336).
Full list
Every change, with its issue and pull request, is in
CHANGELOG.md; its
[0.77.0] section opens with the same upgrade notes as above.
---8<--- release body ends here ---8<---