Files
tts_site/app/engines/__init__.py
claude 9c1009d16d feat: CosyVoice 한국어 엔진 통합 (Apache-2.0, GPU)
- vendor/CosyVoice: 패치된 CosyVoice 코드 + Matcha-TTS 벤더링
- cosyvoice_worker: 전용 venv에서 상주하는 합성 워커(FastAPI, 모델 1회 로드)
- app/engines/cosyvoice_engine: HTTP 프록시 엔진(속도/피치)
- Dockerfile: 전용 venv(torch cu128) + 모델 베이킹 + 빌드 워밍업
- entrypoint.sh: 워커(8001) + 메인앱(8788) 동시 기동
2026-08-23 23:16:24 +09:00

74 lines
1.8 KiB
Python

"""엔진 레지스트리.
엔진을 lazy 하게 생성하고 id 로 조회한다. 사용 불가한 엔진(전용 venv/모델 미설치)은
자동으로 목록에서 제외한다.
"""
from __future__ import annotations
import threading
from .base import BaseEngine
_ENGINES: dict[str, BaseEngine] = {}
_LOCK = threading.Lock()
_INITED = False
def _build() -> None:
global _INITED
if _INITED:
return
with _LOCK:
if _INITED:
return
# MeloTTS (항상 사용 가능)
try:
from .melo_engine import MeloEngine
e = MeloEngine()
_ENGINES[e.id] = e
except Exception as exc: # pragma: no cover
print(f"[registry] MeloTTS 로드 실패: {exc}")
# CosyVoice 한국어 (전용 워커 URL 이 설정된 경우에만)
try:
from .cosyvoice_engine import CosyVoiceEngine
if CosyVoiceEngine.available():
e = CosyVoiceEngine()
_ENGINES[e.id] = e
except Exception as exc: # pragma: no cover
print(f"[registry] CosyVoice 엔진 스킵: {exc}")
_INITED = True
def get_engine(engine_id: str) -> BaseEngine:
_build()
if engine_id not in _ENGINES:
raise ValueError(f"알 수 없는 엔진입니다: {engine_id}")
return _ENGINES[engine_id]
def list_engines() -> list[BaseEngine]:
_build()
return list(_ENGINES.values())
def default_engine_id() -> str:
_build()
# MeloTTS 우선
if "melo" in _ENGINES:
return "melo"
return next(iter(_ENGINES)) if _ENGINES else ""
def warmup_all() -> None:
_build()
for e in _ENGINES.values():
try:
e.warmup()
except Exception as exc: # pragma: no cover
print(f"[registry] {e.id} warmup 실패: {exc}")