Instructions to use stabilityai/stable-audio-3-optimized with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Stable Audio 3
How to use stabilityai/stable-audio-3-optimized 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
Rebuild medium DiT fp16-mixed engines (sm_90 + new sm_120): attention now fuses, 4.3x faster
Rebuilds the medium DiT's FP16-mixed TRT engines for sm_90 and sm_120 from the corrected ONNX merged in #3, and adds sm_120 as a published architecture.
Companion to #3 (graph fix) and to the code PR on Stability-AI/stable-audio-3 (producer pass, runtime default, docs).
What changed
| file | arch | built on | size | fused MHA |
|---|---|---|---|---|
tensorRT/sm_90/sa3-m/dit_fp16mixed.trt |
sm_90 | NVIDIA H200 (132 SM, 141 GB HBM3e, 700 W) | 2.92 GB | 96 |
tensorRT/sm_120/sa3-m/dit_fp16mixed.trt |
sm_120 | NVIDIA RTX PRO 4500 Blackwell Server Edition (82 SM, 32 GB GDDR7, 165 W) | 2.92 GB | 96 |
TRT engines are portable across devices of the same compute capability, so the sm_120 engine runs on any sm_120 part (RTX 5090, RTX PRO 6000 Blackwell, RTX PRO 4500/4000, β¦). The latency figures below are specific to the card each engine was built and measured on β see the note under the timings.
Both built with the public consumer recipe β build_from_onnx.py sa3-m, i.e. parse + STRONGLY_TYPED, no builder flags, profile L β [1, 4096] opt 1292, TF32 cleared. No pinning, no plugins, nothing a consumer cannot reproduce. TRT 10.15.1.29.
sm_90 replaces the published engine in place (same path, same filename). sm_120 is new β Blackwell workstation users previously had to compile locally.
Why
The published engine kept the entire O(LΒ²) attention core in FP32 and therefore could not use TRT's FMHA fuser: 0 fused MHA nodes. Bounding the RoPE island (#3) lets QK^T β Softmax β PΒ·V run FP16, so the fuser fires on all 96 attentions.
Measured
Per DiT forward, CUDA-event median of 7 after 3 warmup, TF32 off, batch 1, dedicated idle GPU.
H200 (sm_90 Β· 132 SM Β· 141 GB HBM3e Β· 700 W Β· TRT 10.15.1.29):
| L | published | this PR | speedup |
|---|---|---|---|
| 256 | 11.1 ms | 7.4 ms | 1.49Γ |
| 1292 | 27.9 ms | 12.2 ms | 2.28Γ |
| 4096 | 180.9 ms | 41.4 ms | 4.4Γ |
RTX PRO 4500 Blackwell Server Edition (sm_120 Β· 82 SM Β· 32 GB GDDR7 Β· 165 W Β· TRT 10.15.1.29):
| L | published | this PR | speedup |
|---|---|---|---|
| 256 | 23.4 ms | 17.6 ms | 1.33Γ |
| 1292 | 99.2 ms | 44.4 ms | 2.24Γ |
| 4096 | 714.0 ms | 166.1 ms | 4.3Γ |
Do not read the sm_120 absolute numbers as representative of sm_120 generally. The RTX PRO 4500 is a mid-range 165 W workstation part; other sm_120 cards (RTX 5090, RTX PRO 6000 Blackwell) carry roughly twice the SM count and considerably more memory bandwidth, so they will be substantially faster in absolute terms. The speedup ratio is the portable number here β both engines were measured on the same card, and the ratio held within 0.1Γ across two very different architectures, which is what you would expect from a change that is about kernel fusion rather than silicon.
For the same reason, the H200 and RTX PRO 4500 columns are not an architecture comparison: they are different product tiers (700 W datacenter vs 165 W workstation), and the ~4Γ absolute gap between them is silicon, not tuning.
Accuracy of each shipped engine against the dit_fp32.trt reference built and run on that same card (seed 6000, 8-step pingpong, TF32 off) β free-run latent std ratio and teacher-forced velocity cosine, mean over the 8 steps with the worst step in brackets:
| L | RTX PRO 4500 (sm_120) | H200 (sm_90) |
|---|---|---|
| 256 | 1.00Γ Β· 1.0000 (1.0000) | 1.00Γ Β· 1.0000 (1.0000) |
| 1292 | 1.00Γ Β· 1.0000 (1.0000) | 1.00Γ Β· 1.0000 (0.9999) |
| 4092 | 1.00Γ Β· 1.0000 (0.9999) | 0.99Γ Β· 0.9997 (0.9988) |
Both are effectively fp32-exact. The H200 engine is a hair further from its reference at the 6-minute anchor (0.9997 vs 1.0000) β each card's TRT picks its own kernels and accumulation order, so per-arch references are the right comparison and small per-arch differences are expected.
380 s render through SAME-L (RTX PRO 4500, SAME-L windowed decoder, seed 6000): 0.001% samples clipped, crest 6.51, against the FP32 engine's 0.000% / 6.25.
So it is both ~4.3Γ faster and marginally more accurate than the engine it replaces (the old one scored 0.9998) β closer to eager semantics, since PyTorch also runs the attention core at the autocast dtype inside fused SDPA.
Compatibility
- Filename, precision name (
fp16mixed), profile, and I/O contract are all unchanged.sa3_trt.pypicks these up with no config change. - Output changes at a fixed seed. This is a bug fix, not a re-tune: renders differ from the previous engine. Deterministic and reproducible going forward, but not bit-identical to the old engine.
- Engines are TRT-version and compute-capability specific: these require TRT 10.15.x on sm_90 / sm_120 respectively. They are portable to any other device of the same compute capability (the sm_120 engine runs on RTX 5090 / RTX PRO 6000 Blackwell / etc.), but not across capabilities. Other architectures β including datacenter Blackwell (sm_100) β compile from the corrected ONNX with
build_from_onnx.py sa3-m. - Only the medium DiT is affected.
sa3-sm-music/sa3-sm-sfxuse standard (non-differential) attention and already fused 40/40 MHA in their published engines β verified against the published ONNX: their QK^T operands are already FP16, where medium's were FP32 (which is why medium's pre-softmaxCast(FP32)was a no-op and its whole attention core sat unfused). - β One forward-looking caveat for the small DiTs: although their attention already fuses, their
Softmaxis still inside an FP32 island, so the newbound_attention_core()pass matches and converts 40/40 on them too. Re-running the producer forsa3-sm-music/sa3-sm-sfxwould therefore change their graphs (softmax FP32 β FP16). That variant is neither shipped nor validated β the engines in this PR are medium-only, and the published small-DiT ONNX/engines are untouched. Anyone regenerating the small DiTs should validate before shipping.
Not in this PR
sa3-m/dit_bf16.trtis unchanged and still drifts at long sequence. It evaluates RoPE's rotation angle in bf16, where the angle reaches ~4155 rad at L=4092 and bf16's spacing is 32 rad (> 2Ο) β position information for the fast-rotating dimensions is destroyed, the latent inflates ~2.5Γ over 8 steps, and the decoder clips 2β3% of samples on a 6-min render. It is clean at short lengths. The companion code PR documents this and moves the medium default tofp16mixed; a corrected bf16 engine is in progress separately.- FAD/CLAP perceptual validation at n=128 has not been run yet. Everything above is latent-space fidelity (teacher-forced velocity cosine, latent std ratio vs the per-card fp32 reference), amplitude metrics on full-length renders, and spot listening across 3 prompts x 3 lengths. That is a narrower bar than the
dit_bf16release cleared (FAD/floor + CLAP over the prompt bank at n=128). Do not merge on quality grounds until it lands β I will post it here. - Pipeline-mode coverage is likewise partial: text-to-audio and varlen are exercised, but CFG, audio-to-audio, and inpaint have not been re-tested against these engines.
Validation complete β both blockers from "Not in this PR" are now closed
Full reports: FADCLAP_VALIDATION.md and MODE_COVERAGE.md.
1. FAD + CLAP, n=128 β clears the bar
FAD against each card's own dit_fp32.trt, expressed as a ratio to the fp32 re-seed floor (FAD between two fp32 runs at different seeds β anything below the floor is perceptually meaningless):
| anchor | H200 (sm_90) | RTX PRO 4500 (sm_120) |
|---|---|---|
| 2 min, n=128 | 0.008Γ floor | 0.113Γ floor |
| 6.3 min, n=64 | 0.058Γ floor | 0.126Γ floor |
The dit_bf16 release cleared this same bar at 0.59Γ floor; this beats it by 5β74Γ. In 200 paired bootstrap resamples the new engine is inside the floor 100% of the time at the 2-minute anchor. CLAP shows no significant degradation at any arch or length (paired Ξ vs fp32 = +0.00000 Β± 0.00049 on H200 at 2 min; the only significant shifts are higher CLAP). Clipping and crest match fp32 (0.0180% vs 0.0182%, crest 6.95 vs 6.95).
Prompts are the 128 held-out entries (indices 512β639) of the same prompt bank the bf16 release was measured on, split by track id.
One honest qualification. "New is at-or-better than old" does not hold as a point estimate in every cell. The old engine keeps the whole O(LΒ²) attention core in FP32, so it hugs the fp32 reference by construction; the new one runs that core in FP16. At 6.3 min on H200 the new engine is further from fp32 than the old by a margin that is statistically real (paired bootstrap P(new better) = 0.025) and perceptually irrelevant β +0.0115 FAD = 2.8% of the noise floor β mirroring the teacher-forced cosines already in this PR (0.9997 new vs 0.9998 old @L4092). At 6.3 min on sm_120 the ordering reverses (P = 0.84). So the defensible claim is "perceptually equivalent to fp32 and to the engine it replaces, at 4.3Γ the speed" β not "better than the old engine".
For scale: the two fp32 engines built for the two different cards are 100Γ further apart in FAD (0.4010) than the new engine is from its own card's fp32 (0.0039).
2. Pipeline modes β drop-in on both architectures
314 CLI invocations through the shipped sa3_trt.py: text-to-audio, CFG / negative-prompt / APG, audio-to-audio, inpaint, varlen across the whole advertised profile (L = 1 β¦ 4096), both decoders, all three precisions, and both small DiTs. All run and produce finite, non-silent, correct-length audio with sane amplitude statistics; cross-arch stats agree to ~0.1 dB. The I/O contract is identical β same 6 inputs, names, dtypes, output, and single optimization profile.
Nothing in the mode matrix is broken by this change.
β But the matrix surfaced five pre-existing runtime defects β none caused by this PR
Every one reproduces identically on the old published engine, and every one lives in the Python call helpers or CLI wrapper that this PR does not touch. Three are silent wrong-output bugs. These should gate the next code release, not this engine PR, but they need to be on the record:
| # | defect | severity |
|---|---|---|
| P1 | DiTRunner.step() returns its persistent output buffer β CFG is a complete no-op; --cfg/--apg have zero effect and the render follows the negative prompt |
high, silent |
| P2 | decoder_decode() / encoder_encode() missing a cross-stream sync β SAME-L renders silently wrong; a2a/inpaint intermittently garbage |
high, silent |
| P3 | SAME-L decoder engine not CUDA-stream-capturable on sm_120 β mega-graph silently drops the decode | high, silent (sm_120) |
| P4 | sa3_trt.py double-loads every engine on the eager path β ~2Γ peak VRAM, duplicated teardown aborts the process |
medium |
| P5 | L < 32 not validated against the decoder profile β exit 0 + digital silence |
low, silent |
Two hit the default configuration: P2/P3 mean --dit medium with its own default decoder (same-l) can return wrong audio with exit code 0, which is why the correctness matrix above was routed through --decoder same-s. P1 means every CFG measurement ever taken through this runtime was measuring the unconditional branch.
"CFG passes" above therefore means the dual-pass executes cleanly on both passes at every length with sane audio out β which is what the engine swap could plausibly have broken, and did not. It does not mean guidance is applied.
Also worth flagging: a measurement-infrastructure bug
The sad310 venv's numpy 1.23.5 (openblas64) computes threaded gemm incorrectly above ~64Β³ and returns non-orthogonal eigh eigenvectors, which was producing negative FrΓ©chet distances (self-check FAD(X,X) = β17.57). VGGish's log-mel front-end is a numpy matmul, so embeddings were contaminated too. The numbers above were computed after pinning OPENBLAS_NUM_THREADS=1 with a hard self-test, moving all covariance/eigen work to numpy 2.2.6, and validating against closed-form values plus an independent torch-float64 implementation (agreement 0.00e+00 across all 16 cells). Historical FAD numbers computed in that venv are suspect β including, potentially, the 0.59Γ-floor bf16 reference quoted above.
Not covered
Human listening at n=128 (spot listening only, across 3 prompts Γ 3 lengths); CLAP text truncation to 77 tokens (identical across sets, so comparisons hold).
Validated: FAD 0.008x/0.113x of the fp32 re-seed floor at n=128, all pipeline modes drop-in, ear-checked. sm_120 completed to full 15-file parity with sm_90 so install.sh cannot 404 on it.