Download inference.py from FroxAI/Flex-TTS: direct link, hf CLI and curl.
- Browser
- Download file 2.21 kB
-
https://huggingface.co/FroxAI/Flex-TTS/resolve/main/inference.py
- Command line
-
hf download hf://FroxAI/Flex-TTS/inference.py
-
curl -L -o inference.py https://huggingface.co/FroxAI/Flex-TTS/resolve/main/inference.py
2.21 kB
| """ | |
| FroxAI Flex-Audio — inference helper. | |
| Loads the fine-tuned XTTS-v2 checkpoint (model.pth + config.json + vocab.json, | |
| all expected in the repo root) and exposes a single generate() function used by | |
| both app.py (Gradio UI) and any other script that wants to import this directly. | |
| """ | |
| import os | |
| import torch | |
| from TTS.tts.configs.xtts_config import XttsConfig | |
| from TTS.tts.models.xtts import Xtts | |
| REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| VOICES_DIR = os.path.join(REPO_ROOT, "voice_refs") | |
| _model = None | |
| _config = None | |
| def load_model(): | |
| """Loads the model once and caches it. Safe to call repeatedly.""" | |
| global _model, _config | |
| if _model is not None: | |
| return _model, _config | |
| config = XttsConfig() | |
| config.load_json(os.path.join(REPO_ROOT, "config.json")) | |
| model = Xtts.init_from_config(config) | |
| model.load_checkpoint(config, checkpoint_dir=REPO_ROOT, eval=True) | |
| if torch.cuda.is_available(): | |
| model.cuda() | |
| _model, _config = model, config | |
| return model, config | |
| def list_voices(): | |
| """Returns available voice names (without the .wav extension) found in voice_refs/.""" | |
| if not os.path.isdir(VOICES_DIR): | |
| return [] | |
| return sorted( | |
| os.path.splitext(f)[0] | |
| for f in os.listdir(VOICES_DIR) | |
| if f.lower().endswith(".wav") | |
| ) | |
| def generate(text: str, language: str, voice: str) -> str: | |
| """Generates speech and returns the path to the written WAV file. | |
| Args: | |
| text: the text to speak. | |
| language: an XTTS-v2 language code, e.g. 'en', 'es', 'hi'. | |
| voice: a voice name as returned by list_voices() (matches a file in voice_refs/). | |
| """ | |
| model, config = load_model() | |
| voice_path = os.path.join(VOICES_DIR, f"{voice}.wav") | |
| if not os.path.exists(voice_path): | |
| raise FileNotFoundError(f"No reference clip found for voice '{voice}' at {voice_path}") | |
| outputs = model.synthesize( | |
| text, | |
| config, | |
| speaker_wav=voice_path, | |
| language=language, | |
| ) | |
| out_path = "/tmp/frox_flex_audio_output.wav" | |
| import soundfile as sf | |
| sf.write(out_path, outputs["wav"], config.audio.sample_rate) | |
| return out_path | |