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, finished in v0.67.0) treats LoRA adapters as first-class versioned objects.

Ten subcommands across v0.57 + v0.67:

CommandWhat it doesShipped
soup adapters diffPer-layer Frobenius + relative drift + SVD effective rankv0.57
soup adapters merge5 strategies: linear / TIES / DARE / SVD / CMA-ESv0.57 + v0.67
soup adapters blameLeave-one-out layer ablation plannerv0.57
soup adapters branchName a LoRA config with SHA-pinned hashesv0.57
soup adapters checkoutRestore a branch; refuses on driftv0.57
soup adapters branchesList everythingv0.57
soup adapters prGitHub-shaped PR markdown with eval-delta + sample diffsv0.67
soup adapters bisectBinary-search checkpoint history for regression boundaryv0.67
soup lock write / show / checkSHA256(base \\dataset \\env) closure, exit 3 on driftv0.67
(v0.60 supply chain)scan / sign / verify / check-safetensorsv0.60

All adapter math is pure numpy, no torch. .bin adapters are rejected with an actionable "re-save as safetensors" message. See Adapter lifecycle (v0.67) for the v0.67 surfaces.

soup adapters diff

bash
soup adapters diff adapter-a/ adapter-b/ --top-k 10 --format markdown

For each layer:

  • Frobenius norm of the delta
  • Relative drift (Frobenius / norm of a)
  • SVD effective rankeffective_rank(s) = exp(H(s²/Σs²)) where H is 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 — 5 strategies

bash
soup adapters merge a/ b/ c/ -o merged/ \
  --strategy ties --weights 0.4,0.3,0.3 --density 0.7 --seed 0

# v0.67 — evolutionary search over the simplex
soup adapters merge a/ b/ c/ -o merged/ \
  --strategy cmaes --eval ./suite.yaml --budget 1h

Strategies:

  • `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 by 1/density, deterministic via --seed.
  • `svd` — linear-merge then low-rank SVD reconstruction (--rank).
  • `cmaes` (v0.67, Sakana-style) — rank-mu CMA-ES (pure Python, no cma dep) over N-1 softmaxed logits on the simplex. Population [2..256], generations [1..10K], plateau-detects after 3 no-improvement gens. Eval-fn failures swallowed with sentinel score so one broken eval ≠ crashed run.

Live as of v0.71.4--canary <suite.json> scores the merged adapter OK/MINOR/MAJOR via the Quant-Lobotomy taxonomy (--strict-verdict exits 2 on MAJOR), and --strategy cmaes runs the full evolutionary eval-suite loop (merge → materialise → score → write best). The backdoor-scan + license-conflict gates run for every strategy.

soup adapters blame — leave-one-out planner

bash
soup adapters blame adapter/ --dataset eval.jsonl --layer model.layers.* --budget 5m --shards 4

Plans 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

bash
soup adapters branch chat-llama-v3 -c soup.yaml --base meta-llama/Llama-3.1-8B --dataset data.jsonl

Records a frozen Branch:

text
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.0

Branch-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

bash
soup adapters checkout chat-llama-v3 -o restored-soup.yaml

Re-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

  • Adapter algebra — v0.71.34 adds soup adapters arithmetic: add, scale and negate LoRA deltas.
  • Registry — lineage DAG of full training runs
  • Soup Cans — package an adapter + config + data ref into a portable bundle
  • Adapter lifecycle (v0.67)soup adapters merge --strategy cmaes evolutionary search, soup adapters pr GitHub-shaped reviews, soup adapters bisect regression history, and soup lock shared SHA256 closure
  • Supply-chain security (v0.60)soup adapters scan / sign / verify for backdoor detection + Merkle-root tamper protection