Sidharthan commited on
Commit
ac841dc
·
verified ·
1 Parent(s): 261df1e

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +327 -176
README.md CHANGED
@@ -7,63 +7,35 @@ tags:
7
  - dit
8
  - audio
9
  - educational
10
- - from-scratch
11
  pipeline_tag: text-to-audio
12
  ---
13
 
14
  # QaDiT — text-to-audio latent Diffusion Transformer
15
 
16
- > **Educational / research build.** This is not a state-of-the-art text-to-audio
17
- > system. It is a from-scratch DiT trained on a budget so you can see how latent
18
- > audio diffusion is wired, how the loss behaves, and what a mid-scale run
19
- > actually produces. The model already learns useful representations and can
20
- > generate solid samples for many prompts — but peak quality will need longer
21
- > training and broader data. That next stage is planned.
22
 
23
- Part of **[QuarkML](PLACEHOLDER_WEBSITE)** public lab notes by
24
- **[Sidharth GN](PLACEHOLDER_AUTHOR_PAGE)**: pick an architecture, implement it
25
- from nothing, train it on hardware a normal person can afford, then publish the
26
- code, weights, numbers, and what broke along the way.
27
 
28
- | | |
29
- | --- | --- |
30
- | **Website write-up** | [PLACEHOLDER_WEBSITE_POST](PLACEHOLDER_WEBSITE_POST) |
31
- | **Training / sampling code** | [PLACEHOLDER_GITHUB_REPO](PLACEHOLDER_GITHUB_REPO) |
32
- | **This weights repo** | [PLACEHOLDER_HF_MODEL](PLACEHOLDER_HF_MODEL) |
33
- | **Author** | [Sidharth GN](PLACEHOLDER_AUTHOR_PAGE) · [QuarkML](PLACEHOLDER_WEBSITE) |
34
- | **Contact / social** | [PLACEHOLDER_TWITTER](PLACEHOLDER_TWITTER) · [PLACEHOLDER_LINKEDIN](PLACEHOLDER_LINKEDIN) · [PLACEHOLDER_EMAIL](mailto:PLACEHOLDER_EMAIL) |
35
 
36
  ---
37
 
38
- ## What this model is (and is not)
39
-
40
- **Is:** a ~159M-parameter latent Diffusion Transformer (DiT-B) that turns a text
41
- caption into **10.24 s of 16 kHz mono audio**. Built to teach the full stack —
42
- mel VAE latents, T5 conditioning, v-prediction training, DDIM + CFG sampling,
43
- REPA alignment — with runnable code and publishable weights.
44
 
45
- **Is not:** a production AudioLDM / Tango / Stable Audio competitor. Prompt
46
- adherence and timbre fidelity are good enough to demonstrate that the pipeline
47
- works and that the representation is learning, not good enough to claim SOTA.
48
- Improving that means **more steps, more diverse data, and the usual scaling
49
- knobs** — not a different architecture fantasy.
50
-
51
- If you came here to learn how modern latent audio diffusion is trained on a
52
- budget, you are in the right place. If you need broadcast-quality SFX on every
53
- prompt, wait for a longer run or use a larger released system.
54
-
55
- ---
56
-
57
- ## Architecture
58
-
59
- <!-- Replace the placeholder image with your diagram (e.g. assets/architecture.png). -->
60
 
61
  ![Architecture diagram](assets/architecture.png)
62
 
63
- *Placeholderdrop the DiT + T5 + VAE + vocoder diagram at
64
- `assets/architecture.png` (or update the path above).*
65
-
66
- **Pipeline at a glance**
67
 
