`soup adapters` — git for LoRA
After 6 weeks of running experiments you have 30 adapter folders and no idea which one to ship. soup adapters (v0.57.0) treats LoRA adapters as first-class versioned objects.
Six subcommands:
| Command | What it does |
|---|---|
soup adapters diff | Per-layer Frobenius + relative drift + SVD effective rank |
soup adapters merge | 4 strategies: linear / TIES / DARE / SVD |
soup adapters blame | Leave-one-out layer ablation planner |
soup adapters branch | Name a LoRA config with SHA-pinned hashes |
soup adapters checkout | Restore a branch; refuses on drift |
soup adapters branches | List everything |
All adapter math is pure numpy, no torch. .bin adapters are rejected with an actionable "re-save as safetensors" message.
`soup adapters diff`
soup adapters diff adapter-a/ adapter-b/ --top-k 10 --format markdownFor each layer:
- Frobenius norm of the delta
- Relative drift (Frobenius / norm of a)
- SVD effective rank —
effective_rank(s) = exp(H(s²/Σs²))whereHis Shannon entropy. Tells you whether a high-rank adapter actually used its rank.
--top-k ranks layers by drift. --format accepts table / json / markdown and routes through render_report_*.
`soup adapters merge` — 4 strategies
soup adapters merge a/ b/ c/ -o merged/ \
--strategy ties --weights 0.4,0.3,0.3 --density 0.7 --seed 0Strategies:
- `linear` — weighted average. Baseline.
- `ties` (Yadav et al. 2023) — trim by
density→ elect majority sign → disjoint average. Tied-sign defaults to+1. - `dare` (Yu et al. 2024) — Bernoulli drop with
density, rescale by1/density, deterministic via--seed. - `svd` — linear-merge then low-rank SVD reconstruction (
--rank).
The frozen MergeReport ships a verdict='UNKNOWN' stub today; live canary-verdict integration via the v0.55 eval gate lands in v0.57.1.
`soup adapters blame` — leave-one-out planner
soup adapters blame adapter/ --dataset eval.jsonl --layer model.layers.* --budget 5m --shards 4Plans which layer ablations to run within a wall-clock budget. parse_budget accepts 60s / 5m / 2h (bounds [60s, 24h]). _MIN_PER_SHARD_SECONDS = 30 checks feasibility — if the budget can't cover shards × 30s you get an actionable error. Returns a frozen BlamePlan with one BlameShardWork per shard.
Use --plan-only to see the plan without running anything. The live runner ships in v0.57.1.
`soup adapters branch` — named, SHA-pinned configs
soup adapters branch chat-llama-v3 -c soup.yaml --base meta-llama/Llama-3.1-8B --dataset data.jsonlRecords a frozen Branch:
name chat-llama-v3
config_path soup.yaml
config_sha256 a3f1...
dataset_sha256 7c92...
base_model meta-llama/Llama-3.1-8B
created_at 2026-05-15T23:14:02Z
soup_version 0.58.0Branch-name regex: ^[A-Za-z0-9][A-Za-z0-9._\-]{0,127}$. Config files capped at 1 MiB. Pointer file capped at 1,024 entries. Atomic write + POSIX 0o600. SOUP_BRANCHES_DIR env override containment-checked to $HOME / $CWD / $TMPDIR.
`soup adapters checkout` — drift-detecting restore
soup adapters checkout chat-llama-v3 -o restored-soup.yamlRe-emits the locked config. Refuses to restore on SHA mismatch — if your soup.yaml or your dataset has changed since the branch was made, you get a hard error explaining what drifted. No silent stale restores.
See also
- [Registry](/docs/registry) — lineage DAG of full training runs
- [Soup Cans](/docs/soup-cans) — package an adapter + config + data ref into a portable bundle