Free & Open Source

Stop tuning.Start training.Soup writes the config for you_

The whole post-training stack in one CLI. Soup doctors your data pre-flight, picks the method, writes the config (task, quantization, LR and epochs come from rules, not a search), derives evals from your own data, gates every save, and self-corrects reward hacking mid-run instead of just halting. And when the model is bigger than the card, one opt-in config key streams the frozen base from RAM or NVMe one layer at a time and quantizes it to 4-bit (BETA), so Llama-3.1-8B fine-tunes on a 4 GB GPU, and DPO, ORPO, SimPO and KTO stream too. 23 methods · 142 recipes · 17 quant formats · MLX + Apple adapter.

Soup CLI on Product Hunt
Apache-2.0 LicensePython 3.10 to 3.12No vendor lock-in
1Install
$ pip install "soup-cli[train]"
2Configure
$ soup init
✓ Created soup.yaml
3Train
$ soup train
> Training started...
Coming soon

Meet Soup Zero.

The full AI workbench built on top of Soup: playground, data, evals, fine-tuning, deploy and monitoring in one desktop app, on your own hardware. The deep layer is live today in the CLI; the workbench around it is what we're building.

Integrates with your entire ML stack

HuggingFaceHuggingFace
OllamaOllama
vLLMvLLM
DeepSpeedDeepSpeed
UnslothUnsloth
ONNXONNX
NVIDIA TensorRTNVIDIA TensorRT
W&BW&B
SGLangSGLang
FlashAttentionFlashAttention
HuggingFaceHuggingFace
OllamaOllama
vLLMvLLM
DeepSpeedDeepSpeed
UnslothUnsloth
ONNXONNX
NVIDIA TensorRTNVIDIA TensorRT
W&BW&B
SGLangSGLang
FlashAttentionFlashAttention
soup migrate

Already using another tool? Switch in 30 seconds

One command converts your existing config. No rewriting, no guessing, just migrate and train.

LLaMA-Factory
LLaMA-Factory
Auto-converted to Soup
Axolotl
Axolotl
Auto-converted to Soup
Unsloth
Unsloth
Auto-converted to Soup

See the difference

LLaMA-Factory config
llama3_lora_sft.yaml
model_name_or_path: meta-llama/Llama-3.1-8B
stage: sft
finetuning_type: lora
lora_rank: 64
lora_alpha: 16
lora_dropout: 0.05
lora_target: all
dataset: alpaca_en
template: llama3
cutoff_len: 2048
per_device_train_batch_size: 4
gradient_accumulation_steps: 4
num_train_epochs: 3
learning_rate: 2.0e-5
lr_scheduler_type: cosine
warmup_ratio: 0.1
quantization_bit: 4
output_dir: ./saves/llama3-lora
Soup config (auto-generated)
soup.yaml
base: meta-llama/Llama-3.1-8B
task: sft

data:
  train: ./data/alpaca_en.jsonl
  max_length: 2048

training:
  epochs: 3
  lr: 2e-5
  quantization: 4bit
  lora:
    r: 64
    alpha: 16

output: ./saves/llama3-lora

Soup auto-detects everything else: optimizer, scheduler, target modules, batch size.

v0.73.0 — Borrowed Hardware

The whole loop: decide, train, ship, operate, secure

Every other tool stops at "hit train and hope." Curate the data, train text or speech without erasing the old task, then gate every save on one SHIP or DON'T-SHIP verdict you can commit next to the weights that produced it.

v0.73.0 Flagship · Layer Streaming · BETA

Fine-tune Llama-3.1-8B on a 4 GB laptop GPU. Align on the same card.

Never load the frozen base at all. Soup keeps it in CPU RAM or on NVMe and copies it into VRAM one decoder layer at a time on a dedicated CUDA stream, so peak VRAM is bounded by one layer, not by the model. Quantizing that streamed base to NF4 shrinks it about fourfold.

  • • Measured on a 4 GB RTX 3050 Laptop: Llama-3.1-8B at 119.6 tok/s in 3.32 GB, GPU 100% busy. Qwen2.5-3B at 264.2 tok/s in 1.76 GB. Both rates predate the v0.73.0 correctness repair and have not been re-measured on that card
  • DPO, ORPO, SimPO and KTO stream too. DPO's reference model is the same streamed base with its adapters switched off, so it costs no extra weights: 0.914x the supervised peak on a 365M synthetic fixture, where forcing a real second instance cost 730.44 MB, exactly one copy of them
  • Nine architectures (Llama, Qwen, Mistral, Gemma, Phi) and a pre-flight that refuses a run that will not fit: streaming bounds the weights, not the logits, which reached 8.71 GB on their own at batch 8 on a 152k-token vocabulary
  • BETA, with the limits stated: transformers, text, plain LoRA. The reference is free in memory, not in time (1.52x the layer reads), no tok/s is claimed for a preference loss because none was measured, and 8B is the largest size measured on this card

