
AI 나레이터의 목소리가 매번 바뀌는 문제 — 목소리를 한 번만 설계하고 계속 복제하는 TTS 운영
요약
TTS를 활용한 영상 자동 생성 시 발생하는 목소리 불일치 문제를 해결하기 위해, Irodori-TTS를 이용한 '목소리 설계 및 복제' 파이프라인을 제안합니다. VoiceDesign 모델로 고유한 정본 목소리를 설계하고, base 모델의 zero-shot 클로닝을 통해 일관된 브랜드 보이스를 유지하는 운영 노하우를 다룹니다.
핵심 포인트
- VoiceDesign 모델로 실존 인물과 무관한 고유한 목소리 설계
- 설계된 정본(Canonical Reference)을 활용한 zero-shot 클로닝
- 일관성 유지를 위해 참조 WAV 파일과 Seed 값 고정
- 퍼블리시티권 및 사칭 문제를 회피하는 구조적 설계
매일 영상을 자동으로 생성하는 개인 프로젝트를 운영하고 있습니다. 나레이션을 TTS에 맡기면 곧바로 부딪히는 문제가 있습니다. 생성할 때마다 목소리가 미묘하게 다르다는 점입니다.
시청자에게 '채널의 목소리'는 브랜드 그 자체입니다. 어제와 오늘 목소리가 달라지면, 같은 시리즈의 영상이라도 별개의 것으로 보입니다. 그렇다고 매번 사람이 녹음하는 것은 스케일(Scale)이 되지 않습니다.
해결책은 간단했습니다. 목소리를 한 번만 '설계'하고, 이후에는 그 목소리를 zero-shot 클론으로 계속 복제하는 것입니다. OSS인 Irodori-TTS로 이 운영을 수개월간 진행해 왔기에, 파이프라인 설계와 실제로 겪었던 함정들을 정리합니다.

Irodori-TTS의 두 가지 모델 활용법
Irodori-TTS는 Flow Matching 기반의 일본어 대응 TTS로, 역할이 다른 두 계통의 체크포인트(Checkpoint)가 있습니다.
| 모델 | 역할 | 사용 빈도 |
|---|---|---|
Irodori-TTS-600M-v3-VoiceDesign | 목소리를 만듦 — 텍스트 캡션으로부터 목소리 자체를 설계 | 처음 한 번만 |
Irodori-TTS-500M-v3 (base) | 목소리를 재사용 — 참조 음성으로부터 zero-shot 클론 | 매일·모든 영상 |
이 분담이 핵심입니다. VoiceDesign은 "30대 정도의 차분한 여성 목소리, 약간 빠른 말투, 밝은 톤"과 같은 문장으로부터 목소리를 생성할 수 있습니다. 즉, 실존하는 누구의 목소리도 아닌 목소리를 제로(Zero)에서 만들 수 있습니다.
Step 1: 목소리를 '설계'하여 정본을 결정하기
VoiceDesign으로 후보를 여러 개 생성하여 비교해 본 뒤, 단 하나만을 승인합니다. 승인한 WAV 파일은 이후 일절 변경하지 않고, 정본(canonical reference)으로서 단 1개의 파일만 남깁니다.
여기서 의식한 점은, 실존 인물의 녹음을 복제 원본으로 사용하지 않는 것입니다. 오리지널로 설계한 목소리라면 퍼블리시티권(Publicity rights)이나 사칭 문제를 구조적으로 회피할 수 있습니다. 나레이션 용도로는 처음부터 "누군가의 목소리를 닮게 만들" 필요가 없습니다.
Step 2: zero-shot 클론으로 양산하기
양산 단계는 base 모델 하나로 진행합니다. 정본 WAV를 --ref-wav에 전달하기만 하면, 매번 같은 목소리로 임의의 텍스트를 읽어줍니다.
python infer.py \
--hf-checkpoint Aratako/Irodori-TTS-500M-v3 \
--text "こんにちは。今日は通信費の見直しについて話します。" \
...
포인트는 두 가지입니다:
--ref-wav는 매번 같은 정본 파일을 가리킨다. 대본마다 바꾸지 않는다.--seed를 고정하면 목소리 질감·말투의 편차를 더욱 줄일 수 있다 (저희는 모든 영상의 seed=42).
v3 계열은 출력 길이를 자동으로 추정해주므로, --seconds를 수동으로 지정할 필요도 없습니다.
실운영에서 겪은 함정 3가지
여기서부터가 본론입니다. 기술적으로는 위의 2단계로 완성되지만, 운영에 도입하면 사고는 '코드 밖'에서 발생합니다.

