Stable Audio 3
English
music
audio
autoencoder
lora
thecollabagepatch commited on
Commit
5005213
Β·
verified Β·
1 Parent(s): 3f7b12e

Tighten card: audio first, drop hedging, no em dashes

Browse files
Files changed (1) hide show
  1. README.md +81 -128
README.md CHANGED
@@ -17,82 +17,46 @@ 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 β€” 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
@@ -114,79 +78,68 @@ set_lora_strength(ae.decoder, 1.0) # separate call; 0.0 is the stock decode
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 \
@@ -200,15 +153,15 @@ python scripts/train_decoder_lora.py \
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).
 
 
 
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, so the latent space, the DiT and every existing DiT
21
+ LoRA stay bit-compatible and this stacks with them in any order.
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ It targets the high-frequency squeaks SAME's autoencoder adds to percussion when
24
+ audio goes round the encode/decode loop more than once. A continuation or a
25
+ transform re-encodes its input, so a chained session compounds them.
 
 
 
 
 
26
 
27
+ ## Listen
 
 
 
 
28
 
29
  | | stock decoder | `squeakfix_v3` |
30
  |---|---|---|
31
+ | **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> |
32
+ | **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> |
33
+ | **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> |
34
+ | **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> |
35
+ | **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> |
36
+ | **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> |
37
+
38
+ 15 s clips, same latent and seed, decoder adapter the only variable, peak-matched
39
+ to βˆ’1 dBFS. Generated with the `koan` DiT LoRA on `medium`. These three prompts
40
+ were not picked for artifact content, and the fresh-generation rows are there to
41
+ show the progression rather than because much is audible in them.
42
+
43
+ ### On a fresh generation
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  | | stock decoder | `squeakfix_v3` |
46
  |---|---|---|
47
+ | **glitch hop**, worst of 16 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> |
48
 
49
+ Much subtler, and it took screening 16 candidates by tonality runaway to find a
50
+ pair where it carries. What changes here is air rather than squeak count: on this
51
+ pair tonality moves 0.08 dB, which is nothing, while 16-22 kHz comes back
52
+ +2.4 dB.
 
 
53
 
54
  ## Usage
55
 
56
  Requires `target: "decoder"` support in
