Upload README.md with huggingface_hub
Browse files
README.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
pipeline_tag: text-to-audio
|
| 4 |
+
language:
|
| 5 |
+
- en
|
| 6 |
+
tags:
|
| 7 |
+
- audio
|
| 8 |
+
- text-to-audio
|
| 9 |
+
- diffusion
|
| 10 |
+
- rectified-flow
|
| 11 |
+
- spectrogram
|
| 12 |
+
- clap
|
| 13 |
+
- custom-code
|
| 14 |
+
- tiny
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
# AudioModel v1 🔊
|
| 18 |
+
|
| 19 |
+
<p>
|
| 20 |
+
<audio controls src="samples/rain_falling_on_a_roof.wav"></audio> "rain falling on a roof"
|
| 21 |
+
</p>
|
| 22 |
+
<p>
|
| 23 |
+
<audio controls src="samples/footsteps_on_gravel.wav"></audio> "footsteps on gravel"
|
| 24 |
+
</p>
|
| 25 |
+
<p>
|
| 26 |
+
<audio controls src="samples/a_dog_barking.wav"></audio> "a dog barking"
|
| 27 |
+
</p>
|
| 28 |
+
<p>
|
| 29 |
+
<audio controls src="samples/a_car_engine_starting.wav"></audio> "a car engine starting"
|
| 30 |
+
</p>
|
| 31 |
+
|
| 32 |
+
A tiny text-to-audio diffusion model. You give it a sentence, it gives you 17.8
|
| 33 |
+
seconds of sound. It is 40,296,844 trained parameters and it trained in under four
|
| 34 |
+
hours on a single H100.
|
| 35 |
+
|
| 36 |
+
This is the PixelModel line moving into a third modality. v1 through v6 were tiny
|
| 37 |
+
latent diffusion for images, VoxelModel did 3D occupancy grids, and this one treats
|
| 38 |
+
a mel spectrogram as a grayscale image and runs the same DiT plus rectified flow
|
| 39 |
+
recipe on it. Same argument every time: low resolution as a deliberate aesthetic,
|
| 40 |
+
applied to a new kind of output.
|
| 41 |
+
|
| 42 |
+
## Why this combination didn't already exist
|
| 43 |
+
|
| 44 |
+
Riffusion proved that treating a spectrogram as an image and running image
|
| 45 |
+
diffusion on it works, including inverting it back to audio. But Riffusion is a
|
| 46 |
+
fine-tune of Stable Diffusion v1.5, not trained from scratch, and not tiny.
|
| 47 |
+
tiny-audio-diffusion is from scratch and genuinely small, but it diffuses raw
|
| 48 |
+
waveforms, not spectrograms, and isn't built for free-text conditioning.
|
| 49 |
+
AudioLDM and Make-An-Audio are the real text-to-audio research lineage, but both
|
| 50 |
+
are full-scale systems with a VAE-compressed latent space and a separately trained
|
| 51 |
+
vocoder, not something you train from scratch on a rented GPU in an afternoon.
|
| 52 |
+
|
| 53 |
+
Nothing combined from-scratch, hobbyist scale, spectrogram-as-image, rectified
|
| 54 |
+
flow, and free-text CLAP conditioning in one place. That's the gap this fills.
|
| 55 |
+
|
| 56 |
+
## The one honest result
|
| 57 |
+
|
| 58 |
+
FAD (Frechet Audio Distance, PANN embeddings) on 300 held-out Clotho evaluation
|
| 59 |
+
clips, comparing three things against real audio:
|
| 60 |
+
|
| 61 |
+

|
| 62 |
+
|
| 63 |
+
Text conditioning clearly helps: 67.0 with a real prompt against 87.1 with no
|
| 64 |
+
prompt at all. And the model is not that far from the ceiling a Griffin-Lim
|
| 65 |
+
vocoder allows in the first place: taking real audio, converting it to our exact
|
| 66 |
+
mel spectrogram, and inverting it right back with Griffin-Lim already costs 60.5
|
| 67 |
+
FAD against the original file, before the model has generated anything. Most of
|
| 68 |
+
the remaining distance between the model and real audio is the vocoder, not the
|
| 69 |
+
model.
|
| 70 |
+
|
| 71 |
+
Worth knowing if you use this number: PANN embeddings are 2048-dimensional and our
|
| 72 |
+
full held-out evaluation split is only 1,045 clips, so the covariance estimate
|
| 73 |
+
behind FAD is structurally rank-deficient here. Scipy warns about it
|
| 74 |
+
(`LinAlgWarning: Matrix is singular`) and it would still warn even using every
|
| 75 |
+
single held-out clip we have, since 1,045 is still under 2,048. The relative
|
| 76 |
+
ordering of the three numbers is the trustworthy part, not their precision to one
|
| 77 |
+
decimal place.
|
| 78 |
+
|
| 79 |
+
We also found a real bug while computing this: the `frechet_audio_distance`
|
| 80 |
+
library's PANN path concatenates each clip's flat 2048-length embedding with
|
| 81 |
+
`np.concatenate` instead of stacking them, which silently collapses 300 separate
|
| 82 |
+
embeddings into one 614,400-length vector and breaks the statistics downstream.
|
| 83 |
+
Their own README admits PANN isn't covered by CI. `eval_fad.py` reshapes the
|
| 84 |
+
embeddings back to `(n, 2048)` before computing FAD, which is the whole fix.
|
| 85 |
+
|
| 86 |
+
## Training
|
| 87 |
+
|
| 88 |
+