68
  ```text
69
  caption
@@ -77,57 +49,294 @@ caption
77
  | Piece | Choice |
78
  | --- | --- |
79
  | Backbone | DiT-B — depth 12, width 768, 12 heads, MLP ratio 4.0 (~159M) |
80
- | Latent grid | `[8, 256, 16]` AudioLDM KL-VAE latents |
81
  | Patchify | 2×2 → **1024** tokens, fixed 2-D sincos positions |
82
  | Text | FLAN-T5-large cross-attention every block + pooled text in adaLN-Zero |
83
- | Train target | **v-prediction** (Salimans & Ho) |
84
  | Noise schedule | **cosine** ᾱ, T = 1000 |
85
- | Timestep sampling (train) | logit-normal (SD3-style) |
86
- | CFG | p_uncond = 0.1 train; default guidance scale **4.0** at sample |
87
- | Sampler | **DDIM**, default **50** steps, η = 0 (deterministic) |
88
- | Aux loss | REPA vs frozen AST features (train-time only; dropped at inference) |
89
- | Decode stack | `cvssp/audioldm-s-full-v2` VAE + HiFi-GAN vocoder |
90
 
91
- Weights in this repo are the **EMA** copy from training step **23999**.
 
92
 
93
  ---
94
 
95
- ## Training objective and sampling (DDIM + v-prediction)
96
 
97
- Training and sampling are deliberately a small, classic stack — easy to read
98
- in the code, not a research sampler zoo.
 
 
 
99
 
100
- **Forward process**
 
 
 
 
101
 
102
- \[
103
- z_t = \sqrt{\bar\alpha_t}\, z_0 + \sqrt{1-\bar\alpha_t}\,\varepsilon
104
- \]
105
 
106
- **Network target (v-prediction)**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
- \[
109
- v = \sqrt{\bar\alpha_t}\,\varepsilon - \sqrt{1-\bar\alpha_t}\, z_0
110
- \]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
- The DiT predicts \(v\); at sample time we recover
 
 
113
 
114
  \[
115
- \hat z_0 = \sqrt{\bar\alpha_t}\, z_t - \sqrt{1-\bar\alpha_t}\, v,\quad
116
- \hat\varepsilon = \sqrt{1-\bar\alpha_t}\, z_t + \sqrt{\bar\alpha_t}\, v
117
  \]
118
 
119
- and step with **DDIM** (η = 0 by default). Classifier-free guidance is applied
120
- in v-space:
121
 
122
  \[
123
- v = v_{\text{uncond}} + s\,(v_{\text{cond}} - v_{\text{uncond}})
124
  \]
125
 
126
- with \(s = 4.0\) unless you override `guidance_scale`. After DDIM, latents are
127
- divided by `latent_scale` **0.95035** (unit-variance scaling from the
128
- precompute cache) before VAE decode.
129
-
130
- That whole chain — including CFG against a learned null text token — is what
131
  `model.generate(...)` runs.
132
 
133
  ---
@@ -137,20 +346,13 @@ That whole chain — including CFG against a learned null text token — is what
137
  | | |
138
  | --- | --- |
139
  | Source | [OpenSound/AudioCaps](https://huggingface.co/datasets/OpenSound/AudioCaps) |
140
- | Split used | `train` |
141
- | Clips after precompute | **45,178** |
142
- | Clip length | 10.24 s @ 16 kHz (locked to AudioLDM mel / VAE / vocoder) |
143
- | Precomputed fields | VAE latents, FLAN-T5 embeddings + mask, AST REPA targets |
144
- | `latent_scale` | 0.9503493000009796 (stored in this `config.json`) |
145
 
146
- AudioCaps is captioned environmental / everyday sound — dogs, rain, engines,
147
- ambience not a speech or music corpus. Domain limits show up in samples:
148
- speech and music prompts are out of distribution.
149
-
150
- **Next data (planned):** larger / more diverse captioned audio (and longer
151
- training) to push quality past “good lab demo” toward something closer to
152
- public SOTA systems. Links and recipes will land on the website write-up when
153
- that run ships.
154
 
155
  ---
156
 
@@ -159,78 +361,37 @@ that run ships.
159
  | | |
160
  | --- | --- |
161
  | Optimizer | AdamW, lr 1e-4, weight decay 0 |
162
- | Steps | **23,999** (EMA weights exported) |
163
  | Global batch | 256 (2 GPUs × microbatch 16 × grad accum 8) |
164
  | EMA decay | 0.9999 |
165
  | REPA | weight 0.5, decayed over 15k steps |
166
  | AMP | yes |
167
- | Seed | 0 |
168
-
169
- | Metric | Value |
170
- | --- | --- |
171
- | GPU hours | *PLACEHOLDER_GPU_HOURS* |
172
- | Hardware | *PLACEHOLDER_HARDWARE* (e.g. 2× T4 / 2× A10 / …) |
173
- | Approx. cost | *PLACEHOLDER_COST* |
174
- | W&B / logs | *PLACEHOLDER_WANDB_RUN* |
175
-
176
- Fill the placeholders above (and the loss figures below) before or right after
177
- publishing so the Hub page matches the website lab note.
178
 
179
  ---
180
 
181
  ## Training curves
182
 
183
- <!-- Drop PNGs under assets/ and keep these filenames, or edit the paths. -->
 
 
184
 
185
  ### Diffusion / total loss
186
 
187
  ![Training loss](assets/loss_curve.png)
188
 
189
- *Placeholder `assets/loss_curve.png`*
190
 
191
- ### REPA loss (train-time alignment)
192
 
193
  ![REPA loss](assets/repa_loss_curve.png)
194
 
195
- *Placeholder `assets/repa_loss_curve.png`*
196
 
197
- ### Learning rate / EMA / extras (optional)
198
 
199
  ![LR schedule](assets/lr_schedule.png)
200
 
201
- *Placeholder `assets/lr_schedule.png`*
202
-
203
- ---
204
-
205
- ## Sample outputs
206
-
207
- <!-- Optional: host short WAVs on the Hub or link to the website gallery. -->
208
-
209
- | Prompt | Audio |
210
- | --- | --- |
211
- | *PLACEHOLDER_PROMPT_1* | *[listen](PLACEHOLDER_SAMPLE_1_URL)* |
212
- | *PLACEHOLDER_PROMPT_2* | *[listen](PLACEHOLDER_SAMPLE_2_URL)* |
213
- | *PLACEHOLDER_PROMPT_3* | *[listen](PLACEHOLDER_SAMPLE_3_URL)* |
214
-
215
- Full gallery and failure cases: [PLACEHOLDER_WEBSITE_POST](PLACEHOLDER_WEBSITE_POST).
216
-
217
- ---
218
-
219
- ## Results in plain language
220
-
221
- - The run **did** learn a working text→latent→mel→wave path. With the default
222
- 50 DDIM steps and CFG 4.0 you get recognizable ambient / SFX-style audio for
223
- many AudioCaps-like prompts.
224
- - Representation learning looks healthy for the compute spent (REPA +
225
- v-prediction DiT on ~45k clips, ~24k steps).
226
- - It is **not** peak quality: complex scenes, speech, music, and fine timing
227
- still fall short of large industrial models.
228
- - The honest upgrade path is boring and correct: **train longer, add more
229
- (and cleaner) data**, retune CFG / steps, keep measuring. Architecture
230
- churn is not the bottleneck for this checkpoint.
231
-
232
- Write-ups of collapses, flat loss regions, and compute bugs belong on the
233
- website — those notes are part of the point of QuarkML.
234
 
235
  ---
236
 
@@ -245,10 +406,7 @@ import soundfile as sf
245
  import torch
246
  from transformers import AutoModel
247
 
248
- model = AutoModel.from_pretrained(
249
- "PLACEHOLDER_HF_MODEL", # e.g. QuarkML/QaDiT
250
- trust_remote_code=True,
251
- )
252
  model = model.to("cuda" if torch.cuda.is_available() else "cpu").eval()
253
 
254
  out = model.generate(
@@ -260,7 +418,7 @@ out = model.generate(
260
  sf.write("dog_birds.wav", out.audios[0], out.sampling_rate)
261
  ```
