MakazhanAlpamys / Soup

MakazhanAlpamys / Soup

Soup Fine-tune and post-train LLMs in one command. No SSH, no config hell. Website · Quick Start · Config · Docs · Commands · Models · Discord · Product Hunt Soup 让你通过一条命令即可完成大语言模型(LLM)的微调与后训练。无需 SSH,告别配置地狱。网站 · 快速入门 · 配置 · 文档 · 命令 · 模型 · Discord · Product Hunt

Soup turns the pain of LLM fine-tuning into a simple workflow. One config, one command, done. Soup 将大模型微调的痛苦转化为简单的工作流。一个配置文件,一条命令,搞定。

pip install "soup-cli[train]" # add [train] to fine-tune; bare soup-cli is the light CLI pip install "soup-cli[train]" # 添加 [train] 以进行微调;仅安装 soup-cli 为轻量级命令行工具

soup init --template chat soup train

Fine-tune an 8B model on a 4 GB laptop GPU. Layer streaming keeps the frozen base out of VRAM and feeds it to the GPU one decoder layer at a time. 在 4GB 显存的笔记本 GPU 上微调 8B 模型。层流式传输(Layer streaming)技术将冻结的基座模型移出显存,并一次向 GPU 提供一个解码器层。

Measured on an RTX 3050 Laptop 4 GB: Llama-3.1-8B-Instruct + NF4 at 119.6 tok/s, 3.32 GB peak — bit-exact against a normal resident run, and reproduced independently on an H100 at 113.00 tok/s in the same 3.32 GB. (The tok/s figure was measured on v0.72.2, before the v0.73.0 correctness repair that cost −4.8% at 32B; it has not been re-run on a 4 GB card since.) 在 RTX 3050 笔记本 4GB 显存上测得:Llama-3.1-8B-Instruct + NF4 达到 119.6 tok/s,峰值显存 3.32 GB —— 与常规驻留运行相比位级精确(bit-exact),并在 H100 上独立复现,同样为 3.32 GB 显存下 113.00 tok/s。(tok/s 数据是在 v0.72.2 版本测得,早于 v0.73.0 的正确性修复,该修复在 32B 模型上带来了 -4.8% 的性能损耗;此后尚未在 4GB 显卡上重新测试。)

Opt-in (stream_layers: true) and still BETA — how it works · all measurements · paper · check it yourself on a free Colab T4 (caps the process to 4 GB, then asserts a streamed model is bit-identical to a normal one) 需手动开启 (stream_layers: true) 且仍处于 BETA 阶段 —— 工作原理 · 所有测量数据 · 论文 · 在免费的 Colab T4 上亲自验证(将进程限制在 4GB,并验证流式模型与常规模型位级一致)。

Llama-3.1-8B-Instruct + NF4, LoRA, batch 1, seq 512 on an RTX 3050 Laptop 4 GB — 3.32 GB peak, 119.6 tok/s. Full video (90s) Llama-3.1-8B-Instruct + NF4, LoRA, batch 1, seq 512 在 RTX 3050 笔记本 4GB 显存上 —— 峰值 3.32 GB,119.6 tok/s。完整视频 (90秒)。

Why Soup?

为什么选择 Soup?

Training LLMs is still painful. Even experienced teams spend 30-50% of their time fighting infrastructure instead of improving models. Soup fixes that. 训练大模型依然很痛苦。即使是经验丰富的团队,也要花费 30-50% 的时间在基础设施上,而不是改进模型。Soup 解决了这个问题。

  • Zero SSH. Never SSH into a broken GPU box again.
  • 零 SSH。 再也不用 SSH 登录到故障的 GPU 服务器了。
  • One config. A simple YAML file is all you need.
  • 单一配置。 你只需要一个简单的 YAML 文件。
  • Auto everything. Batch size, GPU detection, quantization — handled.
  • 全自动。 批大小、GPU 检测、量化 —— 全部自动处理。
  • Works locally. Train on your own GPU with QLoRA. No cloud required.
  • 本地运行。 使用 QLoRA 在你自己的 GPU 上训练。无需云端。

