File size: 3,839 Bytes
3bd5145
a7a175f
3bd5145
 
a7a175f
 
 
3bd5145
 
 
 
9cd288b
 
 
 
 
 
 
 
 
 
 
 
 
3bd5145
 
 
9cd288b
3bd5145
 
 
 
 
 
 
 
 
 
 
 
 
 
9cd288b
3bd5145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import functools
import os
import time

# Disable Dynamo by default for Space stability; the CLI script does the same.
os.environ.setdefault("TORCHDYNAMO_DISABLE", "1")

import gradio as gr
import numpy as np
import torch

try:
    import spaces
except ImportError:
    class _SpacesFallback:
        @staticmethod
        def GPU(*_args, **_kwargs):
            def _decorator(func):
                return func

            return _decorator

    spaces = _SpacesFallback()

from moss_soundeffect_v2 import MossSoundEffectPipeline

MODEL_PATH = "OpenMOSS-Team/MOSS-SoundEffect-v2.0"
DEFAULT_DEVICE = "cuda"
MAX_INFERENCE_SECONDS = 30


@functools.lru_cache(maxsize=1)
def load_backend(model_dir: str, device_str: str):
    device = torch.device(device_str if torch.cuda.is_available() else "cpu")
    pipe = MossSoundEffectPipeline.from_pretrained(
        model_dir,
        torch_dtype=torch.bfloat16 if device.type == "cuda" else torch.float32,
        device=str(device),
    )
    return pipe, device


@spaces.GPU(duration=180)
def run_inference(prompt, seconds, steps, cfg_scale, sigma_shift, seed):
    if not (prompt or "").strip():
        raise ValueError("Please enter a prompt describing the audio you want to generate.")

    seconds = round(float(seconds), 1)
    if seconds <= 0:
        raise ValueError("Duration must be greater than 0.")
    if seconds > MAX_INFERENCE_SECONDS:
        raise ValueError(f"Duration must be no greater than {MAX_INFERENCE_SECONDS}s.")

    started_at = time.monotonic()
    pipe, _ = load_backend(MODEL_PATH, DEFAULT_DEVICE)

    audio = pipe(
        prompt=prompt,
        seconds=seconds,
        num_inference_steps=int(steps),
        cfg_scale=float(cfg_scale),
        sigma_shift=float(sigma_shift),
        seed=int(seed),
    )

    audio_np = audio[0].detach().float().cpu().numpy()
    if audio_np.ndim > 1 and audio_np.shape[0] == 1:
        audio_np = audio_np.squeeze(0)
    elif audio_np.ndim > 1:
        audio_np = audio_np.T
    audio_np = audio_np.astype(np.float32, copy=False)

    elapsed = time.monotonic() - started_at
    status = (
        f"Done | elapsed: {elapsed:.2f}s | "
        f"duration={seconds:.1f}s, steps={int(steps)}, "
        f"cfg_scale={float(cfg_scale):.2f}, sigma_shift={float(sigma_shift):.2f}, "
        f"seed={int(seed)}"
    )
    return (pipe.sample_rate, audio_np), status


with gr.Blocks(title="MOSS-SoundEffect v2.0") as demo:
    gr.Markdown(
        """
        # MOSS-SoundEffect v2.0
        Text-to-audio diffusion demo.
        """
    )

    with gr.Row():
        with gr.Column(scale=3):
            prompt = gr.Textbox(
                label="Prompt",
                lines=8,
                value="The crisp, rhythmic click-clack of fast typing on a mechanical keyboard.",
            )
            seconds = gr.Slider(1, MAX_INFERENCE_SECONDS, step=0.1, value=10, label="Duration (seconds)")
            with gr.Accordion("Sampling Parameters", open=True):
                steps = gr.Slider(10, 150, step=1, value=50, label="num_inference_steps")
                cfg_scale = gr.Slider(1.0, 8.0, step=0.1, value=4.0, label="cfg_scale")
                sigma_shift = gr.Slider(0.0, 10.0, step=0.1, value=5.0, label="sigma_shift")
                seed = gr.Number(value=0, label="seed", precision=0)
            run_btn = gr.Button("Generate Sound Effect", variant="primary")
        with gr.Column(scale=2):
            output_audio = gr.Audio(label="Output Audio", type="numpy")
            status = gr.Textbox(label="Status", lines=4, interactive=False)

    run_btn.click(
        fn=run_inference,
        inputs=[prompt, seconds, steps, cfg_scale, sigma_shift, seed],
        outputs=[output_audio, status],
    )

demo.queue(max_size=16, default_concurrency_limit=1)

if __name__ == "__main__":
    demo.launch()