Configuration

Soup uses a single YAML config file for all settings. Run soup init to generate one.

Reproducibility and full fine-tuning (v0.73.0)

Two training keys landed in v0.73.0. Both are config keys, not CLI flags.

yaml
training:
  seed: 1234        # weight init of new params, data order, dropout
  data_seed: 7      # optional: vary data order while holding init fixed
  lora:
    r: 0            # 0 means no adapter: full fine-tuning, dense checkpoint

seed and data_seed are the first seed knobs in the project's history: before this every run trained at seed 42 with no way to change it, so "run this twice with a different seed" was impossible. Both default to unset rather than to 42, deliberately, because an unset seed has to keep reproducing two different historical defaults (the trainer's 42 and the multipack sampler's 0) and a plain 42 would have silently re-ordered every existing multipack run. A boolean is refused by name, since seed: true would otherwise become seed 1.

The honest scope: the seed reaches the trainer arguments on supervised runs only, so setting it on a DPO run parses and does nothing. On a streamed run it additionally seeds the adapter initialisation for all five streaming tasks, which is why a streamed run is bit-reproducible from a seed while a resident 4-bit one still is not.

lora.r: 0 selects full fine-tuning: no adapter is built, and the run writes a dense checkpoint rather than a LoRA. Rank 0 was chosen because three parts of the codebase already read it as "no adapter" and because r: 0 used to crash, so no config that worked before changes meaning. It is refused with a named message alongside a non-transformers backend, a non-text modality, any quantisation, Spectrum, LISA, layer streaming, or any LoRA-shaped option, and it refuses rather than running a no-op if your freeze settings leave nothing trainable.

Config Structure

yaml
base: meta-llama/Llama-3.1-8B-Instruct   # HuggingFace model ID (required)
task: sft                                   # Training task
# backend: unsloth                          # 2-5x faster (pip install "soup-cli[fast]")
# modality: text                            # text, vision, or audio

data:
  train: ./data/train.jsonl                 # Path to training data
  format: alpaca                            # Data format (auto-detected if omitted)
  val_split: 0.1                            # Validation split ratio
  max_length: 2048                          # Max sequence length (64-1048576)
  # image_dir: ./data/images               # For vision modality
  # audio_dir: ./data/audio                # For audio modality

training:
  epochs: 3
  lr: 2e-5
  batch_size: auto                          # auto or integer
  quantization: 4bit                        # none, 4bit, 8bit
  # quantization_aware: false              # Enable QAT
  # optimizer: adamw_8bit
  # gradient_checkpointing: true
  # stream_layers: false                   # Train or align a model bigger than VRAM (v0.72, BETA)
  # stream_source: auto                    # auto | ram | disk
  # stream_buffers: 2                      # 2-8
  lora:
    r: 64
    alpha: 16
    dropout: 0.05
    # target_modules: auto                 # Auto-detected per model
    # use_dora: false                      # Weight-decomposed LoRA

output: ./output

Layer streaming keys

These turn on layer streaming, which trains a model larger than your VRAM by keeping the frozen base out of the card entirely. They are config keys, not CLI flags: there is deliberately no --stream-layers.

KeyValuesDefaultNotes
stream_layerstrue / falsefalseBETA. Only enable it if the model does not fit resident; streaming trades time for memory
stream_sourceauto / ram / diskautoauto takes RAM when the base fits and falls back to an NVMe tier; ram refuses instead of falling back; disk forces NVMe
stream_buffers2 to 82VRAM buffers in the pool. 2 is double-buffering; 1 cannot overlap load with compute, so it is refused
stream_vram_probetrue / falsefalsev0.73.1. Decide the fit by measuring one real forward and backward at your shape, instead of predicting it. task: sft only. Costs 1 to 5 seconds, and cannot overrule a prediction more than 4x over budget
stream_disk_kindnvme / ssd / hdd(unset)v0.73.3. Override the detected media type behind the disk tier. nvme forces the tier on, ssd and hdd force it off. The override prints beside what was actually detected, and deliberately carries no measured rate, so a later refusal can never cite a reading you overrode
stream_vram_overridebytes(unset)v0.73.1. Replaces the free-VRAM figure the pre-flight checks against, in either direction. It changes the yardstick, not the check: an override below real free VRAM still refuses a config that would otherwise fit

