github MakazhanAlpamys/Soup v0.77.1
v0.77.1 — data commands keep their input; plan and apply refuse what train refuses

4 hours ago

22 of the 28 pull requests in this release came from 11 people outside the maintainer.
Thank you: the Contributors section below names each of them and what they found or built.

v0.77.1 is a cut of main after v0.77.0, not a backport: it carries every pull request merged since that tag. The fixes that matter most are three. soup data commands no longer write their output over their own input. soup plan and soup apply now refuse the configs soup train refuses. And the README's Docker example works again. Nothing in v0.77.0 is taken back; coming from v0.76.x or older, read the v0.77.0 notes first, because a config that loaded on v0.76 can stop loading on v0.77, and run:

soup doctor --config soup.yaml

Fixes that matter

  • soup data commands no longer overwrite their input when --output names it. Eighteen commands used to write their result over one of their own inputs and exit 0; the original could not be recovered. Each now compares its outputs with its inputs before it reads anything, and refuses the same file under any spelling: the same string, ./x, sub/../x, the absolute path, a case variant on a case-insensitive file system, a hard link or a symlink. The message names both paths and says what to change, for example --output './d.jsonl' is the same file as the input 'd.jsonl'; choose a different --output. An output that is a different file works as before, and default output names are unchanged.
    • decontaminate, toxicity, langdetect, pii and educational (#2245, closes #2225). Their default output names (clean.jsonl, toxicity.jsonl, langdetect.jsonl, pii.jsonl, educational.jsonl) used to replace an input of the same name. decontaminate also compares --output with --benchmark-file. On Windows a trailing space or dot, ::$DATA and a junction are refused too. Exit code 1.
    • Thirteen more (#2261, refs #2226): lint, doctor and topics (the JSON report replaced the dataset), from-traces (the preference pairs, often an empty file, replaced the trace file), canary insert, sample, dedup, filter, convert, merge, active-sample, augment and evolve (the result replaced the input). A default output name that the input already has is refused too: merged.jsonl, prefs.jsonl, active_samples.jsonl, augmented.jsonl. canary insert also refuses a --manifest that is the dataset or the --output; before, the dataset write replaced the manifest that had just been written, and the only record of the inserted secrets was lost. Exit code 1, except lint (3) and augment and evolve (2), which keep the code of their other path errors.
    • soup data clean already refused this and is unchanged.
  • soup plan and soup apply refuse the configs soup train refuses (#2242). They checked only for unknown keys, so a config with a staged field set (training.early_stop_patience: 5), a refused deprecated value (data.remove_unused_columns: true) or any other schema error got a plan (exit 0), and soup apply and soup apply --dry-run accepted it. Both commands now exit 1 with the Config validation error: lines soup train prints for the same file, write no plan, and leave an existing state file unchanged (so it is not marked applied). A valid config plans and applies as before. This is the gap the v0.77.0 notes said was open.
  • The README's Docker example works again (#2244, closes #2229). docker run without -t gives soup train a stdin that is not a terminal, and since v0.77.0 such a run needs --yes; the README example exited 3. It now passes --yes, and the four translations follow.
  • Five statements about v0.77.0 now match the code (#2244). They were wrong in the v0.77.0 CHANGELOG, SECURITY.md, docs/backends-and-ops.md and the README What's New; no behaviour changed, the only source edits are two comments.
    • soup doctor --config: the System, GPU, System Resources and Dependencies tables still print first; what moved is the All checks passed! line. The config is checked before it, and a refused, missing or unreadable config exits 2 without it. The text had said the config is checked "before the environment summary".
    • A KTO row whose label is not a boolean, a true/false-style string or exactly -1, 0 or 1 is dropped with a warning (soup train names the first such row and stops only when none is left; soup data validate --min-valid-fraction 1.0 exits 2). It is not refused at load, as the text listed it; the README says fourteen silently ignored settings are refused, not fifteen.
    • A dpo or ipo term under a simpo or orpo primary trains (since #1828), against an adapter-off reference; only with full fine-tuning, which has no adapter to switch off, does it still stop at the first step, with a message that names the fix. The #1785 entry had said it always stopped.
    • Telemetry: as released, nothing is sent. The bundled analytics key is a placeholder, so an opted-in command prints Notice: telemetry is not yet live. and makes no network request. Only an operator's own SOUP_POSTHOG_KEY (and optionally an HTTPS SOUP_POSTHOG_ENDPOINT) gives one HTTPS POST at command exit; the payload list now names every field it carries.
    • Which commands refuse a staged field or a deprecated value: soup train exits 1, soup doctor --config exits 2, soup recipes verify --config and soup ship --config exit 3. soup plan and soup apply did not (fixed above).

What's New

  • GRPO trains natively on Apple Silicon. task: grpo with backend: mlx was refused at config load; Soup's own MLX loop now generates num_generations completions per prompt from the current policy, scores them with the built-in accuracy or format function and takes one policy-gradient step per update. The objective is the one the transformers path trains on TRL 0.29.1 (loss_type: dapo, group-scaled scores, epsilon 0.2, one iteration, token-level importance sampling, a k3 KL against the base model with training.grpo_beta), every setting is recorded in adapter_config.json, and held-out prompts are scored once after training as val_reward. A non-finite loss or gradient skips the update. Try task: grpo, backend: mlx, reward_fn: accuracy. This is the dense baseline, step 1 of #1976 (#2182 by @dryn85-max).
  • soup infer --backend mlx. Native text LoRA adapters and MLX base models load and generate without Torch or PEFT, through a shared strict loader that checks every adapter name, shape and finite value and refuses unsupported tasks, controls, targets and variants. Dense and genuine 4-bit bases are covered, and base-only generation works. Part 1 of #1986; soup chat is scoped separately (#2121 by @Amix29).
  • soup ship --progress jsonl. Versioned start, progress, end and error events on stderr, with explicit identities for noise-floor repeats and a fixed execution_aborted code when a group aborts. It is opt-in: ordinary output, stdout and exit codes are unchanged; in JSONL mode an unexpected exception becomes exit 1 with start/error events and no traceback (#2171 by @kok-o).
  • Unknown config keys get better hints. A key written the way another library names it now names the Soup field: learning_rate suggests lr, num_train_epochs suggests epochs, training.lerning_rate suggests training.lr rather than an unrelated field. The suggestion cutoff is 0.65 in every section. "use X" is for those names and one-edit typos of them; a name that is only similar gets the "did you mean" ranking, and per_device_eval_batch_size, per_gpu_eval_batch_size, eval_batch_size, warmup_steps and warmup_step, which have no Soup counterpart, get a sentence saying so at the top level and under training: alike. The hints are diagnostics; the schema still decides what loads (closes #2099; #2138 by @Nari-Ab).
  • Two reads of a streamed routed expert per step instead of three (experimental). build_streamed_model(..., two_read_experts=True) keeps the decoder checkpoint but no longer fetches routed experts in its replay: the forward and the expert's own backward read each expert once, and the router reuses the forward's top-k choice while its scores stay differentiable. It needs the per_expert layout and reaches DeepSeek-V3-family bases only. It is API only, off by default: there is no config field, flag or default change. A forward hook on a two-read layer, its MoE block or its routed experts is refused with an error. On CPU the losses and gradients equal the resident model's bit for bit; no hardware speed record is part of this release (#2158 by @Batyrkhantzy111).

Also fixed

  • Streamed LoRA on an untied embedding or head saves and resumes. The adapter saves with PEFT's defaults and resumes through Trainer or load_adapter with every tensor kept; reloads keep the runtime's device map; DPO's reference adapter can attach through the streaming wrappers (completes item 1 of #1048; #2159 by @kok-o).
  • Building a streamed fused-expert MoE no longer asks the CPU for each full expert tensor. The skeleton is built on meta, but each MoE layer first created its expert tensor on the CPU (15 GB for DeepSeek-V3, 22.5 GB for Kimi K2 in bf16) before moving it; on Linux with strict overcommit, a small machine, or Windows with too little page file this failed with DefaultCPUAllocator: can't allocate memory or not enough memory. Every CPU request of 1 MiB or more is now made on meta; a model that registers a buffer that large is built the old way with the buffer named in a warning. Closes #2154 (#2157 by @ybai08).
  • /v1/tools/python reports what failed. A timeout is timed_out: true with exit_code: 124 and no output; other process failures carry their stdout, stderr and exit code with timed_out: false (output overflow is exit_code: 1); every HTTP 401 from the tool routes carries WWW-Authenticate: Bearer. Closes #2194 (#2204 by @Nari-Ab).
  • soup profile --gpu and the MCP profile tool know the RTX 30-series laptop GPUs. --gpu "rtx3060 laptop" was "Unknown GPU", and the laptop 3060 has 6 GB, not the desktop card's 12; each part now has its own entry with NVIDIA's memory, the names the driver reports resolve to it, and a size written as a word ("A100 40GB") reaches the matching entry (#2144 by @abdulwaarith0).
  • Adapter commands name the missing dependency. soup adapters check and the others reported corrupt weights when numpy or safetensors was missing; read-only operations now ask for numpy, and merge and arithmetic for numpy and safetensors (closes #2056; #2141 by @Nari-Ab).
  • soup eval gate handles a malformed suite. Malformed YAML and non-mapping roots ([], false, 0, "") exit 3 with a file-specific message; before, malformed YAML and a list or scalar root exited 1 with a bare Error: TypeError or ParserError line, and an empty root such as [] exited 3 with a generic validation message; soup train --gate exits 1 and the training callbacks keep their fatal-failure policy (#1878, reported by @taljeon; #1895 by @Nari-Ab).
  • soup export cleans up after a failed step. The temporary .soup_merge_tmp_<adapter>/ directory is removed when llama.cpp is not found, a clone or install fails, or the merge dies while saving, for the gguf, onnx, tensorrt, bitnet and gguf-ud paths; before, a multi-gigabyte directory was left next to the adapter. It removes only a directory that export created: one that was already there is left alone, and the output says so (#1464 by @ShivanshShukla in #2164).
  • Spike recovery hints are written safely. They refuse symbolic-link targets and are replaced atomically, which keeps other hard links and the previous hint when the write fails, without consuming an attempt (#2169 by @Nari-Ab).
  • Langfuse zero scores are kept. soup ingest --source langfuse --logs dropped scores of 0, 0.0 and false; they now reach the thumbs-down signal and preference-pair construction. Only a missing or null score falls back to rating (closes #1856; #1871 by @akkupratap323).
  • A malformed model file no longer stops the estimate. A model's config.json that is malformed, or states a figure no model has, is treated as an unreadable config.json by the VRAM pre-flight, soup plan, soup profile and the MCP profile tool (soup profile prices a guessed shape and says so; soup plan records that it could not price the run); a malformed .safetensors header is skipped and the parameter count comes from config.json (approximate); and soup infer --backend mlx refuses a malformed native adapter's adapter_config.json with a message naming the file.
  • A mixture-of-experts model known only by its cached config.json is priced with all its experts, not as a dense model of a few billion parameters; the estimate's note says the count is approximate.
  • Names from a config or a command line reach the terminal cleaned. soup profile prints the LoRA target modules, and soup adapters bisect the checkpoint ids, with control characters and bidi marks removed. soup infer --backend mlx names the one option it refuses (--task, --batch-size or --cuda-graphs).

Changed

  • One peak-VRAM estimate for soup train's pre-flight, soup profile, the MCP profile tool and soup plan. They priced the same run with two formulas in two units, and neither charged the logits and loss chain that decides long, large-vocabulary runs. All four now use one estimate that reads the model's config.json and safetensors headers (never the weights) and prices weights, adapters, gradients, optimizer state, activations, logits, the 4-bit dequantization copy and overhead, calibrated on 39 measured runs (benchmarks/gate-2049-resident-vram.md). Details under Behaviour changes (#2146 by @abdulwaarith0).
  • External programs are started by an absolute path found on PATH (#2205), and on Windows the current directory is left out of the program search (#2213). Both under Behaviour changes.
  • training.curriculum_dynamic is documented as telemetry. Its weights are logged to curriculum_history.jsonl for soup runs curriculum-curve and do not change which samples a batch contains; the schema descriptions, reference entries and training guide now say so. Behaviour is unchanged (#2142 by @Nari-Ab).

Tests, records and benchmarks

  • A measurement record for selective attention checkpointing of streamed NF4 (Mistral-7B, one RTX 3090 on Windows, five alternating pairs per comparison). Only saving Q/K/V/O at sequence length 2048 met the pre-registered rule: 3.1% less measured time, interval 3.0% to 3.4%; the other three arms were inconclusive or slower. The installer is benchmark-only and nothing in soup train uses it (closes #2050; #2161 by @Shutaru).
  • The stream_loss_chunk_vram harness runs each arm in a process of its own, because only the first arm per process got the RAM tier. It is step 1 of #1693's order: the rerun and the chunked-charge fix follow (#2151 by @ybai08).
  • The test suite passes under pytest 9.2.0, released after the cut: a Windows-path test no longer leaves os.fstat and os.name faked while pytest reads its capture file (closes #2286, reported by @abdulwaarith0; the test change comes from #2284 by @Nari-Ab).
  • A fresh-process streaming test now imports this tree's soup_cli and has a timeout (#2208 by @ybai08); the GGUF progress test no longer fails on a machine with a real ~/.soup/llama.cpp (closes #2198; #2207 by @Nari-Ab); effective vision and audio checkpointing is covered by 28 offline cases (closes the last item of #797; #2180 by @SauravMukherjee44); the atomic writers are pinned to stage their temporary file in the destination directory, with a mutation check per writer (closes #2178; #2179 by @SauravMukherjee44).

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. The opt-in two-read routed experts, saving a streamed LoRA on an
untied embedding or head, and the benchmark-only selective attention checkpointing record are
outside what it measured.

Behaviour changes to know

  • A script that wrote a soup data result over its own input now fails. soup data dedup d.jsonl -o d.jsonl (or sample, filter, convert, merge, pii, toxicity and the rest listed above) used to exit 0 and replace d.jsonl; it now exits non-zero before reading anything. If you wanted an in-place edit, write to a new file and rename it. soup data clean already refused this.
  • soup plan and soup apply now refuse what soup train refuses (#2242), with exit 1 and no state written. A pipeline that planned a config containing a staged field, a refused deprecated value or any schema error will now stop at soup plan; delete the line the message names (run soup doctor --config soup.yaml to see them all). With several unknown keys, every line of the message is now indented, as soup train prints it.
  • Soup starts external programs by an absolute path found on PATH (#2205). nvidia-smi, sysctl, the disk-probe tools, git, ollama, the llama.cpp binaries, trtllm-build, docker, the Modal CLI, gh, ssh and scp (RunPod and Lambda controllers), the code-sandbox tools, accelerate for soup train --gpus and the soup adapters bisect --eval-command program now run by the absolute path found in an absolute PATH directory. Empty and relative PATH entries (., bin, and on Windows \bin or C:bin) are not searched, and neither is the current directory. If a tool is only in the current directory or in a relative PATH entry, Soup no longer finds it: put its directory on PATH as an absolute path, or give the tool's path. Related edges: on Windows a set but empty PATHEXT falls back to .COM;.EXE;.BAT;.CMD; soup adapters bisect exits 2 before the first probe when its --eval-command program is not on PATH (and when the checkpoint id fills in the program name, a name not on PATH counts as a failed probe); the macOS code sandbox runs sandbox-exec from /usr/bin/sandbox-exec only; a llama.cpp checkout given as --llama-cpp . runs its binaries by absolute path; soup train --cloud lambda refuses an output with a part that starts with -, as --cloud runpod already did; and both controllers stop before launching with "OpenSSH ssh and scp must be installed and on PATH" when they are missing.
  • On Windows, a program that is only in the current directory is no longer started by bare name (#2213), by soup or by the programs it starts, eval scripts and the scripts behind a custom reward_fn included. soup sets NoDefaultCurrentDirectoryInExePath=1 for itself when it is not set. A value you already set is kept, and any non-empty value, 0 included, already leaves the current directory out, so no setting brings the old search back. To run a program from the current directory, give its path (./tool.exe, or an absolute path in quotes) or put the directory on PATH as an absolute path. soup adapters bisect --eval-command is split with POSIX shell rules, in which a backslash is an escape, so a Windows path there takes forward slashes or quotes; .\tool.exe would reach the program as .tool.exe.
  • The VRAM pre-flight prices runs differently (#2146). Inside the range its estimate was fitted on (dense models of 3B and below on one 6 GB card), soup train's pre-flight now refuses some long-sequence, large-vocabulary runs and some runs without gradient checkpointing that it let through, and --allow-oom-attempt still launches them. Outside that range (a larger model, a mixture-of-experts model, medium or selective checkpointing, use_liger or use_cut_ce, backend: unsloth; none of these is among the 39 measured runs) a run that does not fit gets the estimate as a warning, with a footnote that it may overstate the peak, and starts, unless its weights, the CUDA context, its adapters and the gradients of the parameters it trains (plus their optimizer state for the AdamW optimizers, unless GaLore replaces the optimizer on sft, tts or pretrain) alone are more than the card holds, which is refused there too (--allow-oom-attempt launches it). The shipped longcontext template (an 8B model at 131,072 tokens) is outside the range, and its header says how to turn on use_liger. soup profile's numbers change and its JSON gains the exact bytes per term, the fit verdict, where the model's shape came from and gradient_checkpointing_tier (off, full, medium or selective); gradient_checkpointing stays the config's own value. Reading a Hub model's shape can now reach the Hub from the pre-flight, soup profile and soup plan (which prints a dim line before it does), and writes its config.json into the Hugging Face cache, unless HF_HUB_OFFLINE or TRANSFORMERS_OFFLINE is set; soup apply compares hashes only and does not read the model; the MCP profile tool reads only a local directory or the local cache. A Hub model with no readable config.json is priced from a shape guessed from its name. soup plan records peak_vram_gb: null with a peak_vram_reason when it cannot price the run, instead of a fixed 8.0 GB; an older state file still loads. gradient_checkpointing is priced as the trainer applies it: auto resolves on the card as sft does, selective is priced as no checkpointing (an upper bound), and tasks other than sft and tts checkpoint fully. Tasks without an LM head (classifier, reranker, cross_encoder, embedding, reward_model) are charged no logits.
  • /v1/tools/python answers differently on failure (#2204). A caller that treated every non-success as a timeout will now see timed_out: false for ordinary failures, with the process output in the reply; a timeout still reports timed_out: true, now with exit_code: 124 and no output.

Install / Upgrade

pip install -U soup-cli               # or: pipx upgrade soup-cli
soup --version                        # soup v0.77.1
soup doctor --config soup.yaml        # before the first run of an existing config
  • From v0.77.0: nothing to change in a valid soup.yaml. A Windows setup that relied on a tool in the current directory, and a script that wrote a soup data result over its input, need the changes described above.
  • From v0.76.x or older: read the v0.77.0 notes first. Python 3.10 stays on v0.76.x (pip install "soup-cli[train]<0.77"); AWQ and GPTQ export were removed in v0.77.0.
  • Docker: docker pull ghcr.io/makazhanalpamys/soup:0.77.1 (also latest); the host driver must support CUDA 12.8.

Security

This release tightens how external programs are started. Upgrading is enough; the one visible effect on a setup is described under Behaviour changes.

Known Limitations

New in this release:

  • The pre-flight's estimate was fitted on dense models of 3B and below on one 6 GB card (benchmarks/gate-2049-resident-vram.md). No model of 7B or more, no mixture-of-experts model, no medium or selective tier, no fused loss and no Unsloth run was measured, so for those it warns and starts instead of refusing. A model known only by its cached config.json is counted from that file (approximate for a mixture-of-experts one).
  • A distill soup.yaml with training.minillm_enabled: true, training.minillm_teacher_mix_ratio: 0 and no training.minillm_on_policy loads only under soup train --minillm-on-policy, which sets the field before validation. soup plan and soup apply have no such flag, so they refuse that config (minillm_enabled with minillm_on_policy=false requires minillm_teacher_mix_ratio > 0). Write training.minillm_on_policy: true in the YAML.
  • soup data persona-mix still writes over its --prompts input when --output names it. mix, forge, generate, gen-magpie, recipe and canary check have not been checked yet. Both are tracked in #2226.
  • MLX GRPO is the dense baseline: quantization: 8bit, lora.r: 0, custom or ensemble reward_fn settings and non-text modalities are refused at load, and --resume is refused because only the adapter is saved (#1976). Native MLX inference covers text LoRA adapters only; soup chat on MLX is open (#1986, #2123).
  • two_read_experts has no hardware speed record yet; its scope is discussed in #2170.

Carried over from v0.77.0:

  • task: simpo on the transformers backend cuts a prompt longer than data.max_length // 2 tokens even when the whole row would fit, until #1196 lands (#1185).
  • training.fast_lora is verified on CPU (float32 and float64 against peft) only; no speedup is claimed (#792).
  • training.stream_loss_chunk has not been measured on a GPU and its peak-VRAM table is still open (#1693).
  • training.stream_recompute is SFT only; auto works on the RAM tier only, gains nothing on a read-bound disk tier, and at a high VRAM fill it is slower.
  • 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-code and pip install tiktoken. 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_expert covers the DeepSeek-V3 family only and costs step time (about 2x to 2.7x on Moonlight-16B); a non-NVMe cache volume is warned about (#2170).
  • 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); local input files are not uploaded.
  • soup export --format gguf still clones llama.cpp b5270, which cannot convert Qwen3.5; it refuses before cloning and names --llama-cpp <dir> (#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_pattern are refused on MLX and Unsloth until those trainers apply them (MLX: #1996).
  • freeze_layers / freeze_ratio with LoRA need a list of lora.target_modules; a regex, all-linear, lora.target_parameters and VeRA are refused when the model is built (#2201).
  • soup merge --low-memory refuses 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/python is unavailable (501) on Windows and on Linux with Python 3.11, as /v1/tools/bash already was.
  • On MLX, task: preference stays refused (#2202).
  • Still open from v0.76.0: fields that reach no consumer outside the staged table (#1814), soup doctor --config coverage (#1815), config-error wording (#1816) and vague messages for rows of an unknown shape (#1818).
  • Layer streaming remains BETA and opt-in; --cuda-graphs remains experimental.

Fixed since v0.77.0 and no longer limits: the 22.5 GB CPU commit while a full-size Kimi K2 is set up (#2154) and the empty stderr of a failing /v1/tools/python call (#2194).

Contributors

Grouped by person, in order of merged pull requests; each line says what they found or built.

  • Nariman Abdikarim (@Nari-Ab), 7: unknown-key hints that know other libraries' parameter names (#2138); soup eval gate exits 3 on a malformed suite (#1895, reported by @taljeon); adapter commands name the missing dependency (#2141); /v1/tools/python failure diagnostics and WWW-Authenticate (#2204); safe spike recovery hints (#2169); the curriculum_dynamic telemetry contract (#2142); the GGUF progress test isolated from a developer's own converter (#2207); the Windows-path test change that keeps the suite green on pytest 9.2.0 (from #2284)
  • Yang Bai (@ybai08), 3: the streamed fused-expert MoE build without a CPU allocation first (#2157); the stream_loss_chunk_vram harness with one process per arm (#2151); the fresh-process streaming test on this tree (#2208)
  • Nurkhan Esenbek (@kok-o), 2: save and resume of streamed LoRA on an untied embedding or head (#2159); soup ship --progress jsonl (#2171)
  • Abdulwaarith Zakariyya (@abdulwaarith0), 2: the single peak-VRAM estimate and its calibration on 39 runs (#2146); the RTX 30-series laptop GPUs (#2144); the pytest 9.2.0 diagnosis and fix (#2286)
  • Saurav Mukherjee (@SauravMukherjee44), 2: vision and audio checkpointing coverage (#2180); the atomic-writer destination-directory pin (#2179)
  • dryn85-max (@dryn85-max), 1: native GRPO on Apple Silicon (#2182)
  • AmixDigital (@Amix29), 1: native MLX inference, soup infer --backend mlx (#2121)
  • Batyrkhan (@Batyrkhantzy111), 1: two reads of a streamed routed expert per step (#2158)
  • Aditya Pratap Singh (@akkupratap323), 1: Langfuse zero scores kept as negative feedback (#1871)
  • Shivansh Shukla (@ShivanshShukla), 1: soup export removes its temporary merge directory on failure (#2164)
  • Shutaru (@Shutaru), 1: the selective attention checkpointing measurement for streamed NF4 (#2161)

Reports that led to fixes in this release: @taljeon (#1878), @abdulwaarith0 (#2286).

Full list

Every change, with its issue and pull request, is in
CHANGELOG.md; its [0.77.1] section lists the same changes. Compare with the previous release: v0.77.0...v0.77.1.

Don't miss a new Soup release

NewReleases is sending notifications on new releases.