multimodalart HF Staff commited on
Commit
c3c7ab2
·
verified ·
1 Parent(s): 2a23192

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +134 -47
app.py CHANGED
@@ -4,61 +4,148 @@ os.environ.setdefault("NUMBA_DISABLE_CUDA", "1")
4
 
5
  import spaces
6
  import torch
7
- print(f"After import spaces: cuda_available={torch.cuda.is_available()}")
 
 
 
 
8
 
9
- import subprocess, sys
10
  subprocess.run(
11
  [sys.executable, "-m", "pip", "install", "--no-deps",
12
  "chatterbox-tts==0.1.7", "chatterbox-flash==0.1.0"],
13
  check=True,
14
  )
15
- print(f"After pip install: cuda_available={torch.cuda.is_available()}")
16
 
17
- # Test: just import chatterbox, don't load model
18
  from chatterbox_flash import ChatterboxFlashTTS
19
- print(f"After chatterbox import: cuda_available={torch.cuda.is_available()}")
20
-
21
- # Test: load just the voice encoder (small model)
22
- from chatterbox.models.ve.model import VoiceEncoder
23
- from safetensors.torch import load_file
24
- import tempfile, os as _os
25
- from huggingface_hub import hf_hub_download
26
-
27
- print("Downloading ve.safetensors...")
28
- ve_path = hf_hub_download("ResembleAI/chatterbox-flash", "ve.safetensors")
29
- ve = VoiceEncoder()
30
- ve.load_state_dict(load_file(ve_path))
31
- ve.to("cpu").eval()
32
- print(f"After ve load: cuda_available={torch.cuda.is_available()}")
33
-
34
- # Test: load just the t3 model
35
- from chatterbox_flash.t3 import ChatterboxFlashT3
36
- print("Downloading t3_flash.safetensors...")
37
- t3_path = hf_hub_download("ResembleAI/chatterbox-flash", "t3_flash.safetensors")
38
- t3 = ChatterboxFlashT3(drf_block_size=16)
39
- t3_state = load_file(t3_path)
40
- if "model" in t3_state:
41
- t3_state = t3_state["model"][0]
42
- t3.load_state_dict(t3_state)
43
- t3.to(device="cpu", dtype=torch.bfloat16).eval()
44
- print(f"After t3 load: cuda_available={torch.cuda.is_available()}")
45
-
46
- # Test: load s3gen
47
- from chatterbox.models.s3gen.s3gen import S3Gen
48
- print("Downloading s3gen.safetensors...")
49
- s3gen_path = hf_hub_download("ResembleAI/chatterbox-flash", "s3gen.safetensors")
50
- s3gen = S3Gen(meanflow=True)
51
- s3gen.load_state_dict(load_file(s3gen_path), strict=False)
52
- s3gen.to("cpu").eval()
53
- print(f"After s3gen load: cuda_available={torch.cuda.is_available()}")
54
-
55
- print("All models loaded on CPU. Testing GPU...")
56
 
57
- import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
- @spaces.GPU(duration=60)
60
- def test_gpu(text):
61
- return f"CUDA: {torch.cuda.is_available()}, devices: {torch.cuda.device_count()}"
 
 
 
 
 
 
62
 
63
- demo = gr.Interface(fn=test_gpu, inputs=gr.Textbox(value="test"), outputs=gr.Textbox())
64
- demo.launch(mcp_server=True)
 
4
 
5
  import spaces
6
  import torch
7
+ import numpy as np
8
+ import gradio as gr
9
+
10
+ import subprocess
11
+ import sys
12
 
 
13
  subprocess.run(
14
  [sys.executable, "-m", "pip", "install", "--no-deps",
15
  "chatterbox-tts==0.1.7", "chatterbox-flash==0.1.0"],
16
  check=True,
17
  )
 