|
| 89 |
+
|
| 90 |
+
| | |
|
| 91 |
+
|---|---|
|
| 92 |
+
| clips | 3,839 train (development split), 1,045 held out (validation split) |
|
| 93 |
+
| pairs | 19,195, since each clip carries 5 independent captions |
|
| 94 |
+
| steps | 90,000 at batch 256 |
|
| 95 |
+
| hardware | one H100 SXM 80GB, 6.51 steps/s, 28.3 GiB |
|
| 96 |
+
| wall clock | 3.85 hours |
|
| 97 |
+
| optimizer | AdamW 2e-4, betas (0.9, 0.99), grad clip 1.0 |
|
| 98 |
+
| schedule | cosine to 1e-6, 500 step warmup |
|
| 99 |
+
| EMA | 0.9999 |
|
| 100 |
+
| CFG dropout | 10% |
|
| 101 |
+
|
| 102 |
+
Held-out loss bottomed at **0.06961 at step 54,000** and drifted up to 0.07078 by
|
| 103 |
+
step 90,000. That's a real overfitting inflection, and it arrives earlier than it
|
| 104 |
+
did on VoxelModel (step 64,000 of 90,000 there), which makes sense: Clotho's
|
| 105 |
+
development split has 3,839 unique clips against VoxelModel's 28,415 unique
|
| 106 |
+
meshes, so the same step budget means a lot more repetition per unique example
|
| 107 |
+
here. The shipped weights are the step 54,000 EMA checkpoint, not the step 90,000
|
| 108 |
+
final one, because this run saves the best validation checkpoint separately as it
|
| 109 |
+
trains. VoxelModel v1 didn't do this and lost its own best checkpoint to an
|
| 110 |
+
overwrite bug. That was worth fixing before this run, not after.
|
| 111 |
+
|
| 112 |
+
## No VAE, but not zero baggage either
|
| 113 |
+
|
| 114 |
+
AudioModel diffuses directly on the mel spectrogram image. There's no autoencoder
|
| 115 |
+
compressing it first, which is the same "no asterisk" choice VoxelModel made for
|
| 116 |
+
voxels instead of copying AudioLDM's VAE step. Total trained footprint is 40.30M.
|
| 117 |
+
|
| 118 |
+
Conditioning is frozen CLAP (`laion/clap-htsat-unfused`), cross-attention on the
|
| 119 |
+
RoBERTa text tower's last hidden state (768 dim, 32 tokens) plus adaLN-zero from
|
| 120 |
+
the projected pooled embedding (512 dim). Loading `ClapModel` pulls in the whole
|
| 121 |
+
153.49M-parameter checkpoint, audio tower included, but only the text tower and
|
| 122 |
+
projection, 125.30M of it, ever runs a forward pass here. The HTSAT audio encoder
|
| 123 |
+
just sits there unused. If you're adapting this code, swapping in a text-only CLAP
|
| 124 |
+
checkpoint would trim that dead weight; we didn't bother for a single training run.
|
| 125 |
+
|
| 126 |
+
## Architecture
|
| 127 |
+
|
| 128 |
+
`AudioDiT` patchifies a 384x256 mel spectrogram at patch size 16, giving a 24x16
|
| 129 |
+
grid, 384 tokens, dim 384, depth 12, heads 6. Positional encoding is a 2D sincos
|
| 130 |
+
over that grid. Objective is rectified flow with `target = x1 - x0` and
|
| 131 |
+
logit-normal timestep sampling, `t = sigmoid(randn)`, identical to VoxelModel's
|
| 132 |
+
objective on a different kind of image.
|
| 133 |
+
|
| 134 |
+
## Data
|
| 135 |
+
|
| 136 |
+
Clotho v2.1 (Drossos, Lipping and Virtanen, DCASE 2020), from Zenodo, not from an
|
| 137 |
+
HF mirror since none of the official kind exists. Development split for training,
|
| 138 |
+
validation split for the held-out loss during training, evaluation split reserved
|
| 139 |
+
untouched for the FAD numbers above. Each clip carries 5 independent crowdsourced
|
| 140 |
+
captions, and all 5 get used as separate training pairs against the same
|
| 141 |
+
spectrogram rather than picking one, which is a free 5x on the text side without
|
| 142 |
+
touching the audio side.
|
| 143 |
+
|
| 144 |
+
Spectrograms come from `diffusers.pipelines.deprecated.audio_diffusion.mel.Mel`
|
| 145 |
+
at `x_res=384, hop_length=1024`, both bumped from the library's defaults
|
| 146 |
+
(`x_res=256, hop_length=512`) to cover 17.8 seconds instead of 5.9. `y_res=256`
|
| 147 |
+
mel bins is the library default, left alone. The `Mel` class already pads short
|
| 148 |
+
clips with silence and only reads the first slice of longer ones, so every clip
|
| 149 |
+
in the 15 to 30 second Clotho range ends up as a fixed 17.8 second window starting
|
| 150 |
+
at the beginning of the clip, no custom windowing logic needed.
|
| 151 |
+
|
| 152 |
+
Griffin-Lim, 32 iterations, is the inversion back to audio. It's the zero-training
|
| 153 |
+
default and it's known to sound phasey and metallic compared to a learned vocoder
|
| 154 |
+
like BigVGAN-v2. We didn't swap one in for v1: the FAD numbers above suggest the
|
| 155 |
+
vocoder actually is the dominant source of remaining distance from real audio, so
|
| 156 |
+
that's the correct place to spend effort on a v2, not on the diffusion model
|
| 157 |
+
itself.
|
| 158 |
+
|
| 159 |
+
## Usage
|
| 160 |
+
|
| 161 |
+
```bash
|
| 162 |
+
python sample.py "a dog barking" "rain falling on a roof" --cfg 4.0 --steps 50
|
| 163 |
+
```
|
| 164 |
+
|
| 165 |
+
Writes 17.8 second WAVs at 22,050 Hz to `--out-dir`.
|
| 166 |
+
|
| 167 |
+
## What v1 does not do
|
| 168 |
+
|
| 169 |
+
**A learned vocoder.** Griffin-Lim is what's shipped. The FAD breakdown above is
|
| 170 |
+
the argument for why that's a defensible v1 choice and not just laziness.
|
| 171 |
+
|
| 172 |
+
**More than 300 clips of FAD signal.** The evaluation split only has 1,045 clips
|
| 173 |
+
total and PANN embeddings are 2048-dimensional, so the covariance estimate behind
|
| 174 |
+
every FAD number in this card is on the edge of what's estimable at all. Treat the
|
| 175 |
+
ordering as real and the decimal places as decoration.
|
| 176 |
+
|
| 177 |
+
**Augmentation.** 90,000 steps over 3,839 unique clips is a lot of repetition with
|
| 178 |
+
nothing to break it up. Time-shift or pitch-shift augmentation on the waveform
|
| 179 |
+
before spectrogram conversion is the obvious next lever, same shape of fix as the
|
| 180 |
+
yaw-and-mirror augmentation flagged as unbuilt on VoxelModel v1.
|
| 181 |
+
|
| 182 |
+
## Files
|
| 183 |
+
|
| 184 |
+
| file | what |
|
| 185 |
+
|---|---|
|
| 186 |
+
| `model.safetensors` | EMA weights at step 90,000 |
|
| 187 |
+
| `model_best.safetensors` | EMA weights at step 54,000, the shipped checkpoint |
|
| 188 |
+
| `audio_dit.py` | the model |
|
| 189 |
+
| `train.py` | training loop |
|
| 190 |
+
| `sample.py` | inference |
|
| 191 |
+
| `eval_fad.py` | FAD evaluation against held-out real audio |
|
| 192 |
+
| `fetch_clotho.py` | Zenodo download and extraction |
|
| 193 |
+
| `build_data.py` | mel spectrogram and CLAP embedding precompute |
|
| 194 |
+
| `benchmark_throughput.py` | the throughput check this run's batch size came from |
|
| 195 |
+
| `config.json` | architecture and training config |
|
| 196 |
+
| `fad_results.json` | the raw numbers behind the FAD chart |
|
| 197 |
+
| `requirements.txt` | what you need installed to run any of the above |
|
| 198 |
+
| `samples/` | the four clips embedded at the top of this card |
|