문서에서 음성까지
This content is not available in your language yet.
세팅과 참조음성이 준비됐으면 “docx를 내 목소리로 읽어줘”처럼 문서를 건네면 됩니다. zeroshot-tts-orchestrator가 받아 단계를 에이전트에 위임합니다. 이 문서는 그 단계들이 실제로 무엇을 하는지 봅니다.
먼저 복잡도를 가른다
섹션 제목: “먼저 복잡도를 가른다”오케스트레이터는 작업이 들어오면 곧장 파이프라인을 돌리지 않고 blast radius부터 나눕니다. 문구나 상수 하나 고치는 일이면 오케스트레이션 없이 바로 고칩니다. 크로스페이드 길이만 바꾸는 국소 변경이면 해당 단계 에이전트 하나만 부릅니다. 새 문서를 통째로 변환하거나 엔진을 갈아 끼우는 다단계 작업일 때만 아래 전체 흐름을 탑니다. 되돌리기 어려운 긴 렌더를 헛돌리지 않으려는 장치입니다.
네 단계
섹션 제목: “네 단계”추출 → 전처리·청킹 → 청크별 합성 → 조립1. 텍스트 추출
섹션 제목: “1. 텍스트 추출”doc-extractor가 확장자와 매직바이트로 포맷을 확정합니다. 확장자만 믿지 않는 이유는 .hwp인데 실제로는 hwpx인 경우가 있기 때문입니다. 포맷별로 추출기가 갈립니다. docx는 python-docx, hwpx는 python-hwpx나 zipfile로 여는 방식, pptx는 python-pptx, pdf는 pymupdf를 씁니다.
본문만 뽑고 끝내지 않습니다. 표, 헤더와 푸터, 발표 노트처럼 빠지기 쉬운 텍스트를 챙기고 무엇을 넣고 뺐는지 보고합니다. 문단은 빈 줄로 구분한 평문으로 내보내, 다음 단계의 문단 감지가 작동하게 합니다.
스캔한 PDF처럼 이미지만 있는 문서는 텍스트가 안 나옵니다. 이때 조용히 빈 결과를 내지 않고 OCR이 필요하다고 알립니다.
2. 한국어 전처리와 청킹
섹션 제목: “2. 한국어 전처리와 청킹”제로샷 TTS는 한 번에 처리할 수 있는 길이에 한계가 있습니다. 넘치면 뒤가 잘리거나 엔진이 폭주합니다. audio-pipeline-engineer가 korean-text-chunking으로 이 한도를 지키되 자연스러운 경계에서만 자릅니다.
핵심은 문자 수가 아니라 토큰 추정으로 나눈다는 점입니다. 그리고 문장 중간에서는 절대 자르지 않습니다. 합성 전에 페이지 번호, 각주, URL 같은 읽을 필요 없는 것을 걷어내고, 아라비아 숫자를 한국어 표기로 바꿉니다. 예를 들어 “1장”을 “제 일 장”으로 씁니다. 일부 모델이 숫자를 엉뚱하게 읽기 때문입니다.
3. 청크별 합성
섹션 제목: “3. 청크별 합성”tts-engine-engineer가 만든 어댑터로 청크를 하나씩 합성합니다. 어댑터는 교체할 수 있게 추상화돼 있어서, 엔진을 바꿔도 위쪽 코드는 그대로입니다. 디바이스는 MPS를 먼저 시도하고 실패하면 CPU로 내려갑니다.
합성한 결과가 다 멀쩡하지는 않습니다. 엔진이 갑자기 침묵을 내거나 같은 말을 반복하는 폭주 청크가 나옵니다. 품질 게이트가 이걸 걸러 냅니다. 오디오 길이가 추정한 것보다 지나치게 길면 폭주로 보고 그 청크만 다시 합성합니다. 문서 전체를 다시 돌리지 않습니다. 다시 시도해도 실패하면 해당 청크를 빠뜨렸다고 명시하고 진행한 뒤 최종 리포트에 기록합니다.
4. 조립
섹션 제목: “4. 조립”청크 WAV들을 하나로 잇습니다. 앞뒤의 무음과 노이즈를 트림하고, equal-power 크로스페이드로 이어 붙이고, 문단 사이에 짧은 무음을 넣습니다. 마지막으로 EBU R128 기준 -16 LUFS로 음량을 정규화해 mp3나 wav로 냅니다.
이음매 문제를 정직하게
섹션 제목: “이음매 문제를 정직하게”이 파이프라인에서 가장 어려운 자리가 조립입니다. 청크를 따로따로 합성하기 때문에 경계에서 음색이나 억양이 미세하게 튑니다. 참고한 프로젝트 castforge는 바로 이 경계 문제 때문에 목소리 클로닝을 포기하고 정해진 성우 음성으로 돌아섰습니다.
이 하네스는 크로스페이드로 이음매를 가리고, 청크를 모델이 허용하는 한도까지 크게 잡아 경계 수 자체를 줄이는 쪽으로 완화합니다. 하지만 크로스페이드는 가리는 것이지 없애는 것이 아닙니다. 독립 청크 합성이 만드는 경계의 구조적 한계는 남습니다. 자세한 이야기는 알려진 한계에 있습니다.
다시 실행하기
섹션 제목: “다시 실행하기”작업 공간이 남아 있으면 처음부터 다시 하지 않습니다. “청크 크게” 또는 “엔진 바꿔서”처럼 부분만 바꾸면 해당 단계부터 다시 돕니다. 새 문서를 주면 기존 산출물을 옆으로 옮겨 두고 새로 시작합니다. 중간 산출물은 재실행과 감사를 위해 보존합니다.
파이프라인이 무엇을 하는지 봤으니, 어떤 엔진으로 돌릴지는 모델 비교에서 정합니다. 남은 한계가 궁금하면 알려진 한계로 갑니다.