Eyob-Sol's picture
Update app.py
3a90167 verified
raw
history blame
4.01 kB
# app.py
from app.gradio_app import build_demo
from models.tts_router import cleanup_old_audio
import os
import shutil
import stat
import huggingface_hub
from shutil import which
# -----------------------------
# Model: ensure GGUF is present
# -----------------------------
def ensure_model() -> str:
"""
Download the GGUF model into ./models if not already present.
Requires in environment:
- LLAMACPP_MODEL_PATH (target path including filename)
- HF_MODEL_REPO (e.g. Qwen/Qwen2.5-1.5B-Instruct-GGUF)
- HF_MODEL_FILE (e.g. qwen2.5-1.5b-instruct-q4_k_m.gguf)
"""
model_path = os.getenv("LLAMACPP_MODEL_PATH")
repo_id = os.getenv("HF_MODEL_REPO")
filename = os.getenv("HF_MODEL_FILE") or (os.path.basename(model_path) if model_path else None)
if not model_path or not repo_id or not filename:
raise RuntimeError("Missing config: set LLAMACPP_MODEL_PATH and HF_MODEL_REPO (optionally HF_MODEL_FILE).")
if os.path.exists(model_path):
print(f"[MODEL] Found existing model at {model_path}")
return model_path
os.makedirs(os.path.dirname(model_path), exist_ok=True)
print(f"[MODEL] Downloading {filename} from {repo_id} …")
local_path = huggingface_hub.hf_hub_download(
repo_id=repo_id,
filename=filename,
local_dir=os.path.dirname(model_path),
local_dir_use_symlinks=False,
)
# If hf_hub_download wrote elsewhere (cache), move/rename into desired path
if os.path.abspath(local_path) != os.path.abspath(model_path):
shutil.copyfile(local_path, model_path)
print(f"[MODEL] Ready at {model_path}")
return model_path
# ---------------------------------------
# Piper: rely on the PyPI wheel (piper-tts)
# ---------------------------------------
# --- keep your existing imports ---
import os
from huggingface_hub import hf_hub_download
def ensure_piper_voice():
"""
Make sure the Piper voice model exists at PIPER_MODEL.
Defaults to Amy-medium English if none specified.
"""
target_path = os.getenv("PIPER_MODEL", "models/piper/en_US-amy-medium.onnx")
repo_id = os.getenv("PIPER_VOICE_REPO", "rhasspy/piper-voices")
hf_file = os.getenv("PIPER_VOICE_FILE",
"en/en_US/en_US-amy-medium.onnx") # path inside the repo
# If already present, we're done.
if os.path.exists(target_path):
print(f"[PIPER] Voice model present: {target_path}")
return target_path
os.makedirs(os.path.dirname(target_path), exist_ok=True)
print(f"[PIPER] Downloading voice {hf_file} from {repo_id} …")
local = hf_hub_download(
repo_id=repo_id,
filename=hf_file,
local_dir=os.path.dirname(target_path),
local_dir_use_symlinks=False,
)
# Move/rename to the exact target filename if the name differs
if os.path.abspath(local) != os.path.abspath(target_path):
import shutil
shutil.copyfile(local, target_path)
print(f"[PIPER] Voice ready at: {target_path}")
return target_path
# No PIPER_BIN provided → try PATH
resolved = which("piper")
if resolved:
print(f"[PIPER] Found in PATH: {resolved}")
return resolved
print("[PIPER] Not found. Install via 'piper-tts' wheel in requirements.txt.")
return None
def log_env_for_audio():
print("[ENV] TTS_ENGINE =", os.getenv("TTS_ENGINE", "(unset)"))
print("[ENV] PIPER_MODEL=", os.getenv("PIPER_MODEL", "(unset)"))
print("[ENV] PIPER_BIN =", os.getenv("PIPER_BIN", "(unset)"))
# -------------
# Application
# -------------
def main():
# Log a few envs to help debug Spaces
log_env_for_audio()
# Clean runtime/audio on boot
cleanup_old_audio(keep_latest=None)
# Ensure model exists locally
ensure_model()
ensure_piper_voice()
# Launch Gradio
demo = build_demo()
# On Spaces, share=True is ignored (safe locally)
demo.launch(share=True)
if __name__ == "__main__":
main()