What’s New

更新日志

v0.73.2 — the release gate stops lying in both directions. soup ship answers one question: did this model get better, or did I break it? v0.73.2 —— 发布门控(release gate)不再双向误报。soup ship 只回答一个问题:这个模型变好了,还是被我改坏了?

Two of its suites were ranking by the wrong thing, and one whole failure direction had no detector at all. A suite scored 0.225 for a model that got it right 40/40. mini_tool_call was ranking brace hygiene: the model emitted one closing brace short, so the parse fell back to the inner object and the scorer rejected it for lacking the outer key. And mini_mmlu scored Llama-3.1-8B at 0.423 — below a 0.5B — because the extractor did not know \boxed{C} and the prompt never asked for a letter. Both fixed; 0.423 → 0.731. 其中两个测试套件的排序逻辑错误,且有一个完整的失败方向完全没有检测器。一个模型在 40/40 全对的情况下,套件评分仅为 0.225。mini_tool_call 之前在评估括号规范:模型少输出了一个闭括号,导致解析回退到内部对象,评分器因缺少外部键而拒绝了它。mini_mmlu 将 Llama-3.1-8B 评分为 0.423 —— 低于 0.5B 模型 —— 因为提取器不识别 \boxed{C} 且提示词未要求输出字母。两者均已修复;评分从 0.423 提升至 0.731。

New: a benign-prompt axis. Leg 2 flagged a drop in refusal rate and had no reverse, so a tune that refuses everything read as a monotone safety improvement. Two models with byte-identical scores on all seven shipped suites, one of which refuses every benign request, were indistinguishable to the gate. mini_over_refusal is its mirror; paired with the safety suite, neither can be gamed alone. 新增:良性提示词轴。第二阶段标记了拒绝率的下降,但没有反向检测,因此一个拒绝所有请求的微调模型会被误读为安全性提升。两个在七个发布套件上得分完全相同的模型,其中一个拒绝所有良性请求,门控系统却无法区分。mini_over_refusal 是其镜像;与安全套件配合使用,两者都无法被单独欺骗。

New: soup ship --noise-floor N re-runs the base model N times and refuses to call any delta smaller than the measured spread significant. Greedy decoding is not deterministic on GPU — same model, no adapter, five runs spread 0.015–0.020 against a 0.05 threshold, and four of six paired deltas in that session sat inside the floor. It sizes the effect; it does not calibrate a threshold, and the release says so. 新增:soup ship --noise-floor N 会将基座模型重跑 N 次,并拒绝承认任何小于测量偏差的增量。GPU 上的贪婪解码并非确定性的 —— 同一模型、无适配器,五次运行偏差在 0.015–0.020 之间,阈值为 0.05,该会话中六分之四的配对增量都在噪声底限内。它衡量的是效应大小,而不是校准阈值,发布说明中已明确指出。

A caller error was indistinguishable from a regression. A non-callable generator scored 0.0 on three suites and raised on the others — and in leg 2 a 0.0 reads as “failed every item”, i.e. it failed in the direction that looks like a finding. 调用错误曾无法与回归区分。一个不可调用的生成器在三个套件上得分为 0.0,在其他套件上报错 —— 而在第二阶段,0.0 被解读为“所有项目失败”,即它在看起来像是一个发现的方向上失败了。