18
 
 
19
  from chatterbox_flash import ChatterboxFlashTTS
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ MODEL_ID = "ResembleAI/chatterbox-flash"
22
+ _tts = None
23
+
24
+
25
+ def get_tts():
26
+ global _tts
27
+ if _tts is None:
28
+ print(f"Loading Chatterbox-Flash from {MODEL_ID}...")
29
+ _tts = ChatterboxFlashTTS.from_pretrained(
30
+ MODEL_ID, device="cuda", dtype=torch.bfloat16,
31
+ )
32
+ print("Model loaded successfully.")
33
+ return _tts
34
+
35
+
36
+ @spaces.GPU(duration=120)
37
+ def generate_tts(
38
+ text_input: str,
39
+ audio_prompt_path: str | None = None,
40
+ exaggeration: float = 0.5,
41
+ temperature: float = 0.6,
42
+ cfg_scale: float = 1.0,
43
+ num_steps: int = 10,
44
+ seed_num: int = 0,
45
+ ):
46
+ """Generate speech from text using Chatterbox-Flash block-diffusion TTS."""
47
+ tts = get_tts()
48
+
49
+ if seed_num != 0:
50
+ torch.manual_seed(int(seed_num))
51
+ torch.cuda.manual_seed(int(seed_num))
52
+ np.random.seed(int(seed_num))
53
+
54
+ generate_kwargs = {
55
+ "exaggeration": exaggeration,
56
+ "temperature": temperature,
57
+ "cfg_scale": cfg_scale,
58
+ "num_steps": num_steps,
59
+ "backend": "torch",
60
+ }
61
+
62
+ if audio_prompt_path:
63
+ generate_kwargs["audio_prompt_path"] = audio_prompt_path
64
+
65
+ wav = tts.generate(text_input[:300], **generate_kwargs)
66
+ return (tts.sr, wav.squeeze(0).cpu().numpy())
67
+
68
+
69
+ CSS = """
70
+ #col-container { max-width: 1100px; margin: 0 auto; }
71
+ .dark .gradio-container { color: var(--body-text-color); }
72
+ """
73
+
74
+ with gr.Blocks() as demo:
75
+ gr.Markdown(
76
+ """
77
+ # Chatterbox-Flash TTS
78
+ Prior-calibrated block-diffusion zero-shot TTS by Resemble AI.
79
+ Provide a reference audio clip to clone a voice, or generate with the default voice.
80
+
81
+ [Paper](https://huggingface.co/papers/2605.30748) · [Model](https://huggingface.co/ResembleAI/chatterbox-flash) · [GitHub](https://github.com/resemble-ai/chatterbox-flash)
82
+ """
83
+ )
84
+
85
+ with gr.Row(elem_id="col-container"):
86
+ with gr.Column(scale=3):
87
+ text = gr.Textbox(
88
+ value="Sometimes it's better to just let things slide, you know?",
89
+ label="Text to synthesize (max 300 chars)",
90
+ max_lines=5,
91
+ )
92
+ ref_wav = gr.Audio(
93
+ sources=["upload", "microphone"],
94
+ type="filepath",
95
+ label="Reference Audio (for voice cloning)",
96
+ )
97
+
98
+ with gr.Accordion("Advanced settings", open=False):
99
+ exaggeration = gr.Slider(
100
+ 0.25, 2.0, step=0.05,
101
+ label="Exaggeration (0.5=neutral, higher=more expressive)",
102
+ value=0.5,
103
+ )
104
+ temperature = gr.Slider(
105
+ 0.05, 2.0, step=0.05,
106
+ label="Temperature",
107
+ value=0.6,
108
+ )
109
+ cfg_scale = gr.Slider(
110
+ 0.2, 1.0, step=0.05,
111
+ label="CFG Scale",
112
+ value=1.0,
113
+ )
114
+ num_steps = gr.Slider(
115
+ 1, 30, step=1,
116
+ label="Denoising Steps",
117
+ value=10,
118
+ )
119
+ seed_num = gr.Number(
120
+ value=0, label="Seed (0=random)", precision=0,
121
+ )
122
+
123
+ run_btn = gr.Button("Generate", variant="primary")
124
+
125
+ with gr.Column(scale=2):
126
+ audio_output = gr.Audio(label="Output Audio")
127
+
128
+ gr.Examples(
129
+ examples=[
130
+ ["Sometimes it's better to just let things slide, you know?"],
131
+ ["The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs."],
132
+ ["In the depths of winter, I finally learned that within me lay an invincible summer."],
133
+ ],
134
+ inputs=[text],
135
+ outputs=[audio_output],
136
+ fn=generate_tts,
137
+ cache_examples=True,
138
+ cache_mode="lazy",
139
+ )
140
 
141
+ run_btn.click(
142
+ fn=generate_tts,
143
+ inputs=[
144
+ text, ref_wav, exaggeration,
145
+ temperature, cfg_scale, num_steps, seed_num,
146
+ ],
147
+ outputs=[audio_output],
148
+ api_name="generate",
149
+ )
150
 
151
+ demo.launch(mcp_server=True, theme=gr.themes.Citrus(), css=CSS)