57
  [Stability-AI/stable-audio-3](https://github.com/Stability-AI/stable-audio-3).
58
+ The `target` field in the checkpoint config routes it; there is no special
59
+ loading path. Ship at strength **1.0**, where it was trained and auditioned.
60
 
61
  ```bash
62
  python run_gradio.py --model medium-base --lora-ckpt-path squeakfix_v3.safetensors
 
78
  audio = ae.decode(ae.encode(waveform))
79
  ```
80
 
81
+ ## Numbers
82
 
83
+ Four `koan` generations of 2 minutes, screened from 12 candidates by tonality
84
+ runaway. Each latent is decoded twice, adapter off and on, and each chain
85
+ re-encodes in place, so dN is N round trips of that decoder config.
 
86
 
87
+ | depth | tonality p95 | tonal frames | 12-16 kHz | SI-SDR vs own d0 |
88
  |---|---|---|---|---|
89
+ | d0, fresh generation | 11.25 β†’ 11.33 | 780 β†’ 933 | 20.7 β†’ 21.4 | |
90
+ | d1, one continuation | 12.46 β†’ **11.59** | 972 β†’ 1074 | 19.9 β†’ **21.2** | 13.5 β†’ **17.5** |
91
  | d2 | 14.42 β†’ **11.81** | 1492 β†’ **1246** | 19.3 β†’ **21.0** | 8.9 β†’ **12.8** |
92
  | d3 | 17.03 β†’ **12.06** | 2453 β†’ **1411** | 18.6 β†’ **20.9** | 6.7 β†’ **10.4** |
93
 
94
+ Stock tonality climbs **+5.79 dB** over three round trips. With the adapter it
95
+ climbs **+0.73 dB**, and that holds on all four generations individually (stock
96
+ +4.98 to +6.97, adapter +0.18 to +1.40). The artifact stops compounding.
97
+
98
+ The frame count rises at d0 and d1 because the adapter puts high-frequency energy
99
+ back and the detector counts peakiness, so restored harmonics read as tonal. It
100
+ is also dominated by two of the four generations, which start near 1000 and 2100
101
+ frames because glitchcore genuinely is tonal. The other two start at zero and
102
+ stay near zero with the adapter (0 β†’ 39 and 0 β†’ 8 at d3) while stock reaches 1038
103
+ and 268. Read p95.
104
+
105
+ The adapter holds more 12-16 kHz than stock at every depth and the gap widens
106
+ with re-encoding (+0.70, +1.31, +1.76, +2.30 dB at d0 to d3), while SI-SDR
107
+ against its own d0 runs 3.6 to 3.9 dB better. It drifts less rather than erasing
108
+ what drifts.
 
 
 
 
 
 
 
 
109
 
110
  This table is `koan` at 120 s and fp16. An earlier unscreened run covering `kev`
111
+ as well, at 30 s and 120 s, showed the same direction at depth.
112
 
113
  ## Limits
114
 
115
+ - **Decoder LoRAs trained this way stamp a comb into the output.** The un-patch
116
+ is a bare reshape at `patch_size 256`, so output channel and
117
+ time-position-within-patch are the same axis, and any channel-wise bias the
118
+ adapter learns repeats in every patch. That is a harmonic comb at
119
+ `sr/256 = 172.27 Hz`, which reads as a wrong note rather than as noise. It is
120
+ inaudible in a mix and obvious once a stem separator strips the masking
121
+ content, which is how it was found. `--lambda_patch 30` is what prevents it: a
122
+ `v1` control trained without it sits **+10.9 dB** of comb excess over stock
123
+ while v3 sits **0.8 dB below** stock, and both hold through three further round
124
+ trips. On real audio rather than model output v3 measures +1.5 to +4.0 dB, so
125
+ measure on generated audio.
126
+ - **SAME-L only.** SAME-S shares the patch grid but its artifact sits 1-8 kHz and
127
+ wants a different recipe. Loading this there will not error, it will sound
128
+ wrong.
129
+ - **The gain scales with re-encode depth**, so it is small for one-shot
130
+ generation and compounds across chained continuations.
131
+ - **The squeaks are partly a prompt-distribution problem.** Out-of-distribution
132
+ prompts produce far more of the offending frames.
133
+ - **One checkpoint, one dataset**, step 2000, chosen on re-encode behaviour and
134
+ listening. Your material may want a different one.
 
135
  - **Neither half of the autoencoder is bit-deterministic** (encoder 1.5 %
136
+ relative, decoder 7e-3 max abs), so read any A/B as a multiple of those floors.
137
 
138
  ## Training
139
 
140
+ Self-supervised, audio only, no captions or paired data. Rank 16 / alpha 16,
141
+ 5.63M trainable params (~1.30 % of the decoder), fp32 training and fp16 storage,
142
+ single GB10 (DGX Spark) at ~2.9 s/step on 10 s crops, under 10 GB.
 
143
 
144
  ```bash
145
  python scripts/train_decoder_lora.py \
 
153
  ```
154
 
155
  Latents come from three buckets: real audio, drifted audio (`E(D(E(x)))` at depth
156
+ β‰₯ 1, targeted against the original so the decoder is asked to undo accumulated
157
+ drift), and latents sampled from the base DiT. No discriminator, since
158
+ adversarial training makes a decoder invent *more* detail.
 
159
 
160
  Full method, losses, ablations and traps: [Decoder LoRA
161
  workflow](https://github.com/Stability-AI/stable-audio-3/blob/main/docs/workflows/decoder-lora.md).
162
+ Provenance is embedded in the file's `lora_config` metadata. `v1` (identical
163
+ recipe, `--lambda_patch 0`) is an internal control, not published.
 
164
 
165
+ Trained and used by [the collabage patch](https://huggingface.co/thepatch), in
166
+ production in a live `stable-audio-3` backend since 2026-08-14. The autoencoder
167
+ this adapts: [SAME](https://arxiv.org/abs/2605.18613).