Browser UI for Stable Audio 3 — inpainting, text-to-audio, audio-to-audio, LoRA training with live charts, dataset auto-captioning, and inference speedups. Runs on CUDA (Linux/WSL) and Apple Silicon (MPS + MLX decoder, native MLX LoRA training).

Upstream: Stability-AI/stable-audio-3 · stabilityai/stable-audio-3-medium on HF
? to view all shortcutsPer-region prompts · streaming per-step diffusion previews · multi-track · frequency-bounded selections · stretching
Requires Python 3.11+ and Node.js.
# clone with SA3 as a dependency
git clone https://github.com/lyramakesmusic/sa3-inpainter-ui.git
cd sa3-inpainter-ui
# python deps
uv sync
# for LoRA training (optional)
uv pip install pytorch_lightning==2.5.5 dill wandb
# frontend deps
cd webui && npm install && cd ..
SA3 model weights are gated — accept the license at HuggingFace, then either:
huggingface-cli download stabilityai/stable-audio-3-medium --local-dir ~/sa3-inpainter/models/stable-audio-3-mediumFor LoRA training, you also need the stable-audio-3 source repo cloned locally — set the path in Settings.
# backend on :5174 — ~30s to load the model
uv run python backend/server.py
# frontend on :5173 — Vite proxies /api → :5174
cd webui && npm run dev
Open http://localhost:5173. On first launch you'll be prompted to fill in paths and tokens in the Settings tab.
All paths are configurable from the Settings tab in the top bar:
| Setting | Default | Description |
|---|---|---|
| Models directory | ~/sa3-inpainter/models | SA3 model weights |
| LoRA directory | ~/sa3-inpainter/loras | Trained LoRA files |
| LoRA training directory | ~/sa3-inpainter/lora_training | Per-LoRA working directory (audio, latents, per-LoRA settings JSON) |
| Embeddings directory | ~/sa3-inpainter/embeddings | Textual inversion embeddings |
| SA3 source root | (empty) | Path to stable-audio-3 repo clone (needed for training — optimized/mlx tree) |
| HuggingFace token | (empty) | For gated model downloads |
| OpenRouter API key | (empty) | For auto-captioning via Gemini 3 Pro / Flash |
| Autocaptioner model | pro | pro (higher accuracy, ~$0.012/track) or flash (cheaper, ~$0.010) |
| Autocaptioner parallel | 32 | Number of concurrent caption requests |
| Autocaptioner examples | (3 defaults) | Few-shot caption examples that define output style |
| LoRA adapter | dora-rows | Adapter architecture: lora / dora-rows / dora-cols / bora |
Settings can also be set via environment variables: SA3_MODELS_DIR, SA3_LORA_DIR, SA3_LORA_TRAIN_DIR, SA3_EMBED_DIR. Settings are saved to ~/.config/sa3-inpainter/settings.json; per-LoRA training settings + cached profile results go to <lora_training_dir>/<name>/train_settings.json; captioner cost history goes to ~/.config/sa3-inpainter/captioner_stats.json.
backend/server.py FastAPI app, model lifecycle, inference, training/captioning orchestration, all /api routes
backend/captioner.py Async OpenRouter caption pool + per-call cost tracking
backend/train_lora.py LoRA training subprocess wrapper (CUDA)
backend/train_lora_compiled.py torch.compile monkey-patch for training
backend/pre_encode.py Pre-encode audio to latents for faster training
backend/kv_cache.py Cross-attention KV cache for inference speedup
backend/tome.py Token merging (ToME) for inference speedup
mlx_sa3/ae.py MLX AE decoder (Apple Silicon)
mlx_sa3/nn_blocks.py Transformer + differential attention + band-mask SWA
mlx_sa3/weights.py Safetensors to MLX weight remap
mlx_sa3/lora.py MLX LoRA/DoRA/BoRA adapter injection + weight save/load
mlx_sa3/train_lora_mlx.py MLX LoRA training loop with per-step grad-norm logging
mlx_sa3/pre_encode_mlx.py MLX audio-to-latent pre-encoding
webui/src/lib/session.svelte.js Shared reactive state + API client
webui/src/lib/MainCanvas.svelte Spectrogram + paint + zoom interaction
webui/src/lib/SpecCanvas.svelte Canvas-based STFT spectrogram (Web Worker, reassignment)
webui/src/lib/WaveformOverlay.svelte Per-latent frequency-colored waveform overlay
webui/src/lib/TrainerView.svelte Dataset manager + training config + live metric charts
webui/src/lib/SparkLine.svelte Canvas sparkline w/ axis ticks + synced hover cursor
webui/src/lib/SettingsView.svelte Settings tab (paths, API keys, captioner, adapter)
webui/src/lib/Toast.svelte Selectable error/success toasts
webui/src/lib/RightRail.svelte Right sidebar: prompt, generation, LoRA, advanced controls
webui/src/lib/BottomBar.svelte Transport, system stats
webui/src/App.svelte Layout + audio graph + playback wiring + tab routing
3 commits
Python
46.9%
Svelte
38.2%
JavaScript
10.6%
CSS
2.8%
HTML
1.5%
Browser UI for Stable Audio 3 — inpainting, text-to-audio, audio-to-audio, LoRA training with live charts, dataset auto-captioning, and inference speedups. Runs on CUDA (Linux/WSL) and Apple Silicon (MPS + MLX decoder, native MLX LoRA training).

