Flex-TTS / inference.py
FroxAI's picture
Upload 4 files
a5a266c verified
Raw
History Blame Contribute Delete
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