함정 ① 정본 드리프트(Drift) — 다른 사람의 목소리인 채로 공개함
새 채널용으로 파이프라인을 복제·파생시켰을 때, 복사 원본의 REF 경로가 그대로 남아 있어서, 다른 채널의 목소리인 채로 영상을 2개 공개해 버렸습니다.
목소리는 diff(차이점)에 나타나지 않습니다. 코드 리뷰에서는 REF = .../voice.wav라는 한 줄이 "올바르게 보입니다". 깨달은 것은 공개 후였습니다.
대책:
- 정본은 채널마다 1개의 파일을 풀 경로(Full path)로 고정하고, 스크립트 내에 "왜 이 REF인가"를 주석으로 남긴다.
- 파이프라인 파생 시의 체크리스트를 만든다 (목소리 REF·배색·마스코트·자막 양식·제목 서식). 파생 작업은 "코드의 복사"가 아니라 "설정의 재정비"라고 생각한다.
함정 ② 오독은 '공통 사전 + 가나(kana) 표기'의 이중 구조로
TTS는 고유명사를 아무렇지 않게 오독합니다. 저희가 실제로 영상에 노출되었던 것은 "楽天市場(라쿠텐 이치바) → らくてんしじょう(라쿠텐 시장)" 형태의 오독입니다.
대책은 이중 구조로 만들었습니다.
일반 명사·고유명사 → 공통 발음 사전. 치환 사전(JSON)을 하나만 준비하여, 모든 파이프라인이 반드시 이것을 거친 후에 TTS에 전달하도록 구성합니다. 사전을 여러 개 가지게 되면 수정 사항이 파이프라인마다 분기되어 사고가 발생합니다 (이것도 한 번 겪었습니다).
조사어 → 대본 데이터 측에서 가나(かな) 표기. '1월'은 '이치가츠' 또는 '히토츠키'로 읽힐 수 있으며, 문맥으로만 결정되기 때문에 사전으로는 처리할 수 없습니다. 대본 데이터에 전용의 읽기 전용 필드를 두어 분리합니다.
{
"narration": "1月の請求額はここで確認できます",
"tts": "いちがつの請求額はここで確認できます"
...
자막에는 narration (한자), TTS에는 tts (가나)를 전달합니다. 표시와 읽기를 분리하는 것만으로 조사어 문제는 거의 사라집니다.
함정③ 콜드 스타트를 오작동으로 오진하지 않기
최초 추론은 모델 다운로드 및 초기화 과정에서 1번째 줄 출력까지 15~30분간 무음이 될 수 있습니다. 이를 '멈췄다(hang)'고 오진하여 프로세스를 kill하면, 다시 시작하는 데 더 많은 시간이 소요됩니다(한 번 이걸로 1시간 이상을 낭비했습니다).
대책은 '알아두는 것'과 미리 작업 큐를 채운 후 투입하는 것입니다. 워밍업 이후의 2번째 줄부터는 초당 수십 줄 속도로 진행됩니다.
검수도 자동화한다 — faster-whisper로 역전사(逆起こし)
오독 방지책을 세워도, 사전에 없는 신어는 반드시 누락합니다. 마지막 관문으로 합성된 음성을 기계가 다시 듣고 대본과 대조하는 공정을 넣었습니다.
from faster_whisper import WhisperModel
model = WhisperModel("large-v3", device="cpu", compute_type="int8")
segments, _ = model.transcribe(
...
condition_on_previous_text=False는 필수적입니다. 기본값이 True일 경우, 짧은 내레이션 음성으로 **같은 문장을 계속 반복하는 환각 루프(hallucination loop)**가 발생하여 대조 작업이 오탐지로 가득 차게 됩니다.
참고로, 역전사 측(Whisper)도 오인식하기 때문에 완벽한 일치도는 요구하지 않습니다. 고유명사와 숫자에 한정하여 대조하면, 실용적인 정확도로 '영상에 올라가기 전'에 오독을 포착할 수 있습니다.
윤리적 측면: '만든 목소리'이므로 안심하고 운영 가능
목소리 클로닝 기술은 사용법을 잘못 알면 가해(加害)가 될 수 있습니다. 운영 규칙으로 지키고 있는 것은 다음 3가지입니다.
- 타인의 실제 목소리를 무단으로 클로닝하지 않는다. 퍼블리시티권 문제 외에도, 사칭/사기 악용과 구별할 수 없게 됩니다. 본인 목소리를 사용할 경우 본인의 명시적인 동의가 전제되어야 합니다.
- AI 음성임을 공개는 플랫폼 규약에 따릅니다 - Irodori-TTS는 생성된 음성에 SilentCipher의 음성 워터마크가 자동으로 삽입됩니다(지원 환경).
- 탐지 가능성을 훼손하지 않는다
원래 이번 구성은 '실재하지 않는 목소리'를 VoiceDesign으로 설계하는 것에서 시작하고 있기 때문에, 권리 측면에서 가장 깔끔한 형태라고 생각합니다. 내레이션 용도로 '누군가와 비슷한 목소리'가 필요한 장면은 실재하지 않습니다.
어느 정도 규모로 운영되고 있는가
참고로, 이 구성으로 실제로 구동되는 양입니다.
| 항목 | 실적 |
|---|---|
| 목소리를 가진 채널 | 3 (각각 다른 원본 WAV) |
| ... | 0회 (설계 단계 이후) |
'주 30개 분량 × 수개월'을 목소리를 한 번도 재작성하지 않고 운영하고 있다는 것이 이 구성의 가장 큰 효용입니다.
반대로 말하면, 원본을 하나의 파일로 고정해 두지 않았다면, 이 규모에서는 확실히 어딘가에서 목소리가 분기하게 됩니다.
요약
- 목소리의 일관성은 원본 1파일 + seed 고정으로 만듭니다. 대본마다 ref를 바꾸지 않습니다 - 사고는 코드 외부에서 발생합니다.
파생 체크리스트・공통 발음 사전・역전사 검수의 3가지 시스템으로 막습니다 - 목소리는 채널의 브랜드입니다. TTS 도입 초기에 '목소리 관리 설계'를 해두면, 나머지는 전부 수월해집니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기