262
 
263
- First `generate` download pulls the frozen helpers this run was trained with:
264
  `google/flan-t5-large` and the VAE + vocoder from `cvssp/audioldm-s-full-v2`.
265
 
266
  ### Output types
@@ -269,7 +427,7 @@ First `generate` download pulls the frozen helpers this run was trained with:
269
  | --- | --- | --- |
270
  | `"np"` (default) | `audios` | list of float32 numpy waveforms in `[-1, 1]` |
271
  | `"pt"` | `audio_values` | `[B, num_samples]` tensor |
272
- | `"latent"` | `latents` | `[B, 8, 256, 16]` scaled latents (no VAE/vocoder) |
273
 
274
  ### Precomputed T5 states
275
 
@@ -286,13 +444,6 @@ out = model.generate(
286
  v = model(latents, timesteps, encoder_hidden_states, encoder_attention_mask).sample
287
  ```
288
 
289
- ### CLI (from the conversion package)
290
-
291
- ```bash
292
- python qadit_hf/generate.py --model ./qadit-export \
293
- --prompt "Rain falls on a metal roof" --out rain.wav
294
- ```
295
-
296
  ---
297
 
298
  ## Precision and devices
@@ -306,11 +457,9 @@ Keep T5 / VAE / vocoder in float32 (FLAN-T5 overflows easily in fp16).
306
  ## Important details
307
 
308
  - `config.latent_scale` (**0.9503493**) must match training precompute.
309
- `generate` divides by it before VAE decode — change it and the vocoder path
310
- detunes.
311
  - Every sample is fixed length: **10.24 s @ 16 kHz**.
312
- - `repa_layer` exists for fine-tuning with the same REPA recipe; inference
313
- ignores it.
314
  - Sampling always uses the **EMA** weights packaged here.
315
 
316
  ---
@@ -328,38 +477,40 @@ generation, or safety-critical audio.
328
  - ~24k steps on ~45k AudioCaps clips — undertrained vs public SOTA systems
329
  - Weak on speech, music, and densely described scenes
330
  - Inherits caption biases and coverage holes of AudioCaps
331
- - Generated audio can be quiet or coarse at low step counts; prefer the
332
- default 50 DDIM steps for demos
333
-
334
- **Broader impacts:** same class of risks as other generative audio models
335
- (misleading media, copyright-adjacent imitation). Publish and use accordingly.
336
 
337
  ---
338
 
339
- ## Citation / links
340
 
341
- If this lab note or checkpoint helped your own from-scratch run, a link back
342
- to QuarkML is appreciated.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
 
344
  ```bibtex
345
- @misc{qadit_quarkml,
346
- title = {QaDiT: A From-Scratch Text-to-Audio Latent Diffusion Transformer},
347
  author = {Sidharth GN},
348
  year = {2026},
349
- howpublished = {\url{PLACEHOLDER_WEBSITE_POST}},
350
- note = {Code: PLACEHOLDER_GITHUB_REPO ; Weights: PLACEHOLDER_HF_MODEL}
351
  }
352
  ```
353
 
354
- | Resource | URL |
355
  | --- | --- |
356
- | Website | PLACEHOLDER_WEBSITE |
357
- | This build’s article | PLACEHOLDER_WEBSITE_POST |
358
- | GitHub (train + sample) | PLACEHOLDER_GITHUB_REPO |
359
- | Hugging Face model | PLACEHOLDER_HF_MODEL |
360
- | Dataset | https://huggingface.co/datasets/OpenSound/AudioCaps |
361
-
362
- ---
363
-
364
- *Built and published in the open as a QuarkML lab notebook entry — code, weights,
365
- numbers, and the messy middle included.*
 
7
  - dit
8
  - audio
9
  - educational
10
+ - research
11
  pipeline_tag: text-to-audio
12
  ---
13
 
14
  # QaDiT — text-to-audio latent Diffusion Transformer
15
 
16
+ > **Research / educational artifact.** This is **not** a state-of-the-art
17
+ > text-to-audio host model. It is a from-scratch DiT trained on a modest budget
18
+ > so the full stack is readable, reproducible, and improvable. Quality already
19
+ > shows that the pipeline works; pushing further is mostly **more data and
20
+ > longer training**, not a different architecture.
 
21
 
22
+ A ~159M-parameter latent Diffusion Transformer that turns a text caption into
23
+ **10.24 s of 16 kHz mono audio**: FLAN-T5 conditioning DiT denoising of
24
+ AudioLDM KL-VAE latents VAE decode HiFi-GAN vocoder.
 
25
 
26
+ Weights are the **EMA** copy from training step **23,999**.
 
 
 
 
 
 
27
 
28
  ---
29
 
30
+ ## Architecture at a glance
 
 
 
 
 
31
 
32
+ Drop a rendered overview PNG at [`assets/architecture.png`](assets/architecture.png)
33
+ if you want a Hub thumbnail; the Mermaid diagrams below are the source of truth
34
+ and render on GitHub / the Hub.
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
  ![Architecture diagram](assets/architecture.png)
37
 
38
+ *Optional image place your export at `assets/architecture.png`.*
 
 
 
39
 
40
  ```text
41
  caption
 
49
  | Piece | Choice |
50
  | --- | --- |
51
  | Backbone | DiT-B — depth 12, width 768, 12 heads, MLP ratio 4.0 (~159M) |
52
+ | Latent grid | `[8, 256, 16]` (channels × time × freq) |
53
  | Patchify | 2×2 → **1024** tokens, fixed 2-D sincos positions |
54
  | Text | FLAN-T5-large cross-attention every block + pooled text in adaLN-Zero |
55
+ | Train target | **v-prediction** |
56
  | Noise schedule | **cosine** ᾱ, T = 1000 |
57
+ | Timestep sampling (train) | logit-normal |
58
+ | CFG | p_uncond = 0.1 train; default guidance **4.0** at sample |
59
+ | Sampler | **DDIM**, default **50** steps, η = 0 |
60
+ | Aux loss | REPA vs frozen AST features (train only) |
61
+ | Decode stack | `cvssp/audioldm-s-full-v2` VAE + HiFi-GAN |
62
 
63
+ > **Color legend for diagrams:** 🟦 blue = frozen pretrained · 🟩 green = trainable
64
+ > (DiT + glue) · 🟨 yellow = data / tensors · 🟥 red = losses
65
 
66
  ---
67
 
68
+ ## 1. Big picture three pipelines
69
 
70
+ ```mermaid
71
+ flowchart LR
72
+ A[/"AudioCaps<br/>~46K clips + captions"/] --> B["① Offline Pre-compute<br/>(run frozen models once,<br/>cache to disk)"]
73
+ B --> C["② Training Loop<br/>(only the DiT trains)"]
74
+ C --> D["③ Inference / Sampling<br/>(caption → waveform)"]
75
 
76
+ style A fill:#fff3c4,stroke:#b8860b,color:#000
77
+ style B fill:#dbeafe,stroke:#1e40af,color:#000
78
+ style C fill:#dcfce7,stroke:#15803d,color:#000
79
+ style D fill:#fde2e2,stroke:#b91c1c,color:#000
80
+ ```
81
 
82
+ ---
 
 
83
 
84
+ ## 2. Offline pre-compute (frozen models, run once)
85
+
86
+ Heavy frozen models run **once**; the training loop never loads T5, the VAE,
87
+ or the REPA encoder.
88
+
89
+ ```mermaid
90
+ flowchart TD
91
+ subgraph INPUT["Per clip"]
92
+ WAV[/"waveform<br/>10.24 s · 16 kHz · mono"/]
93
+ CAP[/"caption (text)"/]
94
+ end
95
+
96
+ subgraph FRONT["Mel front-end (locked to VAE)"]
97
+ MEL["STFT → log-mel<br/>n_fft 1024 · hop 160 · 64 mels<br/>→ mel 1×1024×64"]
98
+ end
99
+
100
+ subgraph FROZEN["Frozen pretrained encoders 🟦"]
101
+ VAE["AudioLDM mel-VAE<br/>encoder (÷4, C=8)"]
102
+ T5["FLAN-T5 encoder"]
103
+ AST["AST<br/>(REPA target encoder)"]
104
+ end
105
+
106
+ subgraph CACHE["Cached to sharded records 🟨"]
107
+ Z0[/"z₀ latent · 8×256×16<br/>(scaled by latent_scale → unit std)"/]
108
+ CTX[/"text states c ∈ ℝ^{64×1024}<br/>+ attention mask"/]
109
+ YSTAR[/"REPA target features y*"/]
110
+ end
111
+
112
+ WAV --> MEL
113
+ MEL --> VAE --> Z0
114
+ CAP --> T5 --> CTX
115
+ MEL --> AST --> YSTAR
116
+
117
+ style WAV fill:#fff3c4,stroke:#b8860b,color:#000
118
+ style CAP fill:#fff3c4,stroke:#b8860b,color:#000
119
+ style MEL fill:#e0e7ff,stroke:#4338ca,color:#000
120
+ style VAE fill:#dbeafe,stroke:#1e40af,color:#000
121
+ style T5 fill:#dbeafe,stroke:#1e40af,color:#000
122
+ style AST fill:#dbeafe,stroke:#1e40af,color:#000
123
+ style Z0 fill:#fff3c4,stroke:#b8860b,color:#000
124
+ style CTX fill:#fff3c4,stroke:#b8860b,color:#000
125
+ style YSTAR fill:#fff3c4,stroke:#b8860b,color:#000
126
+ ```
127
 
128
+ ---
129
+
130
+ ## 3. Training step (what is actually optimized)
131
+
132
+ Only the **DiT** and its small glue layers receive gradients.
133
+
134
+ ```mermaid
135
+ flowchart TD
136
+ subgraph BATCH["Batch from cache 🟨"]
137
+ Z0[/"z₀' scaled latent"/]
138
+ C[/"T5 tokens c + mask"/]
139
+ YS[/"REPA target y*"/]
140
+ end
141
+
142
+ subgraph NOISE["Forward diffusion"]
143
+ TS["sample t ~ logit-normal"]
144
+ EPS["sample ε ~ N(0, I)"]
145
+ ZT["z_t = √ᾱ_t · z₀' + √(1−ᾱ_t) · ε"]
146
+ end
147
+
148
+ CFGDROP{"CFG dropout<br/>p = 0.1?"}
149
+ NULL["learned null ∅ 🟩"]
150
+
151
+ subgraph DIT["DiT — the ONLY trained network 🟩"]
152
+ PATCH["patchify 2×2 + 2-D pos-emb<br/>→ 1024 tokens"]
153
+ BLOCKS["12 × DiT blocks<br/>(self-attn → cross-attn → MLP,<br/>adaLN-Zero from t + pooled text)"]
154
+ HL["hidden state h_ℓ<br/>(block ℓ = 4)"]
155
+ HEAD["unpatchify head"]
156
+ end
157
+
158
+ PROJ["MLP projection g(·) 🟩"]
159
+ PRED[/"prediction v̂"/]
160
+
161
+ LDIFF{{"L_diff = ‖v − v̂‖²"}}
162
+ LREPA{{"L_REPA = −cos(g(h_ℓ), y*)"}}
163
+ LTOT{{"L = L_diff + λ·L_REPA<br/>(λ = 0.5, decayed)"}}
164
+
165
+ OPT["AdamW + EMA(0.9999)<br/>→ DiT weights only"]
166
+
167
+ Z0 --> ZT
168
+ TS --> ZT
169
+ EPS --> ZT
170
+ ZT --> PATCH
171
+ C --> CFGDROP
172
+ CFGDROP -- "90% keep" --> BLOCKS
173
+ CFGDROP -- "10% drop" --> NULL --> BLOCKS
174
+ TS -- "adaLN-Zero" --> BLOCKS
175
+ PATCH --> BLOCKS --> HEAD --> PRED
176
+ BLOCKS -.-> HL --> PROJ
177
+ PROJ --> LREPA
178
+ YS --> LREPA
179
+ PRED --> LDIFF
180
+ LDIFF --> LTOT
181
+ LREPA --> LTOT
182
+ LTOT --> OPT
183
+
184
+ style Z0 fill:#fff3c4,stroke:#b8860b,color:#000
185
+ style C fill:#fff3c4,stroke:#b8860b,color:#000
186
+ style YS fill:#fff3c4,stroke:#b8860b,color:#000
187
+ style TS fill:#e0e7ff,stroke:#4338ca,color:#000
188
+ style EPS fill:#e0e7ff,stroke:#4338ca,color:#000
189
+ style ZT fill:#e0e7ff,stroke:#4338ca,color:#000
190
+ style CFGDROP fill:#fef9c3,stroke:#a16207,color:#000
191
+ style NULL fill:#dcfce7,stroke:#15803d,color:#000
192
+ style PATCH fill:#dcfce7,stroke:#15803d,color:#000
193
+ style BLOCKS fill:#dcfce7,stroke:#15803d,color:#000
194
+ style HL fill:#dcfce7,stroke:#15803d,color:#000
195
+ style HEAD fill:#dcfce7,stroke:#15803d,color:#000
196
+ style PROJ fill:#dcfce7,stroke:#15803d,color:#000
197
+ style PRED fill:#fff3c4,stroke:#b8860b,color:#000
198
+ style LDIFF fill:#fde2e2,stroke:#b91c1c,color:#000
199
+ style LREPA fill:#fde2e2,stroke:#b91c1c,color:#000
200
+ style LTOT fill:#fde2e2,stroke:#b91c1c,color:#000
201
+ style OPT fill:#dcfce7,stroke:#15803d,color:#000
202
+ ```
203
+
204
+ ---
205
+
206
+ ## 4. Inside one DiT block
207
+
208
+ ```mermaid
209
+ flowchart TD
210
+ TOKENS[/"latent tokens (queries)"/] --> LN1["LayerNorm ⊕ adaLN-Zero<br/>(scale, shift, gate from t-emb)"]
211
+ LN1 --> SA["Self-Attention<br/>(latent ↔ latent)"]
212
+ SA --> ADD1(("+"))
213
+ TOKENS --> ADD1
214
+
215
+ ADD1 --> LN2["LayerNorm"]
216
+ LN2 --> CA["Cross-Attention<br/>Q = latent tokens<br/>K,V = T5 text tokens c<br/>(+ padding mask)"]
217
+ TXT[/"T5 tokens c 🟨"/] --> CA
218
+ CA --> ADD2(("+"))
219
+ ADD1 --> ADD2
220
+
221
+ ADD2 --> LN3["LayerNorm ⊕ adaLN-Zero"]
222
+ LN3 --> MLP["Feed-Forward MLP"]
223
+ MLP --> ADD3(("+"))
224
+ ADD2 --> ADD3
225
+ ADD3 --> OUT[/"tokens → next block"/]
226
+
227
+ TEMB[/"t-embedding<br/>(sinusoidal → MLP,<br/>+ pooled text vector)"/] -. "scale · shift · gate" .-> LN1
228
+ TEMB -. "scale · shift · gate" .-> LN3
229
+
230
+ style TOKENS fill:#fff3c4,stroke:#b8860b,color:#000
231
+ style TXT fill:#fff3c4,stroke:#b8860b,color:#000
232
+ style TEMB fill:#fff3c4,stroke:#b8860b,color:#000
233
+ style OUT fill:#fff3c4,stroke:#b8860b,color:#000
234
+ style LN1 fill:#dcfce7,stroke:#15803d,color:#000
235
+ style SA fill:#dcfce7,stroke:#15803d,color:#000
236
+ style LN2 fill:#dcfce7,stroke:#15803d,color:#000
237
+ style CA fill:#dcfce7,stroke:#15803d,color:#000
238
+ style LN3 fill:#dcfce7,stroke:#15803d,color:#000
239
+ style MLP fill:#dcfce7,stroke:#15803d,color:#000
240
+ ```
241
+
242
+ ---
243
+
244
+ ## 5. Inference / sampling (caption → waveform)
245
+
246
+ ```mermaid
247
+ flowchart TD
248
+ CAP[/"caption"/] --> T5["FLAN-T5 encoder 🟦"]
249
+ T5 --> C[/"text tokens c"/]
250
+ NULLC[/"null embedding ∅"/]
251
+
252
+ ZT[/"z_T ~ N(0, I)<br/>8×256×16"/] --> LOOP
253
+
254
+ subgraph LOOP["Reverse sampler · 50 DDIM steps (default)"]
255
+ DIT["EMA DiT 🟩<br/>two passes: pred(c), pred(∅)"]
256
+ CFG["CFG combine:<br/>v = v(∅) + w · (v(c) − v(∅))<br/>w = 4.0"]
257
+ STEP["DDIM update z_t → z_{t−1}"]
258
+ DIT --> CFG --> STEP
259
+ STEP -- "next t" --> DIT
260
+ end
261
+
262
+ C --> DIT
263
+ NULLC --> DIT
264
+
265
+ LOOP --> ZH[/"ẑ₀' → un-scale (÷ latent_scale)"/]
266
+ ZH --> DEC["VAE decoder 🟦"]
267
+ DEC --> MELO[/"mel-spectrogram"/]
268
+ MELO --> VOC["HiFi-GAN vocoder 🟦"]
269
+ VOC --> OUT[/"waveform 🔊<br/>10.24 s · 16 kHz"/]
270
+
271
+ style CAP fill:#fff3c4,stroke:#b8860b,color:#000
272
+ style C fill:#fff3c4,stroke:#b8860b,color:#000
273
+ style NULLC fill:#fff3c4,stroke:#b8860b,color:#000
274
+ style ZT fill:#fff3c4,stroke:#b8860b,color:#000
275
+ style T5 fill:#dbeafe,stroke:#1e40af,color:#000
276
+ style DIT fill:#dcfce7,stroke:#15803d,color:#000
277
+ style CFG fill:#e0e7ff,stroke:#4338ca,color:#000
278
+ style STEP fill:#e0e7ff,stroke:#4338ca,color:#000
279
+ style ZH fill:#fff3c4,stroke:#b8860b,color:#000
280
+ style DEC fill:#dbeafe,stroke:#1e40af,color:#000
281
+ style MELO fill:#fff3c4,stroke:#b8860b,color:#000
282
+ style VOC fill:#dbeafe,stroke:#1e40af,color:#000
283
+ style OUT fill:#fff3c4,stroke:#b8860b,color:#000
284
+ ```
285
+
286
+ ---
287
+
288
+ ## 6. Component ownership
289
+
290
+ ```mermaid
291
+ flowchart LR
292
+ subgraph FROZEN["🟦 Frozen (reused pretrained)"]
293
+ direction TB
294
+ F1["AudioLDM mel-VAE<br/>(encode + decode)"]
295
+ F2["FLAN-T5 text encoder"]
296
+ F3["AST<br/>(REPA target)"]
297
+ F4["HiFi-GAN vocoder"]
298
+ end
299
+
300
+ subgraph TRAINED["🟩 Trained on AudioCaps"]
301
+ direction TB
302
+ T1["DiT-B/2 (~159M)"]
303
+ T2["T5 → d_model projection"]
304
+ T3["REPA projection head g(·)<br/>(dropped at inference)"]
305
+ T4["learned null embedding ∅"]
306
+ end
307
+
308
+ FROZEN -- "latent space, text<br/>features, alignment<br/>targets, waveform decode" --> TRAINED
309
+
310
+ style F1 fill:#dbeafe,stroke:#1e40af,color:#000
311
+ style F2 fill:#dbeafe,stroke:#1e40af,color:#000
312
+ style F3 fill:#dbeafe,stroke:#1e40af,color:#000
313
+ style F4 fill:#dbeafe,stroke:#1e40af,color:#000
314
+ style T1 fill:#dcfce7,stroke:#15803d,color:#000
315
+ style T2 fill:#dcfce7,stroke:#15803d,color:#000
316
+ style T3 fill:#dcfce7,stroke:#15803d,color:#000
317
+ style T4 fill:#dcfce7,stroke:#15803d,color:#000
318
+ ```
319
+
320
+ ---
321
 
322
+ ## Training objective (DDIM + v-prediction)
323
+
324
+ **Forward process**
325
 
326
  \[
327
+ z_t = \sqrt{\bar\alpha_t}\, z_0 + \sqrt{1-\bar\alpha_t}\,\varepsilon
 
328
  \]
329
 
330
+ **Network target**
 
331
 
332
  \[
333
+ v = \sqrt{\bar\alpha_t}\,\varepsilon - \sqrt{1-\bar\alpha_t}\, z_0
334
  \]
335
 
336
+ At sample time the DiT predicts \(v\); we recover \(\hat z_0\) and
337
+ \(\hat\varepsilon\), then step with **DDIM** (η = 0). CFG is applied in
338
+ v-space with default scale \(s = 4.0\). After DDIM, latents are divided by
339
+ `latent_scale` ��� **0.95035** before VAE decode — that whole chain is what
 
340
  `model.generate(...)` runs.
341
 
342
  ---
 
346
  | | |
347
  | --- | --- |
348
  | Source | [OpenSound/AudioCaps](https://huggingface.co/datasets/OpenSound/AudioCaps) |
349
+ | Split | `train` · **45,178** clips after precompute |
350
+ | Clip length | 10.24 s @ 16 kHz |
351
+ | Cached fields | VAE latents, FLAN-T5 embeddings + mask, AST REPA targets |
352
+ | `latent_scale` | `0.9503493000009796` (baked into `config.json`) |
 
353
 
354
+ AudioCaps is captioned environmental / everyday sound — not speech or music.
355
+ Those domains are out of distribution for this checkpoint.
 
 
 
 
 
 
356
 
357
  ---
358
 
 
361
  | | |
362
  | --- | --- |
363
  | Optimizer | AdamW, lr 1e-4, weight decay 0 |
364
+ | Steps | **23,999** (EMA exported) |
365
  | Global batch | 256 (2 GPUs × microbatch 16 × grad accum 8) |
366
  | EMA decay | 0.9999 |
367
  | REPA | weight 0.5, decayed over 15k steps |
368
  | AMP | yes |
 
 
 
 
 
 
 
 
 
 
 
369
 
370
  ---
371
 
372
  ## Training curves
373
 
374
+ Put W&B / TensorBoard screenshots (or exports) under [`assets/`](assets/) using
375
+ the filenames below. Until then the images show as broken links on the Hub —
376
+ that is intentional so the slots are obvious.
377
 
378
  ### Diffusion / total loss
379
 
380
  ![Training loss](assets/loss_curve.png)
381
 
382
+ *Drop your curve at `assets/loss_curve.png`.*
383
 
384
+ ### REPA loss
385
 
386
  ![REPA loss](assets/repa_loss_curve.png)
387
 
388
+ *Drop your curve at `assets/repa_loss_curve.png`.*
389
 
390
+ ### Learning rate (optional)
391
 
392
  ![LR schedule](assets/lr_schedule.png)
393
 
394
+ *Optional: `assets/lr_schedule.png`.*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
 
396
  ---
397
 
 
406
  import torch
407
  from transformers import AutoModel
408
 
409
+ model = AutoModel.from_pretrained("QuarkML/QaDiT", trust_remote_code=True)
 
 
 
410
  model = model.to("cuda" if torch.cuda.is_available() else "cpu").eval()
411
 
412
  out = model.generate(
 
418
  sf.write("dog_birds.wav", out.audios[0], out.sampling_rate)
419
  ```
420
 
421
+ First `generate` downloads the frozen helpers this run was trained with:
422
  `google/flan-t5-large` and the VAE + vocoder from `cvssp/audioldm-s-full-v2`.
423
 
424
  ### Output types
 
427
  | --- | --- | --- |
428
  | `"np"` (default) | `audios` | list of float32 numpy waveforms in `[-1, 1]` |
429
  | `"pt"` | `audio_values` | `[B, num_samples]` tensor |
430
+ | `"latent"` | `latents` | `[B, 8, 256, 16]` scaled latents (skips VAE/vocoder) |
431
 
432
  ### Precomputed T5 states
433
 
 
444
  v = model(latents, timesteps, encoder_hidden_states, encoder_attention_mask).sample
445
  ```
446
 
 
 
 
 
 
 
 
447
  ---
448
 
449
  ## Precision and devices
 
457
  ## Important details
458
 
459
  - `config.latent_scale` (**0.9503493**) must match training precompute.
460
+ `generate` divides by it before VAE decode.
 
461
  - Every sample is fixed length: **10.24 s @ 16 kHz**.
462
+ - `repa_layer` exists for REPA fine-tuning; inference ignores it.
 
463
  - Sampling always uses the **EMA** weights packaged here.
464
 
465
  ---
 
477
  - ~24k steps on ~45k AudioCaps clips — undertrained vs public SOTA systems
478
  - Weak on speech, music, and densely described scenes
479
  - Inherits caption biases and coverage holes of AudioCaps
480
+ - Prefer the default **50** DDIM steps for demos; low step counts sound coarse
 
 
 
 
481
 
482
  ---
483
 
484
+ ## Research artifact — how to improve this
485
 
486
+ This release is a **research artifact**, not a production host model. The
487
+ architecture and sampling path are solid enough to build on; the ceiling is
488
+ mostly data and compute:
489
+
490
+ 1. **Train longer** — continue past 24k steps with the same recipe (or lower LR).
491
+ 2. **Scale the dataset** — mix in larger captioned audio corpora beyond AudioCaps.
492
+ 3. **Retune sampling** — CFG scale, DDIM step count, and prompt formatting.
493
+ 4. **Keep measuring** — log diffusion loss, REPA loss, and listening tests.
494
+
495
+ Those levers will move quality more than inventing a new backbone for this size
496
+ of model. Contributions and longer runs are welcome; treat this Hub page as a
497
+ reproducible baseline, not a finished product.
498
+
499
+ ---
500
+
501
+ ## Citation
502
 
503
  ```bibtex
504
+ @misc{qadit2026,
505
+ title = {QaDiT: A Text-to-Audio Latent Diffusion Transformer},
506
  author = {Sidharth GN},
507
  year = {2026},
508
+ note = {Research artifact. Weights and transformers remote-code loading.}
 
509
  }
510
  ```
511
 
512
+ | Resource | |
513
  | --- | --- |
514
+ | Dataset | [OpenSound/AudioCaps](https://huggingface.co/datasets/OpenSound/AudioCaps) |
515
+ | VAE / vocoder | [cvssp/audioldm-s-full-v2](https://huggingface.co/cvssp/audioldm-s-full-v2) |
516
+ | Text encoder | [google/flan-t5-large](https://huggingface.co/google/flan-t5-large) |