Adapter algebra (v0.71.34)
soup adapters arithmetic applies task arithmetic (arXiv:2212.04089) to LoRA deltas. You add to blend two skills, scale to dial one down, and, the differentiator, negate to subtract one. The output is a single loadable adapter.
soup adapters arithmetic "coder + 0.5*math - toxic" \
--adapter coder=./coder-lora \
--adapter math=./math-lora \
--adapter toxic=./toxic-lora \
-o ./blendedNames in the expression map to adapter directories via the repeatable --adapter name=path. Exit 0 = ok, 1 = refusal.
Why the coefficient math matters
A LoRA does not store its delta directly; it stores two factors whose product is the effective weight change, ΔW = B @ A. Scale both factors by a coefficient c and the delta scales by c², which quietly breaks the whole idea: - toxic (c = -1) would square to +1 and become a no-op instead of a removal.
Soup splits the coefficient as the square root of its absolute value across the two factors and carries the sign, so the delta scales linearly: negation flips it, 0.5* halves it, 2* doubles it. The live check on two real rank-8 adapters: ||ΔW(2·a)|| / ||ΔW(a)|| = 2.000 exactly, where the old c² bug gives 4.0.
Be precise about how far that exactness goes: it holds on the self (diagonal) term, so scaling or negating a single adapter is exact. A multi-adapter sum (like the example above) also carries cross-terms between the adapters, which this element-wise combine does not cancel. Mixed-rank inputs are refused rather than approximated, and exact concatenation-plus-SVD arithmetic is deferred.
What it refuses
| Guard | Behaviour |
|---|---|
| Mixed ranks | Refused with a "harmonize rank" message, never silently approximated |
| Different base models | Refused; --allow-cross-base overrides |
| A FAIL-scanned input | Refused by the backdoor-scan gate; --allow-unscanned skips it |
| Paths outside the working dir, symlinks | Rejected |
The combine is signed and un-normalized element-wise over same-rank adapters. Exact concat-plus-SVD for mixed ranks is deferred rather than faked.
The expression parser is hand-written. There is no eval, so an adapter name can never become code.
Honesty
What is proven is the mechanism: the delta really does negate, and the scaling ratio is exact to 2.000 on real adapters. What is not benchmarked is the behavioural outcome, so treat - toxic as "subtract that adapter's delta", not as a certified safety control. Whether subtracting a toxicity adapter measurably reduces toxicity on a real safety eval is an open question upstream calls proof-of-mechanism. Measure it on your own eval before you rely on it.
See also
- Adapter lifecycle — diff, merge (linear / TIES / DARE / SVD / CMA-ES), bisect, PR, lock.
- Adapters — the git-for-LoRA surface this builds on.
- Supply-chain security — the backdoor scan the gate reuses.
- LISA — the other half of the v0.71.34 release.