Getting Started
Installation
As of v0.71.0 the install is split. pip install soup-cli is a light, PyTorch-free CLI + data-tools install — soup init, soup data …, and the inspection commands all work on it. To fine-tune, add the [train] extra:
# Light core: CLI + config + data tools, no PyTorch
pip install soup-cli
# Add the training stack (torch, transformers, peft, trl, datasets, …)
pip install "soup-cli[train]"
# Everything (train + serve + ui + data + mcp) in one shot
pip install "soup-cli[all]"
# Or from GitHub: the main branch, which runs ahead of the latest release and carries changes that are not in any tag
pip install git+https://github.com/MakazhanAlpamys/Soup.gitUpgrading from ≤ v0.70?
pip install soup-clino longer pulls PyTorch. If you train, reinstall withpip install "soup-cli[train]"— a missing heavy dependency now surfaces a friendlyTraining needs the [train] extramessage instead of anImportError.
Upgrading from v0.75 or earlier
pip install -U soup-cli # a fresh install with pipx: pipx install soup-cli
pip install -U "soup-cli[train]" # the training stack
soup doctor --config soup.yaml # before you trainA
soup.yamlthat loaded on v0.75 can stop loading on v0.76.0. v0.76.0 refuses settings that were accepted and never applied (for three of them,use_longlora,ebft_variantandquantization_aware: true, applied wrongly). Runsoup doctor --config soup.yamlafter you upgrade and before you train.
soup doctor --config loads your config with the current rules. If something is refused it prints the error, which names the field and what to change, then Config could not be loaded (see above)., and exits 2; a missing file also exits 2 (Config not found: <path>). Unknown keys are reported together, but it stops at the first cross-field refusal, so fix that setting and run it again until it prints no error. A setting that nothing reads yet only warns, for example Warning: training.early_stop_patience is accepted but read by nothing; v0.77 will refuse it: the load continues and the exit code is 0, and upstream states that the refusal for those fields comes in v0.77. Settings refused at load groups the refusals by what they touch, with the start of each message and what to change, and lists the 29 staged fields.
A clean Config check line is not an all-clear. After the load the command prints a Config check that lists settings the backend never reads, but its table covers only four combinations of task, backend and modality: sft on mlx, sft on unsloth, and sft on transformers with vision or with audio. For anything else, plain sft on transformers included, it prints None of the 0 setting(s) known to be unread on task=sft backend=transformers is switched on in this config., which means the combination was not reviewed rather than that nothing is wrong. The refusal at load is what protects you; the table only adds to it.
A config that must load on both v0.75 and v0.76.0 needs the refused key removed, not renamed. What changed in v0.76.0 has the full list, the re-run table and the exit-code move: 0 pass, 2 gate failure and 3 usage or input error on eleven gate and verdict commands, so a CI step that tests for exit 1 as "the gate failed" now lets a failing gate through.
Two dependency traps the upgrade can hit. Both concern a package that was already in your environment.
clickis now declared asclick>=8.0.0,<8.5. click 8.5.0 drops the description of every positional argument from everysoup <command> --helppage, so a fresh install that resolved the newest click showedADAPTER TEXT [required]with nothing after it. If another package in the same environment needs click 8.5 or newer, install Soup in its own environment (pipxdoes this).typeris declared>=0.9.0,<0.21.0, but only typer 0.15.4 and newer start on every click that range admits.pip install -U soup-clidoes not upgrade a dependency that already satisfies its range, so an environment that already holds an older typer fails on every command,soup --helpincluded, withType not yet supported: int | None. Fix it withpip install -U "typer>=0.15.4,<0.21". A normal freshpip installresolves a current typer and is not affected.
Requirements
On Debian 12, Ubuntu 23.04 or anything newer, plain
pip installfails outside a virtualenv witherror: externally-managed-environment, and it is not a Soup problem.
Those distributions ship an EXTERNALLY-MANAGED marker in the system Python, so pip refuses to write into a site-packages that apt also manages (PEP 668). It is the default on current Debian and Ubuntu, so it is the ordinary first-run experience there rather than an edge case, and nothing in Soup can rescue it: the package is not installed yet when the command runs.
Soup declares a soup console script, which makes it an application rather than a library, so upstream's README now leads with pipx:
pipx install soup-cli # or: uv tool install soup-cli
pipx install "soup-cli[train]" # extras spelled exactly as belowBoth give Soup its own virtualenv and put the command on PATH, which is outside PEP 668's scope entirely. Every pip line on this page stays correct inside a virtualenv, a Colab notebook or a Docker image, and python3 -m venv .venv then plain pip works just as well. Use pip rather than pipx if you also want to import soup_cli from your own code, because pipx isolation is the wrong shape for that.
Default: resident QLoRA
- Python 3.10 to 3.12 (the floor was raised from 3.9 in v0.71.0; v0.73.0 added the upper bound, because on 3.13 and above pip resolved untested PyTorch wheels that crash inside the native extension before Soup runs)
- The
[train]stack, as of v0.76.0:torch>=2.6.0,transformers>=5.16.1,<6.0.0,trl>=0.29.0,<1.0.0,peft>=0.20.0,<1.0.0,accelerate>=0.27.0, and since v0.76.0requests>=2.32.2. A fresh install resolves all of that for you; an environment you are upgrading may not (see the two traps above). The core install declarestyper>=0.9.0,<0.21.0(0.15.4 or newer is the working floor) andclick>=8.0.0,<8.5. One consequence worth knowing:pip install "soup-cli[train,mlx]"resolves for the first time in v0.74.0, because the two extras previously declaredtransformersranges that could not be satisfied together at all - CUDA-compatible GPU (recommended); Apple Silicon (MPS) or CPU (experimental) also work
- 8 GB+ VRAM for 7B models with QLoRA
The torch floor moved to 2.6.0 in v0.75.0, and that closed a real trap. v0.74.0 declared
torch>=2.5.0whiletrl>=0.29could not import at 2.5.1 at all, because it needs the public FSDP2 API that arrives in 2.6.0, so a pinned 2.5.x environment silently lost DPO, KTO, GRPO and BCO. pip could not catch it, sincetrldeclares no torch dependency. v0.74.0 published the hole rather than guessing at a fix, because 2.5.1 was measured to fail and 2.6 had not been measured to work; v0.75.0 raised the floor and proved it in CI. If you pin torch yourself, pin 2.6.0 or newer.
Two install-time failures that v0.76.0 repairs, if you are on v0.75.2 or earlier. Fresh environments created after 5 October 2026 could not run
task: grpoortask: online_dpo:datasets5.1.0 stopped installingrequests, which trl imports unconditionally for those two trainers. GRPO failed withRuntimeError: Failed to import trl.trainer.grpo_trainerand online DPO withinstalled trl 0.29.1 does not provide 'OnlineDPOConfig', each ending inNo module named 'requests'. The[train]extra now declaresrequests>=2.32.2; on an earlier releasepip install "requests>=2.32.2"fixes both, and the other trainers were not affected (#1637). Separately, on transformers 5.19.0, which the[train]range admits, everytask: pporun stopped at its first checkpoint withAttributeError: 'PPOTrainer' object has no attribute 'is_distributed_loading_by_transformers'; v0.76.0 fixes it and no other task was affected (#1682).
If the model does not fit: layer streaming (opt-in, BETA)
- Set
training.stream_layers: trueinsoup.yamland the frozen base never loads into VRAM: Llama-3.1-8B fine-tunes in 3.32 GB on a 4 GB card (measured on v0.72.2; the layer streaming page has the later row and its caveats). Slower than resident training, so leave it off for a model that already fits. See Layer Streaming.
Streaming bounds the decoder stack to one layer at a time. Embeddings and the logits tensor stay resident, so peak VRAM still depends on the model, just much less.
Optional Extras
pip install "soup-cli[train]" # Training stack: torch, transformers, peft, trl, …
pip install "soup-cli[fast]" # Unsloth 2-5x training speedup
pip install "soup-cli[mlx]" # Apple Silicon backend (M1–M4)
pip install "soup-cli[serve]" # FastAPI inference server
pip install "soup-cli[serve-fast]" # vLLM backend
pip install "soup-cli[sglang]" # SGLang backend
pip install "soup-cli[eval]" # lm-evaluation-harness
pip install "soup-cli[data]" # MinHash dedup + semantic split (scikit-learn)
pip install "soup-cli[data-pro]" # langdetect + Presidio PII
pip install "soup-cli[vision]" # Pillow for vision fine-tuning
pip install "soup-cli[audio]" # librosa + soundfile + torchaudio
pip install "soup-cli[qat]" # torchao>=0.18.0: FP8 / NVFP4 training and soup export --format torchao
pip install "soup-cli[liger]" # Liger Kernel fused ops
pip install "soup-cli[onnx]" # ONNX export
pip install "soup-cli[tensorrt]" # TensorRT-LLM export
pip install "soup-cli[awq]" # AWQ quantized export (deprecated in v0.76.0, upstream says removal in v0.77)
pip install "soup-cli[gptq]" # GPTQ quantized export, a separate extra (deprecated in v0.76.0, upstream says removal in v0.77)
pip install "soup-cli[ui]" # Web UI dashboard
pip install "soup-cli[tui]" # Full-screen Textual dashboard
pip install "soup-cli[trackers]" # MLflow / SwanLab / Trackio logging
pip install "soup-cli[wandb]" # Weights & Biases, for soup train --wandb
pip install "soup-cli[generate]" # httpx, for soup data generate provider calls
pip install "soup-cli[deepspeed]" # ZeRO distributed training
pip install "soup-cli[ring-attn]" # ring-flash-attn (training.use_ring_attention is checked but not applied in v0.76.0)
pip install "soup-cli[remote]" # Remote datasets (s3 / gs / az; oci needs ocifs, installed separately)
pip install "soup-cli[sign]" # ed25519 adapter / attestation signing
pip install "soup-cli[sigstore]" # Sigstore keyless signing (v0.76.0; sigstore>=4.4.0,<5.0.0; not part of [all])
pip install "soup-cli[compile]" # DSPy / GEPA / TextGrad prompt compiler
pip install "soup-cli[carbon]" # codecarbon energy / CO2 tracking
pip install "soup-cli[modal]" # Serverless cloud GPU (soup train --cloud modal; --cloud lambda needs no extra)
pip install "soup-cli[aider]" # Aider CLI, for soup eval aider (v0.74.0)
pip install "soup-cli[mcp]" # MCP server (soup mcp serve) for coding agents
pip install "soup-cli[cce]" # Cut Cross-Entropy (training.use_cut_ce)
pip install "soup-cli[mix]" # scikit-optimize, for soup data mix --optimize
pip install "soup-cli[pdf]" # reportlab, for the EU AI Act Annex XI/XII PDFs
pip install "soup-cli[dev]" # the test and lint stack, for contributing
pip install "soup-cli[all]" # shorthand for train + serve + ui + data + mcpThat is 37 extras. [all] is only train + serve + ui + data + mcp: it does not pull [sigstore], [awq], [gptq] or [wandb].
[awq]and[gptq]are deprecated in v0.76.0, and upstream says their removal comes in v0.77.soup export --format awqand--format gptqstill work as before and now start with aDeprecated:notice. AutoAWQ and AutoGPTQ are archived upstream, and upstream's documentation says neither extra can be installed next to[train], so on a normal install the two formats could not be reached; run them from a separate environment. The formats to move to aregguf,onnx,tensorrt,bitnetandtq1_0. Model export has the detail. Training LoRA on top of an already-AWQ or GPTQ-quantized base is a different feature and is not covered by this notice.
Use double quotes, and here is why
pip install "soup-cli[train]" is the only spelling that works in every shell: cmd.exe, PowerShell, bash and zsh. Every command above uses it.
Older tutorials and videos, including some of ours, show the single-quoted pip install 'soup-cli[train]'. That is bash, zsh and PowerShell syntax. Windows cmd.exe has no single-quote quoting, so it hands the quotes straight to pip:
ERROR: Invalid requirement: "'soup-cli[train]'": Expected package name at the start of dependency specifierIf you hit that, swap the ' for ". Nothing is wrong with the package: pip is rejecting a literal quote character. Dropping the quotes entirely also works on Windows, but then zsh reads [train] as a glob and fails instead.
Quick Start
1. Create a config
# Interactive wizard
soup init
# Or use a template
soup init --template chat2. Train
soup train --config soup.yamlSoup automatically detects your GPU, sets optimal batch size, configures LoRA, and begins training.
3. Chat with your model
soup chat --model ./output4. Push to HuggingFace
soup push --model ./output --repo your-username/my-model5. Export and serve
# Export to GGUF for Ollama / llama.cpp
soup export --model ./output --format gguf --quant q4_k_m
# Start OpenAI-compatible server
soup serve --model ./output --port 8000Health Check
Check your environment for compatibility issues:
soup doctor
soup doctor --config soup.yaml # also load a config under the current rules; exit 2 if it cannot loadShows Python version, GPU availability, all dependency versions, and fix suggestions. Since v0.76.0 it also prints, for each NVIDIA GPU, its compute capability and architecture (for example sm_89 (Ada)), says in red when the installed PyTorch build contains no code for that architecture and prints a reinstall hint matched to your driver, and adds a "Precision features" block for BF16, FP8 and NVFP4 (whether the hardware and the software path support each). On Apple Silicon it prints an MLX panel with the MLX version, chip and unified memory, or not installed with the [mlx] install line. When the header of nvidia-smi cannot be read it gives no PyTorch index URL at all, rather than guessing one. A transformers, peft or trl at its next major version (6, 1 and 1) makes soup doctor exit 1, as does a missing core dependency.
Upgrading from v0.75? soup doctor --config soup.yaml is the step to run first; see Upgrading from v0.75 or earlier above.
Quick Demo
Run a complete demo in one command:
soup quickstart # Creates sample data + config + trains TinyLlama
soup quickstart --dry-run # Just create files without trainingSoup 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.