TTS 엔진 추가하기
목표
새로운 텍스트 음성 변환 엔진을 Voicebox에 엔드투엔드로 통합: 의존성 조사, 백엔드 프로토콜 구현, 프론트엔드 UI 연동, PyInstaller 패키징, 그리고 최종 빌드 검증까지. 사용자는 최종 빌드를 로컬에서 테스트하기만 하면 됩니다.
참고 문서
전체 단계별 가이드는 docs/content/docs/developer/tts-engines.mdx에 있습니다. 코드를 작성하기 전에 이 파일을 전체적으로 읽으십시오. 다음 내용이 포함되어 있습니다:
- 0단계: 의존성 조사 (코드 작성 전 필수)
- 1단계: 백엔드 구현 (
TTSBackend프로토콜) - 2단계: 라우트 및 서비스 통합 (일반적으로 변경 불필요)
- 3단계: 프론트엔드 통합 (5개 파일)
- 4단계: 의존성 (
requirements.txt, justfile, CI, Docker) - 5단계: PyInstaller 패키징 (
build_binary.py+server.py) - 6단계: 일반적인 상위 호환 우회 방법
- 구현 체크리스트 (단계 간 관문)
워크플로우
1. 가이드 읽기
# TTS 엔진 문서 전체 읽기
cat docs/content/docs/developer/tts-engines.mdx
모든 단계, 특히 0단계와 5단계를 숙지하십시오. v0.2.3 릴리스는 0단계를 건너뛰어 세 번의 패치 릴리스가 발생했습니다.
2. 의존성 조사 (0단계)
모델 라이브러리를 임시 디렉터리에 클론하고 감사합니다. 절대 건너뛰지 마십시오.
mkdir /tmp/engine-research && cd /tmp/engine-research
git clone <model-library-url>
가이드의 0.2단계에 있는 grep 검색을 클론된 소스와 그 전이 의존성에 대해 실행합니다. 다음을 포함하는 서면 의존성 감사 보고서를 작성합니다:
- PyPI 패키지 vs 비PyPI 패키지
- 필요한 PyInstaller 지시문 (
--collect-all,--copy-metadata,--hidden-import) - 번들에 포함해야 하는 런타임 데이터 파일
- frozen 빌드에서 환경 변수 재정의가 필요한 네이티브 라이브러리 경로
- 필요한 패치 (
torch.load, float64, MPS, HF 토큰) - 샘플 레이트
- 모델 다운로드 방식 (
from_pretrainedvssnapshot_download+from_local)
임시 가상 환경에서 CPU 기반 모델 로딩 및 생성을 진행하기 전에 테스트합니다.
3. 구현 (1~4단계)
가이드의 단계를 순서대로 따릅니다. 수정해야 할 주요 파일:
백엔드 (1단계):
backend/backends/<engine>_backend.py생성backend/backends/__init__.py에 등록 (ModelConfig + TTS_ENGINES + 팩토리)backend/models.py의 정규식 업데이트
프론트엔드 (3단계):
app/src/lib/api/types.ts— 엔진 유니온 타입app/src/lib/constants/languages.ts— ENGINE_LANGUAGESapp/src/components/Generation/EngineModelSelector.tsx— ENGINE_OPTIONS, ENGINE_DESCRIPTIONSapp/src/lib/hooks/useGenerationForm.ts— Zod 스키마, 모델명 매핑app/src/components/ServerSettings/ModelManagement.tsx— MODEL_DESCRIPTIONS
의존성 (4단계):
backend/requirements.txtjustfile(setup-python, setup-python-release 타겟).github/workflows/release.ymlDockerfile(해당하는 경우)
4. PyInstaller 패키징 (5단계)
엔진을 backend/build_binary.py에 등록:
- 백엔드 모듈 및 모델 패키지용
--hidden-import inspect.getsource를 사용하는 패키지, 데이터 파일을 제공하거나 네이티브 라이브러리가 있는 패키지용--collect-allimportlib.metadata를 사용하는 패키지용--copy-metadata
엔진에 네이티브 데이터 경로가 있는 경우 backend/server.py의 if getattr(sys, 'frozen', False): 블록 내부에 os.environ.setdefault()를 추가합니다.
5. 개발 모드에서 확인
just dev
전체 체인을 테스트합니다: 모델 다운로드 → 로드 → 생성 → 음성 복제.
6. 체크리스트 사용
tts-engines.mdx 하단의 구현 체크리스트를 처음부터 끝까지 확인합니다. 사용자에게 빌드를 전달하기 전에 모든 항목이 확인되어야 합니다.
주요 교훈 (v0.2.3에서)
다음은 가장 일반적인 실패 패턴입니다. 0단계 조사로 이 모든 것을 잡을 수 있습니다:
| 패턴 | Frozen 빌드에서의 증상 | 해결 방법 |
|---|---|---|
@typechecked / inspect.getsource() | "소스 코드를 가져올 수 없음" | --collect-all <package> |
| 패키지가 사전 학습된 모델 파일 제공 | .pth.tar, .yaml에 대한 FileNotFoundError | --collect-all <package> |
| 하드코딩된 시스템 경로를 가진 C 라이브러리 | /usr/share/...에 대한 FileNotFoundError | --collect-all + server.py의 환경 변수 |
importlib.metadata.version() | "패키지 메타데이터를 찾을 수 없음" | --copy-metadata <package> |
map_location 없이 torch.load 사용 | CPU 빌드에서 CUDA 장치를 사용할 수 없음 | torch.load 패치 적용 |
float64 데이터에 torch.from_numpy 사용 | dtype 불일치 RuntimeError | .float()으로 변환 |
HF 다운로드 호출에서 token=True | 저장된 HF 토큰 없이 인증 실패 | snapshot_download(token=None) + from_local() 사용 |
참고 사항
- 라우트 및 서비스 계층에는 엔진별 디스패치 포인트가 없습니다.
main.py는 변경이 필요하지 않습니다. backends/__init__.py의 모델 설정 레지스트리가 모든 디스패치를 자동으로 처리합니다.backends/base.py의get_torch_device()와model_load_progress()를 사용하십시오. 장치 감지 또는 진행률 추적을 다시 구현하지 마십시오.- 항상 깨끗한 HuggingFace 캐시로 테스트하십시오 (개발 중 사전 다운로드된 모델 없이).
- 푸시하거나 릴리스를 생성하지 마십시오. 사용자에게 로컬 테스트용 빌드를 전달하십시오.