You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The spike #44 proved that a Stable Audio 3 LoRA finetune can run through
LSDJ's MLX inference path: a real public adapter
(motiftechnologies/stable-audio-3-maqam-lora) merged into the medium DiT at load
time produced measurably different audio through LSDJ's own subprocess invocation,
with a bit-exact bypass at strength 0. See docs/spike-sa3-lora.md.
This issue is the build: let users import and manage SA3 LoRA adapters in-app,
the #43-style integration (HF repo-id + local import, "any source, warn +
validate", registry/UI), wired into the generate pipeline.
Accept .safetensors only; refuse.ckpt/.pt/.pth/.bin with a clear
message (they are unpickled by torch.load and can execute code).
Recognise both conventions: SA3-native (config in safetensors metadata) and
PEFT (sibling adapter_config.json).
Infer rank/alpha/adapter_type; verify the adapter's base matches the
target DiT (small vs medium) and that its layer keys/shapes resolve, warning on
any skipped layers rather than corrupting weights.
Runtime wiring: thread the selected adapter(s) + strength into backend/lsdj/sa3.py's generate argv (--lora / --lora-strength) and the /api/generate contract; per-deck / per-kind selection. The optimized/mlx/models/defs/lora_merge.py merge module already covers all nine
adapter types.
Upstream: contribute the spike's lora_merge.py + --lora flag to Stability-AI/stable-audio-3. If/when upstream lands native MLX LoRA, drop ours
and bump sa3-pin.json (ADR-0012's upgrade path).
Acceptance criteria
An SA3 LoRA can be imported in-app (HF id + local) and applied to a generation
from the UI, audibly changing output; strength is adjustable; strength 0 is a
bypass.
Pickle adapters are refused; non-matching-base adapters are rejected at import
with a clear reason.
The registry persists installed adapters grouped by base and survives restart.
just check green; a hardware/UX checklist in docs/ for the parts tests can't
cover (per CLAUDE.md).
Out of scope
SA3 LoRA training (upstream stable-audio-tools / stable-audio-3).
Magenta finetunes — still upstream-blocked ("coming soon"); see the spike's
revisit trigger.
-xs adapter SVD-bases performance on the medium DiT (bases are recomputed
at load) may warrant a measure-and-cache sub-task.
Risks
An upstream rebase of the pinned MLX fork could rename layers and break the merge
name-mapping — mitigated by the pinned commit + the spike's captured patch +
skip-unknown-layers.
-xs SVD recompute cost on medium.
Base/adapter mismatch is a UX footgun — validate hard at import.
Problem
The spike #44 proved that a Stable Audio 3 LoRA finetune can run through
LSDJ's MLX inference path: a real public adapter
(
motiftechnologies/stable-audio-3-maqam-lora) merged into the medium DiT at loadtime produced measurably different audio through LSDJ's own subprocess invocation,
with a bit-exact bypass at strength 0. See
docs/spike-sa3-lora.md.This issue is the build: let users import and manage SA3 LoRA adapters in-app,
the #43-style integration (HF repo-id + local import, "any source, warn +
validate", registry/UI), wired into the generate pipeline.
Gated on
load time, via a new
--loraflag onsa3_mlx.py(the spike's PoC patch, anupstream contribution). Do not start until the spike PoC is in place.
merge-on-the-spawned-subprocess approach. Build to that decision.
Scope
src-tauri/src/models.rs+settings drawer): a HuggingFace repo-id and a local folder /
.safetensors."Any source, warn + validate."
.safetensorsonly; refuse.ckpt/.pt/.pth/.binwith a clearmessage (they are unpickled by
torch.loadand can execute code).PEFT (sibling
adapter_config.json).rank/alpha/adapter_type; verify the adapter's base matches thetarget DiT (small vs medium) and that its layer keys/shapes resolve, warning on
any skipped layers rather than corrupting weights.
backend/lsdj/sa3.py'sgenerateargv (--lora/--lora-strength) and the/api/generatecontract; per-deck / per-kind selection. Theoptimized/mlx/models/defs/lora_merge.pymerge module already covers all nineadapter types.
adapters-grouped-by-base (many LoRAs over one base), with install / list /
delete mirroring the Add an in-app model manager: download Magenta + Stable Audio models from a settings overlay #43 manager. A per-deck strength knob maps to
--lora-strength.compatibility; reflect install progress like the Add an in-app model manager: download Magenta + Stable Audio models from a settings overlay #43 manager.
lora_merge.py+--loraflag toStability-AI/stable-audio-3. If/when upstream lands native MLX LoRA, drop oursand bump
sa3-pin.json(ADR-0012's upgrade path).Acceptance criteria
from the UI, audibly changing output; strength is adjustable; strength 0 is a
bypass.
with a clear reason.
just checkgreen; a hardware/UX checklist indocs/for the parts tests can'tcover (per CLAUDE.md).
Out of scope
stable-audio-tools/stable-audio-3).revisit trigger.
-xsadapter SVD-bases performance on the medium DiT (bases are recomputedat load) may warrant a measure-and-cache sub-task.
Risks
name-mapping — mitigated by the pinned commit + the spike's captured patch +
skip-unknown-layers.
-xsSVD recompute cost on medium.References
docs/spike-sa3-lora.md