| import os |
|
|
| import gradio as gr |
| import numpy as np |
| import soundfile as sf |
| import spaces |
| import torch |
| from huggingface_hub import login |
| from stable_audio_3 import StableAudioModel |
|
|
|
|
| hf_token = os.environ.get("HF_TOKEN") |
|
|
| if not hf_token: |
| raise RuntimeError("HF_TOKEN Space secret is missing.") |
|
|
| login(token=hf_token) |
|
|
| print("PyTorch:", torch.__version__) |
| print("PyTorch CUDA:", torch.version.cuda) |
| print("Compiled architectures:", torch.cuda.get_arch_list()) |
|
|
| model = StableAudioModel.from_pretrained( |
| "small-sfx", |
| device="cuda", |
| ) |
|
|
| def requested_gpu_duration(prompt: str, duration: float) -> int: |
| """ |
| Reserve a modest amount of GPU time. |
| |
| Stable Audio 3 Small models are extremely fast on modern GPUs, |
| but leave room for initial setup and audio decoding. |
| """ |
| del prompt |
|
|
| duration = float(duration) |
|
|
| if duration <= 15: |
| return 15 |
| if duration <= 60: |
| return 20 |
|
|
| return 30 |
|
|
|
|
| @spaces.GPU(duration=requested_gpu_duration) |
| @torch.inference_mode() |
| def generate_sound(prompt: str, duration: float) -> str: |
| prompt = prompt.strip() |
| duration = float(duration) |
|
|
| if not prompt: |
| raise gr.Error("Enter a description of the sound.") |
|
|
| if not 0.5 <= duration <= 120: |
| raise gr.Error("Duration must be between 0.5 and 120 seconds.") |
|
|
| audio = model.generate( |
| prompt=prompt, |
| duration=duration, |
| ) |
|
|
| if isinstance(audio, torch.Tensor): |
| audio = audio.detach().float().cpu().numpy() |
|
|
| audio = np.asarray(audio) |
|
|
| |
| if audio.ndim == 3: |
| audio = audio[0] |
|
|
| |
| if audio.ndim == 2 and audio.shape[0] <= 8: |
| audio = audio.T |
|
|
| with tempfile.NamedTemporaryFile( |
| suffix=".wav", |
| delete=False, |
| ) as output_file: |
| output_path = Path(output_file.name) |
|
|
| sf.write( |
| output_path, |
| audio, |
| samplerate=44_100, |
| subtype="FLOAT", |
| ) |
|
|
| return str(output_path) |
|
|
|
|
| with gr.Blocks(title="Stable Audio 3 Small SFX") as demo: |
| gr.Markdown( |
| """ |
| # Stable Audio 3 Small SFX |
| |
| Generate stereo, 44.1 kHz sound effects using Stable Audio 3 |
| on Hugging Face ZeroGPU. |
| """ |
| ) |
|
|
| prompt = gr.Textbox( |
| label="Sound description", |
| value="Chugging train coming into a station with a loud horn", |
| lines=3, |
| ) |
|
|
| duration = gr.Slider( |
| minimum=0.5, |
| maximum=120, |
| value=7, |
| step=0.5, |
| label="Duration in seconds", |
| ) |
|
|
| generate_button = gr.Button( |
| "Generate sound", |
| variant="primary", |
| ) |
|
|
| output_audio = gr.Audio( |
| label="Generated sound", |
| type="filepath", |
| ) |
|
|
| generate_button.click( |
| fn=generate_sound, |
| inputs=[prompt, duration], |
| outputs=output_audio, |
| concurrency_limit=1, |
| ) |
|
|
|
|
| demo.queue( |
| max_size=20, |
| default_concurrency_limit=1, |
| ).launch() |