File size: 4,469 Bytes
59d0926
0925ec3
 
0b4cf7b
 
 
2262341
0b4cf7b
2e8f212
c1c9edf
 
 
 
 
 
 
 
 
 
 
00a6f4a
2e8f212
802485a
 
 
 
 
 
 
 
 
 
 
 
 
 
c1c9edf
2e8f212
a98020e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429ff99
2e8f212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
db50096
2e8f212
 
 
7f6ae31
a98020e
 
 
2e8f212
a98020e
 
2e8f212
 
 
 
 
 
 
59d0926
7f6ae31
2e8f212
 
 
 
 
 
 
 
 
 
 
 
a98020e
2e8f212
 
 
 
 
 
 
a98020e
2e8f212
 
 
 
 
 
a98020e
2e8f212
a98020e
2e8f212
 
 
 
 
 
 
a98020e
 
 
 
2e8f212
 
59d0926
0925ec3
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import os
import sys

# Ensure both current folder and absolute folder paths are visible to Python
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, "/home/user/app")
os.environ["GRADIO_SSR_MODE"] = "0"
os.environ["PYTHONPATH"] = f".:{os.environ.get('PYTHONPATH', '')}"

# Mock distribution versions to satisfy importlib check on HF
try:
    import importlib.metadata
    orig_version = importlib.metadata.version
    def fake_version(pkg_name):
        if pkg_name == "omnivoice":
            return "0.1.3"
        return orig_version(pkg_name)
    importlib.metadata.version = fake_version
except Exception:
    pass

# Patch HfFolder back into huggingface_hub before gradio/spaces import
import huggingface_hub
if not hasattr(huggingface_hub, 'HfFolder'):
    class HfFolder:
        @staticmethod
        def get_token():
            return huggingface_hub.get_token() if hasattr(huggingface_hub, 'get_token') else None
        @staticmethod
        def save_token(token):
            pass
        @staticmethod
        def delete_token():
            pass
    huggingface_hub.HfFolder = HfFolder

import torch
import spaces  # Import Hugging Face ZeroGPU SDK

# We load the model inside a class wrapper to lazy-load or handle global imports safely
model = None

def get_model():
    global model
    if model is None:
        print("Loading OmniVoice model globally inside ZeroGPU context...")
        from omnivoice.models.omnivoice import OmniVoice
        device = "cuda" if torch.cuda.is_available() else "cpu"
        model = OmniVoice.from_pretrained(
            "k2-fsa/OmniVoice",
            device_map=device,
            dtype=torch.float16 if device == "cuda" else torch.float32,
            load_asr=True
        )
    return model

# Define the generator function decorated with @spaces.GPU
@spaces.GPU
def gpu_generate_fn(
    text,
    language,
    ref_audio,
    instruct,
    num_step,
    guidance_scale,
    denoise,
    speed,
    duration,
    preprocess_prompt,
    postprocess_output,
    mode,
    ref_text=None,
):
    from omnivoice.models.omnivoice import OmniVoiceGenerationConfig
    import time
    import numpy as np
    import scipy.io.wavfile as wavfile

    # Load model instance
    m = get_model()

    # Ensure model is on CUDA inside the ZeroGPU container
    if hasattr(m, "to") and torch.cuda.is_available():
        m.to("cuda")

    gen_config = OmniVoiceGenerationConfig(
        num_step=int(num_step or 32),
        guidance_scale=float(guidance_scale) if guidance_scale is not None else 2.0,
        denoise=bool(denoise) if denoise is not None else True,
        preprocess_prompt=bool(preprocess_prompt),
        postprocess_output=bool(postprocess_output),
    )

    lang = language if (language and language != "Auto") else None
    kw = dict(text=text.strip(), language=lang, generation_config=gen_config)

    if speed is not None and float(speed) != 1.0:
        kw["speed"] = float(speed)
    if duration is not None and float(duration) > 0:
        kw["duration"] = float(duration)

    try:
        if mode == "clone":
            if not ref_audio:
                return None, "Please upload a reference audio.", None
            kw["voice_clone_prompt"] = m.create_voice_clone_prompt(
                ref_audio=ref_audio,
                ref_text=ref_text,
            )

        if instruct and instruct.strip():
            kw["instruct"] = instruct.strip()

        audio = m.generate(**kw)
        waveform = audio[0].squeeze(0).cpu().numpy()
        waveform = (waveform * 32767).astype(np.int16)
        
        timestamp = time.strftime("%Y%m%d-%H%M%S")
        save_path = os.path.join("outputs", f"RJD_{timestamp}.wav")
        os.makedirs("outputs", exist_ok=True)
        wavfile.write(save_path, m.sampling_rate, waveform)
        
        return (m.sampling_rate, waveform), f"Done. Saved to: {save_path}", save_path
    except Exception as e:
        import traceback
        traceback.print_exc()
        return None, f"Error: {type(e).__name__}: {e}", None

def main():
    print("Initializing Gradio Interface...")
    from omnivoice.cli.demo import build_demo
    # Ensure model is initialized for building Gradio components
    m = get_model()
    demo = build_demo(m, checkpoint="k2-fsa/OmniVoice", generate_fn=gpu_generate_fn)
    demo.queue().launch(server_name="0.0.0.0", server_port=7860, show_error=True)

if __name__ == "__main__":
    main()