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.

bash
soup adapters arithmetic "coder + 0.5*math - toxic" \
    --adapter coder=./coder-lora \
    --adapter math=./math-lora \
    --adapter toxic=./toxic-lora \
    -o ./blended

Names 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 , 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 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 ranks are now exact (v0.72.0)

Mixed-rank inputs used to be refused with a "harmonize rank" message. As of v0.72.0 they are handled exactly, not approximated.

The reason it is exact is structural rather than numerical. A LoRA delta is ΔW = B @ A, so stacking the A factors of the inputs on top of each other and the coefficient-scaled B factors side by side gives a single adapter whose product is the sum of the individual deltas, by construction. Concatenation loses nothing; there is no approximation step to be wrong about. The output simply carries the summed rank.

bash
# rank-8 and rank-16 adapters in one expression: no longer a refusal
soup adapters arithmetic "coder + 0.5*math" \
  --adapter coder=./coder-r8 --adapter math=./math-r16 -o ./blended

# ask for a fixed output rank instead of the concatenated one
soup adapters arithmetic "coder + 0.5*math" \
  --adapter coder=./coder-r8 --adapter math=./math-r16 --rank 16 -o ./blended

--rank N truncates the concatenated result with an SVD, which is where an approximation does enter, deliberately and only when you ask for it: you are choosing a smaller adapter over an exact one. Without --rank, nothing is discarded.

Ranks are no longer a reason to refuse. Genuinely incompatible layer shapes still are.

What it refuses

GuardBehaviour
Mixed ranksHandled exactly by concatenation since v0.72.0; --rank N truncates with an SVD if you want a fixed output rank
Different base modelsRefused; --allow-cross-base overrides
A FAIL-scanned inputRefused by the backdoor-scan gate; --allow-unscanned skips it
Paths outside the working dir, symlinksRejected

The combine is signed and un-normalized. Same-rank inputs combine element-wise; mixed-rank inputs combine by concatenation, which is exact by construction (v0.72.0).

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.

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.