Setting any of these while stream_layers is false is refused, because the knobs would silently do nothing.

stream_vram_probe and stream_vram_override are not interchangeable, and the difference is the point. stream_vram_probe is a measurement: it runs the step and reads the peak. stream_vram_override is an assertion you are making about how much VRAM is really available, which is what you need when the pre-flight cannot see the truth, as under a per-process memory cap in a hosted notebook.

Streaming also constrains keys you already set: quantization must be none or 4bit, batch_size must be a concrete number rather than auto, and task must be one of sft, dpo, orpo, simpo and kto (kto additionally needs batch_size of 2 or more). Scaling a streaming run covers sizing, the VRAM pre-flight and the disk tier; Preference losses over streaming covers the four alignment tasks.

Templates

Soup includes 21 built-in templates:

bash
soup init --template chat          # Conversational fine-tune
soup init --template code          # Code generation
soup init --template medical       # Domain expert
soup init --template reasoning     # GRPO reasoning (DeepSeek-R1 style)
soup init --template vision        # Vision/multimodal fine-tune
soup init --template audio         # Audio/speech fine-tune
soup init --template kto           # KTO unpaired preference
soup init --template orpo          # ORPO (no reference model)
soup init --template simpo         # SimPO length-normalized preference
soup init --template ipo           # IPO regularized preference
soup init --template bco           # BCO binary classifier preference (v0.40)
soup init --template rlhf          # Full RLHF pipeline (SFT -> RM -> PPO)
soup init --template pretrain      # Continued pre-training on raw text
soup init --template moe           # MoE fine-tuning (ScatterMoE LoRA)
soup init --template longcontext   # 128k+ context fine-tuning
soup init --template embedding     # Sentence embedding fine-tuning
soup init --template tool-calling  # Function / tool-calling fine-tune (v0.25)

Four more are regulation-shaped (compliance pack, v0.71.35). Each is a valid training config on a license-clean Apache-2.0 base plus header comments naming that regime's exact commands, because Soup's compliance controls are CLI flags and commands rather than config keys:

bash
soup init --template hipaa         # Protected Health Information
soup init --template soc2          # SOC 2 Trust Services Criteria
soup init --template eu-ai-act     # EU AI Act Annex XI/XII
soup init --template sr-11-7       # SR 11-7 Model Risk Management

Task-Specific Config Keys

KeyTasksDescription
dpo_betaDPODPO beta parameter
kto_betaKTOKTO beta parameter
orpo_betaORPOORPO beta parameter
simpo_gammaSimPOSimPO gamma parameter
cpo_alphaSimPOCPO alpha parameter
ipo_tauIPOIPO tau parameter
grpo_betaGRPOGRPO beta parameter
num_generationsGRPONumber of generations per prompt
reward_fnGRPO, PPOReward function (accuracy/format/path.py)
reward_modelPPOPath to reward model
ppo_epochsPPOPPO training epochs
ppo_clip_ratioPPOPPO clip ratio
ppo_kl_penaltyPPOPPO KL penalty
loraplus_lr_ratioAllLoRA+ learning rate ratio
use_galoreAllEnable GaLore optimizer
moe_loraAllTarget MoE expert layers
moe_aux_loss_coeffAllRouter load-balancing loss
use_ligerAllLiger Kernel fused ops
use_flash_attnAllFlashAttention v2/v3
use_ring_attentionAllRing FlashAttention
rope_scaling_typeAllRoPE scaling (linear/dynamic/yarn/longrope)
neftune_alphaAllNEFTune noisy embeddings (0-50)
packingSFTSample packing for efficiency
curriculumAllEnable curriculum learning
curriculum_metricAllSort metric (length)
curriculum_bucketsAllNumber of difficulty buckets (1-20)
loss_watchdogAllEnable loss watchdog
loss_watchdog_thresholdAllLoss spike threshold (≤100)
loss_watchdog_patienceAllPatience before stopping (≤1000)
freeze_layersAllFreeze bottom N layers (≤1000)
freeze_ratioAllFreeze ratio of layers
embedding_lossEmbeddingLoss function
embedding_poolingEmbeddingPooling strategy

Soup 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.