Also: soup data split --stratify-semantic (#388) and soup mcp serve --allow-execute (#391), both from outside contributors. 此外:soup data split --stratify-semantic (#388) 和 soup mcp serve --allow-execute (#391),均来自外部贡献者。

The measurement record for the previous release’s VRAM work, published as written — including the three readings withdrawn during it — is benchmarks/gate-v0.73.1-measured-vram-fit.md. 上一版本 VRAM 工作的测量记录已按原样发布 —— 包括期间撤回的三次读数 —— 详见 benchmarks/gate-v0.73.1-measured-vram-fit.md

# soup.yaml — then just `soup train --config soup.yaml`
training:
  stream_layers: true # base streams out of VRAM; only the adapter trains
  quantization: 4bit # NF4 — ~4x smaller store, so 8B fits a 4 GB card
  batch_size: 4 # bigger batches amortise the weight read
  stream_source: auto # RAM when it fits, NVMe disk when it does not
  seed: 1234 # new in v0.73.0

Python 3.10–3.12 only. v0.73.0 adds the upper bound that was missing: on 3.13+, pip used to resolve untested PyTorch wheels that crash in the native extension before Soup runs at all. 仅限 Python 3.10–3.12。v0.73.0 增加了缺失的上限:在 3.13+ 环境下,pip 过去会解析未经测试的 PyTorch wheel,导致在 Soup 运行前就在原生扩展中崩溃。

Previous release — v0.72.4, align on a laptop (DPO / ORPO / SimPO / KTO over layer streaming) 上一版本 — v0.72.4,在笔记本上进行对齐(通过层流式传输实现 DPO / ORPO / SimPO / KTO)

Layer streaming used to support supervised fine-tuning only; v0.72.4 opened it to the preference losses. The risk was one thing: DPO needs a reference model, and a second copy would double memory and defeat the point. Soup uses the same streamed base with its adapters switched off — measured at 0.914× the SFT peak, where forcing a real second instance cost +730 MB, exactly one copy of the weights. Bit-exact against a normal non-streamed run for all four. Honest cost: free in memory, not in time — DPO reads the layer stack 1.52× as often per step. grpo / ppo stay excluded on purpose. 层流式传输过去仅支持监督微调;v0.72.4 将其扩展至偏好损失函数。风险在于:DPO 需要一个参考模型,而第二个副本会使内存翻倍,从而失去意义。Soup 使用相同的流式基座并关闭适配器 —— 测得峰值仅为 SFT 的 0.914 倍,而强制运行第二个实例则会增加 +730 MB 内存,正好是一份权重的大小。四种方法均与常规非流式运行位级精确。真实成本:内存免费,但时间不免费 —— DPO 每步读取层堆栈的频率是原来的 1.52 倍。grpo / ppo 被特意排除在外。

Trained with stream_layers: true on v0.72.0? That adapter is inert — its tensors were saved under keys with an extra .inner. segment, so every loader returned the untuned base. Fixed in v0.72.1; re-run or re-save. 在 v0.72.0 上使用 stream_layers: true 训练过?该适配器是无效的 —— 其张量保存时带有额外的 .inner. 段,导致加载器返回的是未微调的基座。已在 v0.72.1 修复;请重新运行或重新保存。

Previous release — v0.71.40, soup reward synth (generate a reward verifier from your data) 上一版本 — v0.71.40,soup reward synth(从你的数据生成奖励验证器)

Point soup reward synth at a JSONL of reference outputs and it infers a deterministic verifier, writes a readable / committable .py reward function, and — the part nobody else does — refuses to emit one that can’t tell your references from bad answers (four families: numeric / json_schema / regex / tool_call; a mandatory calibration report is the moat). Reward ensembles (reward_fn: "accuracy,format") also train now. (#311) 将 soup reward synth 指向包含参考输出的 JSONL 文件,它会推断出一个确定性的验证器,编写一个可读/可提交的 .py 奖励函数,并且 —— 这是其他人没做的 —— 如果验证器无法区分你的参考答案和错误答案,它会拒绝生成(四种类型:数值 / json_schema / 正则表达式 / 工具调用;强制性的校准报告是其护城河)。现在也支持奖励集成训练 (reward_fn: "accuracy,format")。(#311)

Previous release — v0.71.39, CI for weights not prompts (emit + provenance-bind the ship verdict) 上一版本 — v0.71.39,针对权重而非提示词的 CI(发布并绑定 ship 结论的来源)