yash184 commited on
Commit
4e2d294
·
verified ·
1 Parent(s): ddd994d

Upload 5 files

Browse files
Files changed (5) hide show
  1. .gitignore +2 -0
  2. README.md +16 -0
  3. app.py +96 -0
  4. huggingface_hub.py +79 -0
  5. requirements.txt +13 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ __pycache__/
2
+ outputs/
README.md ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: "12labtts (lightweight build)"
3
+ emoji: "🎤"
4
+ colorFrom: "blue"
5
+ colorTo: "purple"
6
+ sdk: "gradio"
7
+ sdk_version: "4.19.0"
8
+ app_file: "app.py"
9
+ pinned: false
10
+ ---
11
+
12
+ This Space build avoids installing `chatterbox-tts` by default (it pulls heavy build deps that often fail).
13
+ It provides a gTTS fallback so the Space builds quickly and runs. If you want to enable `chatterbox-tts` later,
14
+ add it to `requirements.txt` and ensure the build environment supports its build dependencies.
15
+
16
+ **If your model `yash184/12labtts` is private**: add `HUGGINGFACE_HUB_TOKEN` in Space settings -> Secrets.
app.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from pathlib import Path
3
+ from gtts import gTTS
4
+ import tempfile
5
+
6
+ # Ensure a huggingface-hub version compatible with Gradio's oauth import is installed.
7
+ # This runs at startup and may increase cold-start time.
8
+ import subprocess, sys
9
+ try:
10
+ import huggingface_hub as _hh
11
+ # If HfFolder is missing, reinstall a compatible minor version
12
+ if not hasattr(_hh, "HfFolder"):
13
+ raise ImportError
14
+ except Exception:
15
+ print("Installing compatible huggingface-hub version...")
16
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "huggingface-hub==0.14.1"])
17
+ # reload after install
18
+ import importlib
19
+ import huggingface_hub as _hh
20
+
21
+ import gradio as gr
22
+ import requests
23
+
24
+ # Try to import chatterbox if user installs it later
25
+ try:
26
+ import chatterbox_tts as cb_tts
27
+ chatterbox_available = True
28
+ except Exception:
29
+ cb_tts = None
30
+ chatterbox_available = False
31
+
32
+ def synthesize_with_chatterbox(text, lang="en", reference=None):
33
+ # Adapter placeholder -- real API call depends on chatterbox-tts
34
+ if not chatterbox_available:
35
+ raise RuntimeError("Chatterbox not available")
36
+ # Example hypothetical API; adapt if you install chatterbox-tts
37
+ model = cb_tts.load_model(".")
38
+ out = model.generate(text, lang=lang, reference=reference)
39
+ # Expecting out to be dict with 'wav' and 'sr' or path; adapt as needed
40
+ if isinstance(out, dict) and "wav" in out:
41
+ wav = out["wav"]
42
+ # Save as WAV via soundfile if available
43
+ import soundfile as sf
44
+ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
45
+ sf.write(tmp.name, wav, out.get("sr", 24000))
46
+ return tmp.name
47
+ elif isinstance(out, str) and Path(out).exists():
48
+ return out
49
+ else:
50
+ raise RuntimeError("Unrecognized Chatterbox output format")
51
+
52
+ def synthesize_with_gtts(text, lang="en"):
53
+ tts = gTTS(text=text, lang=lang.split("-")[0] if "-" in lang else lang)
54
+ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
55
+ tts.save(tmp.name)
56
+ return tmp.name
57
+
58
+ def synthesize(text, language="English", use_chatterbox=False):
59
+ if not text.strip():
60
+ return None, "Text is empty"
61
+ lang_map = {
62
+ "English": "en", "Hindi": "hi", "French": "fr", "Spanish": "es", "German": "de"
63
+ }
64
+ lang = lang_map.get(language, "en")
65
+ # Prefer chatterbox if requested and available
66
+ if use_chatterbox and chatterbox_available:
67
+ try:
68
+ path = synthesize_with_chatterbox(text, lang=lang)
69
+ return path, None
70
+ except Exception as e:
71
+ return None, f"Chatterbox error: {e}"
72
+ # Fallback to gTTS
73
+ try:
74
+ path = synthesize_with_gtts(text, lang=lang)
75
+ return path, None
76
+ except Exception as e:
77
+ return None, f"gTTS error: {e}"
78
+
79
+ with gr.Blocks() as demo:
80
+ gr.Markdown("# 12labtts — lightweight Space\n\nThis Space uses gTTS as a fallback so it builds quickly on Hugging Face.\n")
81
+ with gr.Row():
82
+ txt = gr.Textbox(label="Text", lines=4, value="Hello world! This is a test.")
83
+ lang = gr.Dropdown(choices=["English","Hindi","French","Spanish","German"], value="English", label="Language")
84
+ use_cb = gr.Checkbox(label="Use Chatterbox if available", value=False)
85
+ out = gr.Audio(label="Output", type="filepath")
86
+ status = gr.Textbox(label="Status", interactive=False)
87
+ def run(text, language, use_chatterbox):
88
+ path, err = synthesize(text, language, use_chatterbox)
89
+ if err:
90
+ return None, err
91
+ return path, "OK"
92
+ btn = gr.Button("Synthesize")
93
+ btn.click(run, inputs=[txt, lang, use_cb], outputs=[out, status])
94
+
95
+ if __name__ == "__main__":
96
+ demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)))
huggingface_hub.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # Compatibility shim for huggingface_hub to provide HfFolder and whoami for older Gradio expectations.
3
+ # This shim delegates to the installed huggingface_hub where possible but provides fallback
4
+ # implementations for HfFolder and whoami if the installed version is missing them.
5
+ import os, json, pathlib
6
+ try:
7
+ import huggingface_hub as _real_hf
8
+ except Exception:
9
+ _real_hf = None
10
+
11
+ class HfFolder:
12
+ """
13
+ Minimal compatibility wrapper exposing methods Gradio expects:
14
+ - path(): returns the token file path
15
+ - get_token(): returns token string or None
16
+ - save_token(token): writes token to file
17
+ """
18
+ @staticmethod
19
+ def path(token_filename=".huggingface/token"):
20
+ # return token file path (legacy behaviour)
21
+ home = os.path.expanduser("~")
22
+ hf_dir = os.path.join(home, ".huggingface")
23
+ os.makedirs(hf_dir, exist_ok=True)
24
+ return os.path.join(hf_dir, "token")
25
+
26
+ @staticmethod
27
+ def get_token():
28
+ # Prefer env var (HUGGINGFACE_HUB_TOKEN or HF_TOKEN)
29
+ for key in ("HUGGINGFACE_HUB_TOKEN", "HF_TOKEN", "HUGGINGFACE_TOKEN"):
30
+ v = os.environ.get(key)
31
+ if v:
32
+ return v
33
+ # Try to read token file if present
34
+ try:
35
+ p = HfFolder.path()
36
+ if os.path.exists(p):
37
+ with open(p, "r", encoding="utf-8") as f:
38
+ token = f.read().strip()
39
+ if token:
40
+ return token
41
+ except Exception:
42
+ pass
43
+ # If upstream provides a method, use it
44
+ try:
45
+ if _real_hf and hasattr(_real_hf, "HfFolder") and hasattr(_real_hf.HfFolder, "get_token"):
46
+ return _real_hf.HfFolder.get_token()
47
+ except Exception:
48
+ pass
49
+ return None
50
+
51
+ @staticmethod
52
+ def save_token(token):
53
+ try:
54
+ p = HfFolder.path()
55
+ with open(p, "w", encoding="utf-8") as f:
56
+ f.write(token)
57
+ return p
58
+ except Exception:
59
+ return None
60
+
61
+ # whoami wrapper - try to call the real API if present.
62
+ def whoami(token=None):
63
+ # If user passed token, try to use real whoami
64
+ try:
65
+ if _real_hf and hasattr(_real_hf, "whoami"):
66
+ # some versions accept token parameter, others use env
67
+ try:
68
+ return _real_hf.whoami(token=token) if token is not None else _real_hf.whoami()
69
+ except TypeError:
70
+ return _real_hf.whoami()
71
+ except Exception:
72
+ pass
73
+
74
+ # Fallback: if token available return a minimal dict with 'name' from token file or env
75
+ tk = token or HfFolder.get_token()
76
+ if not tk:
77
+ return {}
78
+ # Heuristic: token might embed username after 'hf_' not possible; return token presence info
79
+ return {"ok": True, "token_present": True}
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ gradio>=6.0.0
2
+ gTTS==2.4.0
3
+ numpy==1.25.2
4
+ wheel
5
+ setuptools
6
+ cython
7
+ torch
8
+ torchaudio
9
+ pydub
10
+ nltk
11
+ huggingface-hub
12
+ requests
13
+ soundfile