Upstream: Stability-AI/stable-audio-3 · stabilityai/stable-audio-3-medium on HF
? to view all shortcutsPer-region prompts · streaming per-step diffusion previews · multi-track · frequency-bounded selections · stretching
Requires Python 3.11+ and Node.js.
# clone with SA3 as a dependency
git clone https://github.com/lyramakesmusic/sa3-inpainter-ui.git
cd sa3-inpainter-ui
# python deps
uv sync
# for LoRA training (optional)
uv pip install pytorch_lightning==2.5.5 dill wandb
# frontend deps
cd webui && npm install && cd ..
SA3 model weights are gated — accept the license at HuggingFace, then either:
huggingface-cli download stabilityai/stable-audio-3-medium --local-dir ~/sa3-inpainter/models/stable-audio-3-mediumFor LoRA training, you also need the stable-audio-3 source repo cloned locally — set the path in Settings.
# backend on :5174 — ~30s to load the model
uv run python backend/server.py
# frontend on :5173 — Vite proxies /api → :5174
cd webui && npm run dev
Open http://localhost:5173. On first launch you'll be prompted to fill in paths and tokens in the Settings tab.
All paths are configurable from the Settings tab in the top bar:
| Setting | Default | Description |
|---|---|---|
| Models directory | ~/sa3-inpainter/models | SA3 model weights |
| LoRA directory | ~/sa3-inpainter/loras | Trained LoRA files |
| LoRA training directory | ~/sa3-inpainter/lora_training | Per-LoRA working directory (audio, latents, per-LoRA settings JSON) |
| Embeddings directory | ~/sa3-inpainter/embeddings | Textual inversion embeddings |
| SA3 source root | (empty) | Path to stable-audio-3 repo clone (needed for training — optimized/mlx tree) |
| HuggingFace token | (empty) | For gated model downloads |
| OpenRouter API key | (empty) | For auto-captioning via Gemini 3 Pro / Flash |
| Autocaptioner model | pro | pro (higher accuracy, ~$0.012/track) or flash (cheaper, ~$0.010) |
| Autocaptioner parallel | 32 | Number of concurrent caption requests |
| Autocaptioner examples | (3 defaults) | Few-shot caption examples that define output style |
| LoRA adapter | dora-rows | Adapter architecture: lora / dora-rows / dora-cols / bora |
Settings can also be set via environment variables: SA3_MODELS_DIR, SA3_LORA_DIR, SA3_LORA_TRAIN_DIR, SA3_EMBED_DIR. Settings are saved to ~/.config/sa3-inpainter/settings.json; per-LoRA training settings + cached profile results go to <lora_training_dir>/<name>/train_settings.json; captioner cost history goes to ~/.config/sa3-inpainter/captioner_stats.json.
backend/server.py FastAPI app, model lifecycle, inference, training/captioning orchestration, all /api routes
backend/captioner.py Async OpenRouter caption pool + per-call cost tracking
backend/train_lora.py LoRA training subprocess wrapper (CUDA)
backend/train_lora_compiled.py torch.compile monkey-patch for training
backend/pre_encode.py Pre-encode audio to latents for faster training
backend/kv_cache.py Cross-attention KV cache for inference speedup
backend/tome.py Token merging (ToME) for inference speedup
mlx_sa3/ae.py MLX AE decoder (Apple Silicon)
mlx_sa3/nn_blocks.py Transformer + differential attention + band-mask SWA
mlx_sa3/weights.py Safetensors to MLX weight remap
mlx_sa3/lora.py MLX LoRA/DoRA/BoRA adapter injection + weight save/load
mlx_sa3/train_lora_mlx.py MLX LoRA training loop with per-step grad-norm logging
mlx_sa3/pre_encode_mlx.py MLX audio-to-latent pre-encoding
webui/src/lib/session.svelte.js Shared reactive state + API client
webui/src/lib/MainCanvas.svelte Spectrogram + paint + zoom interaction
webui/src/lib/SpecCanvas.svelte Canvas-based STFT spectrogram (Web Worker, reassignment)
webui/src/lib/WaveformOverlay.svelte Per-latent frequency-colored waveform overlay
webui/src/lib/TrainerView.svelte Dataset manager + training config + live metric charts
webui/src/lib/SparkLine.svelte Canvas sparkline w/ axis ticks + synced hover cursor
webui/src/lib/SettingsView.svelte Settings tab (paths, API keys, captioner, adapter)
webui/src/lib/Toast.svelte Selectable error/success toasts
webui/src/lib/RightRail.svelte Right sidebar: prompt, generation, LoRA, advanced controls
webui/src/lib/BottomBar.svelte Transport, system stats
webui/src/App.svelte Layout + audio graph + playback wiring + tab routing
3 commits
Python
46.9%
Svelte
38.2%
JavaScript
10.6%
CSS
2.8%
HTML
1.5%