Instructions to use thepatch/same-l-decoder-lora with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Stable Audio 3
How to use thepatch/same-l-decoder-lora with Stable Audio 3:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
Rewrite model card: lead with audio, tighten prose, re-measure on screened koan ladder
Browse files
README.md
CHANGED
|
@@ -17,223 +17,176 @@ tags:
|
|
| 17 |
# SAME-L Decoder LoRA (`squeakfix_v3`)
|
| 18 |
|
| 19 |
A LoRA on **SAME-L's decoder**. It changes how latents are rendered to audio, not
|
| 20 |
-
how latents are produced
|
|
|
|
|
|
|
| 21 |
|
| 22 |
-
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
does.
|
| 29 |
|
| 30 |
-
|
| 31 |
-
In production in a live `stable-audio-3` backend since 2026-08-14.
|
| 32 |
|
| 33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
|
| 35 |
## Usage
|
| 36 |
|
| 37 |
-
Requires
|
| 38 |
[Stability-AI/stable-audio-3](https://github.com/Stability-AI/stable-audio-3).
|
| 39 |
-
|
| 40 |
-
|
| 41 |
|
| 42 |
```bash
|
| 43 |
-
python run_gradio.py --model medium-base
|
| 44 |
-
--lora-ckpt-path squeakfix_v3.safetensors
|
| 45 |
-
```
|
| 46 |
-
|
| 47 |
-
Stacked with a DiT LoRA, in either order:
|
| 48 |
|
| 49 |
-
|
| 50 |
python run_gradio.py --model medium-base \
|
| 51 |
--lora-ckpt-path my_style.safetensors squeakfix_v3.safetensors
|
| 52 |
```
|
| 53 |
|
| 54 |
-
Directly on the autoencoder:
|
| 55 |
-
|
| 56 |
```python
|
| 57 |
from stable_audio_3 import AutoencoderModel
|
| 58 |
from stable_audio_3.models.lora.loader import load_and_apply_loras
|
|
|
|
| 59 |
|
| 60 |
ae = AutoencoderModel.from_pretrained("same-l", device="cuda").autoencoder
|
| 61 |
load_and_apply_loras(ae, ["squeakfix_v3.safetensors"], "autoencoder")
|
|
|
|
| 62 |
|
| 63 |
-
|
| 64 |
-
audio = ae.decode(latents)
|
| 65 |
```
|
| 66 |
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
**The squeak is clearly audible at d0 β hi hats and snares especially, reported
|
| 130 |
-
by several listeners β and no metric here shows it.** Tried and flat or slightly
|
| 131 |
-
negative at d0: tonality p95 in 6β16 kHz and 1β8 kHz, frame counts over 10/12/15
|
| 132 |
-
dB, onset-locked tonality excess, fp32 and fp16, both LoRAs, both lengths.
|
| 133 |
-
|
| 134 |
-
The likely reason is that the measurement has no headroom at d0: ~640 of ~10,300
|
| 135 |
-
frames already read as tonal before any re-encoding, because cymbals and
|
| 136 |
-
distorted guitar genuinely are tonal, and a few dozen added squeak frames cannot
|
| 137 |
-
move a count that size. Separating artifact from content works at depth but not
|
| 138 |
-
at d0 without a clean reference, which generated audio does not have.
|
| 139 |
-
|
| 140 |
-
There is also precedent in this project for the tonality detector pointing the
|
| 141 |
-
wrong way β on SAME-S the clip that sounds squeakiest scores lowest. So the d0
|
| 142 |
-
β16% is not evidence the adapter hurts; it is a regime where this instrument does
|
| 143 |
-
not resolve.
|
| 144 |
-
|
| 145 |
-
Listen before deciding. Do not take the d0 number as the verdict.
|
| 146 |
-
|
| 147 |
-
On the round-trip ladder against real held-out audio β the eval this checkpoint
|
| 148 |
-
was selected against:
|
| 149 |
-
|
| 150 |
-
| metric | stock | `squeakfix_v3` | Ξ |
|
| 151 |
-
|---|---|---|---|
|
| 152 |
-
| tonality p95 | 17.08 | **9.41** | β7.67 |
|
| 153 |
-
| transient excess (dB) | 6.32 | **1.24** | β5.08 |
|
| 154 |
-
| latent drift per round trip | 10.91 % | **5.85 %** | β5.06 pp |
|
| 155 |
-
| onset artifact (dB) | β3.50 | β7.53 | β4.03 |
|
| 156 |
-
|
| 157 |
-
`transient excess` is added-HF on transient frames minus that on sustained
|
| 158 |
-
frames; positive means the artifact rides percussion, which is its signature.
|
| 159 |
-
|
| 160 |
-
---
|
| 161 |
-
|
| 162 |
-
## Honest limits
|
| 163 |
-
|
| 164 |
-
**Any decoder LoRA trained this way stamps a comb into the output β this one
|
| 165 |
-
doesn't, and that is the whole reason it exists.** The autoencoder's un-patch is
|
| 166 |
-
a bare reshape at `patch_size 256`, so output channel index and
|
| 167 |
-
time-position-within-patch are the same axis, and any channel-wise bias the
|
| 168 |
-
adapter learns is repeated identically in every patch. That is a harmonic comb at
|
| 169 |
-
`sr/256 = 172.27 Hz`, with an F3 fundamental β it reads as a wrong note, not as
|
| 170 |
-
noise. It is inaudible in a mix and obvious once a stem separator strips the
|
| 171 |
-
masking content, which is how it was found.
|
| 172 |
-
|
| 173 |
-
`squeakfix_v3` was trained with an explicit penalty on that structure
|
| 174 |
-
(`--lambda_patch 30`). A `v1` trained identically *without* it is the control.
|
| 175 |
-
|
| 176 |
-
Measured on the distribution that matters β audio **generated by the model
|
| 177 |
-
itself** (medium + a DiT LoRA), the same latents decoded through each adapter, so
|
| 178 |
-
the decoder is the only variable. Comb excess in dB over a control comb at
|
| 179 |
-
meaningless spacing, mean of 4 generations:
|
| 180 |
-
|
| 181 |
-
| variant | comb excess | vs stock |
|
| 182 |
-
|---|---|---|
|
| 183 |
-
| stock | 2.80 | β |
|
| 184 |
-
| v1 @ strength 1 | 13.70 | **+10.90** |
|
| 185 |
-
| **v3 @ strength 1** | 1.97 | **β0.83** |
|
| 186 |
-
| stock, +3 round trips | 1.64 | β1.17 |
|
| 187 |
-
| v1 @ 1, +3 round trips | 13.34 | +10.54 |
|
| 188 |
-
| **v3 @ 1, +3 round trips** | 1.37 | **β1.43** |
|
| 189 |
-
| v1 @ strength 2 | 18.52 | +15.72 |
|
| 190 |
-
| **v3 @ strength 2** | 3.49 | **+0.68** |
|
| 191 |
-
|
| 192 |
-
v1 adds ~11 dB of comb. **v3 sits at or slightly below stock**, and stays there
|
| 193 |
-
under re-encoding. Even at strength 2 β double what it ships at, where every
|
| 194 |
-
effect is 2β4Γ clearer β it is within 0.7 dB of stock, while v1 is nearly 16 dB
|
| 195 |
-
above it.
|
| 196 |
-
|
| 197 |
-
One caveat for anyone reproducing this: on **real** audio pushed round the
|
| 198 |
-
autoencoder, rather than on model output, v3 measures +1.5 to +4.0 dB of comb
|
| 199 |
-
excess instead of ~0. Real music and model output are different distributions and
|
| 200 |
-
the artifact does not behave the same on both. Measure on generated audio β that
|
| 201 |
-
is what the decoder is actually asked to render, and it is where the artifact was
|
| 202 |
-
audible in the first place.
|
| 203 |
-
|
| 204 |
-
Other things worth knowing:
|
| 205 |
-
|
| 206 |
-
- **This is one checkpoint from one dataset**, and it was selected partly by ear.
|
| 207 |
-
The in-loop ladder kept improving past step 2000; step 2000 is what was chosen
|
| 208 |
-
on re-encode behaviour and listening. Your material may want a different one.
|
| 209 |
-
- **The squeaks it targets are partly an upstream prompt-distribution problem.**
|
| 210 |
-
Out-of-distribution prompts produce far more of the offending frames than
|
| 211 |
-
in-distribution ones. This adapter reduces the artifact; it does not make
|
| 212 |
prompt choice irrelevant.
|
| 213 |
-
- **
|
| 214 |
-
|
| 215 |
-
continuations or transforms, it compounds in your favour.
|
| 216 |
-
- **It is a SAME-L adapter.** SAME-S has the same patch grid but its artifact
|
| 217 |
-
sits in a different band (1β8 kHz rather than 6 kHz and up) and wants a
|
| 218 |
-
different recipe. Loading this on SAME-S will not error β it will just sound
|
| 219 |
-
wrong.
|
| 220 |
- **Neither half of the autoencoder is bit-deterministic** (encoder 1.5 %
|
| 221 |
-
relative, decoder 7e-3 max abs)
|
| 222 |
-
read as a multiple of those floors; absolute tolerances are meaningless.
|
| 223 |
-
|
| 224 |
-
---
|
| 225 |
|
| 226 |
## Training
|
| 227 |
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
| rank / alpha | 16 / 16.0 |
|
| 233 |
-
| trainable | 5.63M params, 98 tensors (~1.30 % of the decoder) |
|
| 234 |
-
| checkpoint | step 2000 of a run configured for 8000, stopped at 4000 |
|
| 235 |
-
| precision | fp32 training, fp16 storage |
|
| 236 |
-
| hardware | single GB10 (DGX Spark), ~2.9 s/step at 10 s crops, under 10 GB |
|
| 237 |
|
| 238 |
```bash
|
| 239 |
python scripts/train_decoder_lora.py \
|
|
@@ -246,39 +199,16 @@ python scripts/train_decoder_lora.py \
|
|
| 246 |
--out_dir out/declora
|
| 247 |
```
|
| 248 |
|
| 249 |
-
The objective is self-supervised β audio only, no captions, no paired data.
|
| 250 |
Latents come from three buckets: real audio, drifted audio (`E(D(E(x)))` at depth
|
| 251 |
-
β₯ 1, targeted against the **original**
|
| 252 |
-
accumulated drift), and latents sampled from the base DiT.
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
Losses: multi-resolution log-STFT L1 (K-weighted, kept deliberately β this
|
| 257 |
-
decoder over-generates HF, so removing the perceptual de-emphasis would push the
|
| 258 |
-
wrong way), relative round-trip consistency `βE(D(z)) β zβ/βzβ` with the encoder
|
| 259 |
-
frozen, a **one-sided** HF tonality penalty (so legitimate cymbal ring and
|
| 260 |
-
sibilance are never punished), and the patch-grid penalty described above. No
|
| 261 |
-
discriminator: adversarial training makes a decoder invent *more* detail, and the
|
| 262 |
-
failure mode of plain reconstruction losses is the direction this wants.
|
| 263 |
-
|
| 264 |
-
Full method, ablations and traps: [Decoder LoRA
|
| 265 |
-
workflow](https://github.com/Stability-AI/stable-audio-3/blob/main/docs/workflows/decoder-lora.md).
|
| 266 |
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|---|---|
|
| 273 |
-
| `squeakfix_v3.safetensors` | the adapter β SAME-L decoder, rank 16, trained with `--lambda_patch 30` |
|
| 274 |
-
|
| 275 |
-
Provenance (base model, step, full recipe) is embedded in the file's
|
| 276 |
-
`lora_config` metadata, so it identifies itself without this card.
|
| 277 |
-
|
| 278 |
-
The `v1` column in the tables above is an internal checkpoint trained on the
|
| 279 |
-
identical recipe with `--lambda_patch 0`. It is not published β it is reported
|
| 280 |
-
because "the patch penalty matters" is a claim that needs the control.
|
| 281 |
-
|
| 282 |
-
## Citation
|
| 283 |
|
| 284 |
The autoencoder this adapts: [SAME](https://arxiv.org/abs/2605.18613).
|
|
|
|
| 17 |
# SAME-L Decoder LoRA (`squeakfix_v3`)
|
| 18 |
|
| 19 |
A LoRA on **SAME-L's decoder**. It changes how latents are rendered to audio, not
|
| 20 |
+
how latents are produced β the encoder is untouched, so the latent space, the DiT
|
| 21 |
+
and every existing DiT LoRA stay bit-compatible, and this stacks with them in any
|
| 22 |
+
order.
|
| 23 |
|
| 24 |
+
It fixes one thing: the high-frequency squeaks SAME's autoencoder manufactures on
|
| 25 |
+
percussion when audio goes round the encode/decode loop more than once. SAME
|
| 26 |
+
downsamples 44.1 kHz stereo by 4096Γ, so a snare attack lives entirely inside a
|
| 27 |
+
single latent frame β the decoder doesn't reconstruct that attack, it
|
| 28 |
+
resynthesizes one, slightly differently every pass. Nothing in SAME's training
|
| 29 |
+
objective ever asked that `encode(decode(z)) β z`; every loss is
|
| 30 |
+
`real audio β latent β real audio`. This adapter adds that objective after the
|
| 31 |
+
fact, on the decoder only. Since a continuation or a transform re-encodes its
|
| 32 |
+
input, a chained session compounds the artifact β that's where this earns its
|
| 33 |
+
place.
|
| 34 |
|
| 35 |
+
Trained and used by [the collabage patch](https://huggingface.co/thepatch), in
|
| 36 |
+
production in a live `stable-audio-3` backend since 2026-08-14. Ship at
|
| 37 |
+
strength **1.0** β that's where it was trained and auditioned.
|
|
|
|
| 38 |
|
| 39 |
+
## Hear it
|
|
|
|
| 40 |
|
| 41 |
+
Since we keep struggling to produce clean metrics surrounding this artifact, we
|
| 42 |
+
place these examples so you can really hear what it's doing.
|
| 43 |
+
|
| 44 |
+
Same latent, same seed, decoder adapter the only variable; every clip is 15 s,
|
| 45 |
+
peak-matched to β1 dBFS so level can't masquerade as quality. Generated with the
|
| 46 |
+
`koan` DiT LoRA on `medium`.
|
| 47 |
+
|
| 48 |
+
### Round trips β where it earns its place
|
| 49 |
+
|
| 50 |
+
| | stock decoder | `squeakfix_v3` |
|
| 51 |
+
|---|---|---|
|
| 52 |
+
| **jungle** β fresh generation | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/jungle_stock_d0.wav"></audio> | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/jungle_v3_d0.wav"></audio> |
|
| 53 |
+
| **jungle** β after 3 round trips | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/jungle_stock_d3.wav"></audio> | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/jungle_v3_d3.wav"></audio> |
|
| 54 |
+
| **drums** β fresh generation | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/drums_stock_d0.wav"></audio> | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/drums_v3_d0.wav"></audio> |
|
| 55 |
+
| **drums** β after 3 round trips | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/drums_stock_d3.wav"></audio> | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/drums_v3_d3.wav"></audio> |
|
| 56 |
+
| **neurofunk** β fresh generation | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/neurofunk_stock_d0.wav"></audio> | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/neurofunk_v3_d0.wav"></audio> |
|
| 57 |
+
| **neurofunk** β after 3 round trips | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/neurofunk_stock_d3.wav"></audio> | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/neurofunk_v3_d3.wav"></audio> |
|
| 58 |
+
|
| 59 |
+
These three prompts were **not** selected for artifact content β they are
|
| 60 |
+
ordinary koan generations, and the fresh-generation rows are here so you can
|
| 61 |
+
follow the progression rather than because much is audible in them. Three round
|
| 62 |
+
trips is a short chained session: two continuations and a transform get you
|
| 63 |
+
there. jungle is the worst of the three; drums and neurofunk are unremarkable.
|
| 64 |
+
|
| 65 |
+
It isn't winning by sanding the top end, which is the easy way to fake this. At
|
| 66 |
+
d3 all three hold **2.0 to 9.3 dB more** 12β16 kHz and 16β22 kHz energy than the
|
| 67 |
+
stock render, at a higher RMS, while showing a fraction of the tonal frames. The
|
| 68 |
+
only band that ever drops is 8β12 kHz on the drums clip, by 0.9 dB β and that is
|
| 69 |
+
exactly where the artifact concentrates.
|
| 70 |
+
|
| 71 |
+
### A fresh generation β subtler, but we do hear it
|
| 72 |
+
|
| 73 |
+
We swear we hear it on initial generations too, and it is **much** more subtle.
|
| 74 |
+
This pair is the worst of 16 candidates, screened by how far tonality runs away
|
| 75 |
+
over 3 round trips with the adapter off β screening is how you find an audible
|
| 76 |
+
A/B for something this small, and it means this pair is a worst case, not a
|
| 77 |
+
typical one.
|
| 78 |
+
|
| 79 |
+
| | stock decoder | `squeakfix_v3` |
|
| 80 |
+
|---|---|---|
|
| 81 |
+
| **glitch hop** β fresh generation, screened | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/glitchhop_stock_d0.wav"></audio> | <audio controls src="https://huggingface.co/thepatch/same-l-decoder-lora/resolve/main/samples/glitchhop_v3_d0.wav"></audio> |
|
| 82 |
+
|
| 83 |
+
What changes here is **air, not squeak count**. Across the three screened
|
| 84 |
+
generations the adapter moves tonality by β0.37 dB at d0 β nothing β while
|
| 85 |
+
restoring **1.5 to 2.4 dB** of 16β22 kHz top octave in every one. On this
|
| 86 |
+
particular pair tonality moves β0.08 dB, i.e. not at all, and air moves +2.4 dB.
|
| 87 |
+
If you are looking for the difference in a tonal-frame count you will not find
|
| 88 |
+
it.
|
| 89 |
|
| 90 |
## Usage
|
| 91 |
|
| 92 |
+
Requires `target: "decoder"` support in
|
| 93 |
[Stability-AI/stable-audio-3](https://github.com/Stability-AI/stable-audio-3).
|
| 94 |
+
The `target` field in the checkpoint config is what routes it; there's no special
|
| 95 |
+
loading path.
|
| 96 |
|
| 97 |
```bash
|
| 98 |
+
python run_gradio.py --model medium-base --lora-ckpt-path squeakfix_v3.safetensors
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
|
| 100 |
+
# stacks with a DiT LoRA, either order
|
| 101 |
python run_gradio.py --model medium-base \
|
| 102 |
--lora-ckpt-path my_style.safetensors squeakfix_v3.safetensors
|
| 103 |
```
|
| 104 |
|
|
|
|
|
|
|
| 105 |
```python
|
| 106 |
from stable_audio_3 import AutoencoderModel
|
| 107 |
from stable_audio_3.models.lora.loader import load_and_apply_loras
|
| 108 |
+
from stable_audio_3.models.lora.model import set_lora_strength
|
| 109 |
|
| 110 |
ae = AutoencoderModel.from_pretrained("same-l", device="cuda").autoencoder
|
| 111 |
load_and_apply_loras(ae, ["squeakfix_v3.safetensors"], "autoencoder")
|
| 112 |
+
set_lora_strength(ae.decoder, 1.0) # separate call; 0.0 is the stock decode
|
| 113 |
|
| 114 |
+
audio = ae.decode(ae.encode(waveform))
|
|
|
|
| 115 |
```
|
| 116 |
|
| 117 |
+
## Measured
|
| 118 |
+
|
| 119 |
+
Four `koan` generations of 2 minutes, screened from 12 candidates by how far
|
| 120 |
+
6β16 kHz tonality runs away with the adapter off. Each latent is decoded twice β
|
| 121 |
+
adapter off, adapter on β and each chain re-encodes in place, so dN is genuinely
|
| 122 |
+
N round trips of that decoder config. The adapter is the only variable.
|
| 123 |
+
|
| 124 |
+
| depth | tonality p95 | tonal frames | 12β16 kHz | SI-SDR vs own d0 |
|
| 125 |
+
|---|---|---|---|---|
|
| 126 |
+
| d0 β fresh generation | 11.25 β 11.33 | 780 β 933 | 20.7 β 21.4 | β |
|
| 127 |
+
| d1 β one continuation or transform | 12.46 β **11.59** | 972 β 1074 | 19.9 β **21.2** | 13.5 β **17.5** |
|
| 128 |
+
| d2 | 14.42 β **11.81** | 1492 β **1246** | 19.3 β **21.0** | 8.9 β **12.8** |
|
| 129 |
+
| d3 | 17.03 β **12.06** | 2453 β **1411** | 18.6 β **20.9** | 6.7 β **10.4** |
|
| 130 |
+
|
| 131 |
+
**Stock tonality climbs +5.79 dB over three round trips. With the adapter it
|
| 132 |
+
climbs +0.73 dB.** That holds on every generation individually β stock +4.98 to
|
| 133 |
+
+6.97, the adapter +0.18 to +1.40 β and it is the whole claim: the artifact
|
| 134 |
+
stops compounding.
|
| 135 |
+
|
| 136 |
+
**The tonal-frame column rises at d0 and d1, and that is not a regression.**
|
| 137 |
+
That count rewards peakiness, and the adapter puts high-frequency energy back;
|
| 138 |
+
restored harmonics read as tonal. It is also dominated by two of the four
|
| 139 |
+
generations, which start near 1000 and 2100 frames because glitchcore genuinely
|
| 140 |
+
is tonal. The other two start at **zero** and stay there with the adapter β 0 β
|
| 141 |
+
39 and 0 β 8 at d3 β while stock reaches 1038 and 268. Where the artifact has
|
| 142 |
+
room to appear, the adapter suppresses it; where the material is already tonal,
|
| 143 |
+
the count cannot tell artifact from content. Read p95, not the count.
|
| 144 |
+
|
| 145 |
+
**It is not sanding the top end**, which is the easy way to post a good number.
|
| 146 |
+
At every depth it holds more 12β16 kHz energy than stock and the gap *widens*
|
| 147 |
+
with depth (+0.70, +1.31, +1.76, +2.30 dB at d0βd3), while SI-SDR against its
|
| 148 |
+
own d0 runs 3.6 to 3.9 dB better. It drifts less rather than erasing what drifts.
|
| 149 |
+
|
| 150 |
+
At d0 the change is air, not squeak count: on a separate screened 30 s set the
|
| 151 |
+
adapter moves tonality by β0.37 dB β nothing β while restoring 1.5 to 2.4 dB of
|
| 152 |
+
16β22 kHz top octave in all three generations. Trust the clips above over any of
|
| 153 |
+
these numbers.
|
| 154 |
+
|
| 155 |
+
This table is `koan` at 120 s and fp16. An earlier unscreened run covering `kev`
|
| 156 |
+
as well, at both 30 s and 120 s, showed the same direction at depth.
|
| 157 |
+
|
| 158 |
+
## Limits
|
| 159 |
+
|
| 160 |
+
- **Decoder LoRAs trained this way stamp a comb into the output β this one
|
| 161 |
+
doesn't, and that's most of why it exists.** The un-patch is a bare reshape at
|
| 162 |
+
`patch_size 256`, so output channel and time-position-within-patch are the same
|
| 163 |
+
axis, and any channel-wise bias the adapter learns repeats identically in every
|
| 164 |
+
patch: a harmonic comb at `sr/256 = 172.27 Hz` that reads as a wrong note, not
|
| 165 |
+
as noise. Inaudible in a mix, obvious once a stem separator strips the masking
|
| 166 |
+
content, which is how it was found. `--lambda_patch 30` is what prevents it. On
|
| 167 |
+
model output, a `v1` control trained on the identical recipe with
|
| 168 |
+
`--lambda_patch 0` sits **+10.9 dB** of comb excess over stock; v3 sits
|
| 169 |
+
**β0.8 dB**, and both hold that gap through three further round trips. On
|
| 170 |
+
*real* audio rather than model output v3 measures +1.5 to +4.0 dB β different
|
| 171 |
+
distribution, so measure on generated audio.
|
| 172 |
+
- **SAME-L only.** SAME-S shares the patch grid but its artifact sits 1β8 kHz and
|
| 173 |
+
wants a different recipe. Loading this there won't error; it'll sound wrong.
|
| 174 |
+
- **The gain scales with re-encode depth** β small for one-shot generation, it
|
| 175 |
+
compounds across chained continuations.
|
| 176 |
+
- **The squeaks are partly an upstream prompt-distribution problem.** OOD prompts
|
| 177 |
+
produce far more offending frames; this reduces the artifact, it doesn't make
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
prompt choice irrelevant.
|
| 179 |
+
- **One checkpoint, one dataset, chosen partly by ear** at step 2000 on re-encode
|
| 180 |
+
behaviour. Your material may want a different one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
- **Neither half of the autoencoder is bit-deterministic** (encoder 1.5 %
|
| 182 |
+
relative, decoder 7e-3 max abs) β read any A/B as a multiple of those floors.
|
|
|
|
|
|
|
|
|
|
| 183 |
|
| 184 |
## Training
|
| 185 |
|
| 186 |
+
Self-supervised β audio only, no captions, no paired data. Rank 16 / alpha 16,
|
| 187 |
+
5.63M trainable params (~1.30 % of the decoder), step 2000 of a run configured
|
| 188 |
+
for 8000, fp32 training and fp16 storage, single GB10 (DGX Spark) at ~2.9 s/step
|
| 189 |
+
on 10 s crops, under 10 GB.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
|
| 191 |
```bash
|
| 192 |
python scripts/train_decoder_lora.py \
|
|
|
|
| 199 |
--out_dir out/declora
|
| 200 |
```
|
| 201 |
|
|
|
|
| 202 |
Latents come from three buckets: real audio, drifted audio (`E(D(E(x)))` at depth
|
| 203 |
+
β₯ 1, targeted against the **original** so the decoder is asked to undo
|
| 204 |
+
accumulated drift), and latents sampled from the base DiT. No discriminator β
|
| 205 |
+
adversarial training makes a decoder invent *more* detail, and the failure mode
|
| 206 |
+
of plain reconstruction losses is the direction this wants.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
|
| 208 |
+
Full method, losses, ablations and traps: [Decoder LoRA
|
| 209 |
+
workflow](https://github.com/Stability-AI/stable-audio-3/blob/main/docs/workflows/decoder-lora.md).
|
| 210 |
+
Provenance β base model, step, full recipe β is embedded in the file's
|
| 211 |
+
`lora_config` metadata, so the checkpoint identifies itself without this card.
|
| 212 |
+
`v1` (identical recipe, `--lambda_patch 0`) is an internal control, not published.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
|
| 214 |
The autoencoder this adapts: [SAME](https://arxiv.org/abs/2605.18613).
|