Spaces:
Running on Zero
Running on Zero
| """GEPARD β text-to-speech inference Space (ZeroGPU). | |
| Startup order is load-bearing: | |
| 1. ``create_env.setup_dependencies()`` re-pins transformers BEFORE any | |
| ML import β the Space image ships whatever NeMo pinned at build time, | |
| but the Gepard checkpoint requires transformers 5.3.0. | |
| 2. ``spaces`` is imported before torch so ZeroGPU can patch CUDA calls. | |
| 3. The engine (model + codec + speakers) is built ONCE at module level; | |
| ZeroGPU replays the recorded ``.to("cuda")`` moves when a GPU is | |
| attached, so no per-request reloading happens. | |
| """ | |
| from create_env import setup_dependencies | |
| setup_dependencies() | |
| try: # ZeroGPU runtime (present on HF Spaces) | |
| import spaces # noqa: E402 | |
| _gpu_decorator = spaces.GPU | |
| except ImportError: # local run β no-op stand-in | |
| def _gpu_decorator(*args, **kwargs): | |
| if args and callable(args[0]): | |
| return args[0] | |
| def _wrap(fn): | |
| return fn | |
| return _wrap | |
| from pathlib import Path # noqa: E402 | |
| import gradio as gr # noqa: E402 | |
| from gepard_inference.engine import AppConfig, GenerationParams, GepardEngine # noqa: E402 | |
| from interface import MODE_PRESET, GepardInterface # noqa: E402 | |
| CONFIG_PATH = Path(__file__).parent / "config.yaml" | |
| config = AppConfig.from_yaml(CONFIG_PATH) | |
| engine = GepardEngine(config).load() | |
| def synthesize( | |
| mode: str, | |
| speaker: str, | |
| ref_audio: str, | |
| text: str, | |
| temperature: float, | |
| top_k: float, | |
| max_frames: float, | |
| repetition_penalty: float, | |
| repetition_window: float, | |
| ): | |
| """Gradio handler: resolve the reference voice, then generate speech. | |
| Runs inside the ZeroGPU context β both the reference encoding (clone | |
| mode) and the autoregressive generation share one GPU session. | |
| """ | |
| if not (text or "").strip(): | |
| raise gr.Error("Please enter some text to synthesize.") | |
| if mode == MODE_PRESET: | |
| if not speaker: | |
| raise gr.Error("Please choose a preset speaker.") | |
| ref_codes = engine.speakers.codes(speaker) | |
| else: | |
| if not ref_audio: | |
| raise gr.Error("Please record or upload a reference clip.") | |
| ref_codes = engine.encode_reference(ref_audio) | |
| params = GenerationParams( | |
| temperature=temperature, | |
| top_k=int(top_k), | |
| # CFG is not exposed in the UI: strength comes from config defaults and | |
| # the runner's length gate decides whether it applies at all. | |
| cfg_scale=config.defaults.cfg_scale, | |
| cfg_frames=config.defaults.cfg_frames, | |
| stop_threshold=config.defaults.stop_threshold, | |
| max_frames=int(max_frames), | |
| repetition_penalty=repetition_penalty, | |
| repetition_window=int(repetition_window), | |
| ) | |
| return engine.synthesize(text, ref_codes, params) | |
| demo = GepardInterface( | |
| config=config, | |
| speaker_names=engine.speakers.names, | |
| synthesize_fn=synthesize, | |
| ).build() | |
| if __name__ == "__main__": | |
| demo.launch() | |