Two kinds of run completed successfully and were wrong anyway: a v0.72.0 streamed adapter loads as a no-op outside the streaming path, and a 32B or larger NF4 streamed run before v0.73.0 had wrong gradients while its loss looked healthy. Neither announced itself. The full re-run list.

soup · DPO over layer streaming
$ cat soup.yaml
base: Qwen/Qwen2.5-3B
task: dpo                  # sft, dpo, orpo, simpo and kto all stream
data:
  train: ./prefs.jsonl
  format: dpo
  max_length: 512          # a paired loss sends 2x the rows; size it down
training:
  stream_layers: true      # base streams from RAM, only the adapter trains
  quantization: 4bit       # NF4: ~4x smaller store
  stream_source: auto      # RAM when it fits, NVMe disk when it does not
  batch_size: 1            # kto needs 2 or more; the pre-flight sizes the rest
  lora: { r: 16, target_modules: [q_proj, v_proj] }

$ soup train --config soup.yaml
Preparing layer shards -> ~/.soup/layer-stream/Qwen__Qwen2.5-3B
Layer streaming is BETA: slower than resident training, but this
model may not run resident on this card at all.

# reference model = this same streamed base, adapters disabled
# one set of weights, one RAM store, one buffer pool

Most of the above: LLaMA-Factory / Axolotl / Unsloth ✗

Built for the ML Stack you already use

First-class integrations with the tools powering production ML. Deploy anywhere, track everything.

Works with your favorite models

Qwen 3.5
Qwen 3.6
DeepSeek-V4
GLM-5.1
Kimi K2.6
MiniMax M3
Mistral Large 3
Llama 4 Scout
Gemma 3
Phi-4
GPT-OSS
DeepSeek R1
Qwen2-VL
Whisper-large-v3

and 200+ more on the Hugging Face Hub: vision, audio, TTS, BitNet, MoE.

Pulls production traces from

Langfuse
LangSmith
Helicone
OpenPipe
OpenTelemetry
OpenAI Stored Completions

via soup ingest --source <vendor> --logs <export.jsonl>. No per-trace fees, all offline (v0.63).

Deploy & Serve

Ollama
Ollama
One-command local deploy
vLLM
vLLM
Prefix cache + spec decoding
SGLang
SGLang
RadixAttention backend
llama.cpp
llama.cpp
GGUF export + HF Spaces

Training & Infra

Unsloth
Unsloth
2-5x faster training
Apple MLX
Apple MLX
M1–M4 native SFT/DPO/GRPO
DeepSpeed
DeepSpeed
ZeRO 2/3 + ZeRO++ + MII
FlashAttention
FlashAttention
v2/v3 + Multipack varlen

Ecosystem

HuggingFace
HuggingFace
Push models to Hub
OpenAI API
OpenAI API
Compatible server
W&B
W&B
+ MLflow, SwanLab, Trackio
TensorBoard
TensorBoard
Local metrics viz

Quant & Export

GGUF
GGUF
UD ladder + IQ + ARM rungs
ONNX
ONNX
ONNX Runtime deploy
TensorRT
TensorRT
High-throughput GPU
AWQ/GPTQ
AWQ/GPTQ
+ HQQ, AQLM, EETQ, MXFP4, FP8, NVFP4, BitNet 1.58, TorchAO PTQ
Free forever. Apache-2.0 Licensed.

Your first fine-tuned model is one command away.

Soup picks the method, writes the config, and gates every save. Install it, point it at your data, and the first run finishes in minutes.

23 training methods, 142 ready recipes, first run in under a minute.

No credit cardNo sign-upWorks offline

Free and Apache-2.0. It stays that way.

Soup is built and maintained in the open on a single 4 GB laptop, which is why every performance number on this site is measured rather than claimed. Starring the repo helps most, and it costs nothing. If you want to fund the work directly, donations buy GPU time for what a 4 GB card still cannot reach. Three borrowed days on rented cards were enough to find a silent correctness bug nobody could have found on this laptop. The rest of that list is still waiting: multi-GPU, Apple Silicon, and a card we do not have to give back.