내 목소리를 무료로 AI에 클로닝하기 — Mac 오픈소스 TTS 실전기
유튜브 튜토리얼을 만들며 제 목소리로 녹음한 한국어 내레이션이 차곡차곡 쌓여 있었습니다. 그러던 어느 날, 이 목소리를 AI에게 학습시켜 나 대신 나처럼 말하게 할 수 있을까, 그것도 무료로 하는 호기심이 들었습니다. 소스가 될 음성은 충분했으니 더 미룰 이유가 없었습니다. 이 글은 Mac M2 Pro 한 대로 오픈소스 TTS를 직접 돌려 제 목소리를 복제해본, AI 음성 클로닝 실전 기록입니다. 다만 정작 값진 교훈은 "어떻게 클론했는가"가 아니라, 무엇이 무료고 무엇이 무료가 아닌가 하는 경계를 더듬어본 데 있었습니다.
무료 플랜이 있다고 내 목소리가 무료로 클론되는 건 아니었습니다
가장 먼저 부딪힌 것은 기술이 아니라 서비스 지형이었습니다. 음성 클로닝 도구를 훑어보니 무료와 유료의 경계가 막연히 생각하던 것과 사뭇 달랐습니다. "무료 플랜이 있다"는 말과 "내 목소리를 무료로 클론할 수 있다"는 말은 전혀 다른 이야기였습니다.
상업 서비스들은 무료 티어를 두더라도 대개 둘 중 하나였습니다. 클로닝 기능 자체를 막아두거나, 클론은 만들게 해주되 산출물의 상업적 이용을 약관으로 금지하는 식이었습니다. 가령 ElevenLabs는 무료 플랜으로 클로닝이 안 되고 인스턴트 클론이 월 $5부터이며, 무료로 뽑은 결과물은 약관상 광고에 쓸 수 없었습니다. 한국어 토종도 비슷해서, Supertone Play는 무료 체험만으로 클론을 만들 수 있고 운율이 자연스러운 편이었던 반면 Typecast는 클론 생성이 유료 Pro부터였습니다.
| 서비스 | 무료로 클론 생성 | 무료 산출물 상업 이용 |
|---|---|---|
| ElevenLabs | 불가 (인스턴트 클론 $5~) | 약관상 금지 |
| Supertone Play | 무료 체험으로 가능 | 플랜·약관 확인 필요 |
| Typecast | 유료 Pro부터 | 플랜·약관 확인 필요 |
그러니 완전히 무료이면서, 내 음성 파일을 그대로 쓰고, 어디에도 업로드하지 않는 길을 원한다면 답은 하나로 좁혀졌습니다. 내 컴퓨터에서 도는 오픈소스였습니다. 클라우드에 목소리를 올리지 않으니 개인정보 면에서도 마음이 편했습니다.
그래서 로컬 오픈소스 — XTTS와 Chatterbox, 라이선스가 갈랐습니다
먼저 유튜브 영상에서 제 목소리만 담긴 구간을 골라 ffmpeg로 짤막한 레퍼런스 클립을 뽑았습니다. 그다음 로컬에서 돌릴 만한 한국어 지원 모델 두 가지를 직접 비교했습니다.
하나는 XTTS v2(coqui-tts)였습니다. 빨랐습니다. CPU에서 실시간 대비 1.7배속으로 합성했고 한국어도 무리 없이 읽어주었습니다. 그런데 결정적인 문제가 라이선스에 있었습니다. XTTS는 비상업 라이선스(CPML)로 묶여 있는데, 원개발사 Coqui가 이미 폐업한 탓에 상업 라이선스를 사려 해도 살 곳이 없었습니다. 다시 말해 성능이 좋아도 수익화에는 쓸 수 없는 모델, 길이 막혀 있었습니다.
다른 하나는 Chatterbox Multilingual(Resemble AI)이었습니다. 같은 레퍼런스를 물려 직접 들어보니 한국어가 XTTS보다 한결 자연스러웠고, 무엇보다 MIT 라이선스였습니다. 상업적 사용에 제약이 없으니, 무료 로컬에서 수익화까지 가는 현실적인 1순위는 결국 이쪽이었습니다.
| 항목 | XTTS v2 | Chatterbox Multilingual |
|---|---|---|
| 속도(CPU) | 빠름 (1.7배속) | 느린 편 (4.9배속) |
| 한국어 자연스러움 | 무난 | 더 자연스러움 |
| 라이선스 | 비상업 (CPML) | MIT (상업 가능) |
| 수익화 | 불가 (상업 라이선스 취득 경로 없음) | 가능 |
두 모델을 저울질하며 든 생각은, 결국 이 선택을 가른 것이 음질이 아니라 라이선스였다는 점입니다. 아무리 잘 읽어줘도 쓸 수 없는 결과물이라면 의미가 없었습니다.
셋업에서 만난 함정 몇 가지
같은 길을 걸으실 분을 위해, 환경을 세우며 헤맸던 지점을 남겨둡니다. 모두 의존성에서 비롯된 함정이었습니다.
먼저 XTTS 쪽입니다. coqui-tts(0.27.5)는 transformers를 >=4.57로 요구하는데, 정작 코드가 5.0에서 삭제된 함수(isin_mps_friendly)를 호출했습니다. 시키는 대로 최신을 깔면 오히려 깨졌고, 실제 동작 범위는 [4.57, 5.0) 사이였습니다. 여기에 torch 2.9 이상이라면 오디오 입출력을 위해 torchcodec을 따로 설치해야 했습니다.
Chatterbox에도 비슷한 함정이 있었습니다. 워터마크 라이브러리(perth)가 None으로 깨져 들어와, 더미 클래스로 monkeypatch를 해줘야 로드가 됐습니다. 그리고 Mac에서는 torch.load에 map_location을 지정하는 패치를 권합니다. 환경 격리는 uv로 Python 3.11이나 3.12 전용 가상환경을 두는 편이 안전했습니다. 시스템에 깔린 Python 3.14는 너무 최신이라 호환이 맞지 않았습니다.
품질의 80%는 모델이 아니라 레퍼런스였습니다
모델을 띄우고 나서 가장 크게 체감한 사실은 따로 있었습니다. 결과물의 품질을 좌우한 것은 모델이 아니라, 어떤 레퍼런스를 물려주느냐였습니다. 체감으로는 8할이 여기서 결정됐습니다.
영상에서 잡음 없이 한 사람만 또렷하게 말하는 약 22초 구간을 골랐습니다. 그리고 그대로 쓰지 않고 ffmpeg로 한 번 다듬었습니다. 저역의 웅웅거림을 걷어내는 하이패스 필터, 배경 잡음을 줄이는 디노이즈, 음량을 일정하게 맞추는 라우드니스 정규화를 차례로 걸었습니다.
ffmpeg -i input.wav -af "highpass=f=60, afftdn=nr=10, loudnorm" reference.wav
정제 전과 후의 차이는 생각보다 컸습니다. 같은 모델, 같은 파라미터인데도 깨끗하게 다듬은 레퍼런스를 물렸을 때 합성음이 한결 또렷해졌습니다. 길이는 10초에서 20초 사이가 가장 무난했습니다. 너무 짧으면 억양을 충분히 담지 못해 밋밋해졌습니다.
파라미터 두 개와 긴 텍스트 처리
레퍼런스를 갖춘 다음에는 Chatterbox의 파라미터로 결을 맞췄습니다. 핵심 레버는 cfg_weight였습니다. 기본값 0.5에서 0.3으로 낮추니 발음이 또박또박해지고 남아 있던 외국어 억양이 눈에 띄게 완화됐습니다.
반면 exaggeration은 직관이 배신당한 지점이었습니다. 표현을 차분하게 만들고 싶어 0.3으로 낮췄더니, 오히려 소음 같은 아티팩트가 끼었습니다. 결국 exaggeration은 0.5로 두는 편이 가장 깔끔했습니다.
model.generate(
text,
audio_prompt_path="reference.wav",
exaggeration=0.5, # 낮추면 오히려 소음이 끼어 0.5 유지
cfg_weight=0.3, # 0.5 → 0.3, 또박또박해지고 억양 완화 (핵심 레버)
)
한 가지 더, 긴 글을 한 번에 넣으면 Chatterbox가 뒷부분을 잘라먹었습니다. 그래서 문장 단위로 쪼개 따로 합성한 뒤 이어붙였습니다. 번거롭지만 이렇게 해야 긴 내레이션도 온전히 만들어졌습니다.
"Mac GPU 쓰면 빠르겠지"는 신화였습니다
처음엔 당연히 GPU를 켜면 빨라지리라 생각했습니다. Apple Silicon에는 MPS라는 GPU 가속 경로가 있으니 신경망 TTS도 그 덕을 보겠거니 했습니다. 그런데 실측 결과는 정반대였습니다.
같은 Chatterbox를 두고 잰 속도가 MPS에서 실시간 대비 8.4배속, CPU에서 4.9배속이었습니다. 숫자가 작을수록 빠른 것이니 결과적으로 CPU가 더 빨랐습니다. 이유는 단순했습니다. MPS에 아직 구현되지 않은 연산이 많아, 그때마다 GPU와 CPU를 오가는 fallback이 일어났고 그 오버헤드가 이득을 다 까먹은 것입니다.
여기서 혼동하기 쉬운 지점을 짚어둡니다. 영상 편집을 할 때 빠릿하게 돌아가는 그 하드웨어 가속은 VideoToolbox라는 미디어 엔진으로, 영상 인코딩 전용입니다. "렌더링이 빨라지는 그 칩"으로 TTS를 돌릴 수 있는 게 아닙니다. 둘은 전혀 다른 길입니다. 결론은 분명했습니다. 로컬 TTS는 괜히 GPU를 찾지 말고 그냥 CPU로 돌리는 편이 낫습니다.
정리하며 — 무료로 갈 수 있는 자리와 그렇지 않은 자리
여러 시행착오 끝에 정리한 제 정답 레시피는 이렇습니다. ffmpeg로 정제한 약 22초짜리 레퍼런스(highpass + denoise + loudnorm)에 Chatterbox를 exaggeration=0.5 / cfg_weight=0.3으로 두고 CPU로 합성하는 것입니다. 무료이면서 로컬이고 한국어가 되며 상업적으로도 쓸 수 있는 조합을 원한다면, 현재로서는 Chatterbox가 답이라는 결론에 이르렀습니다.
다만 한계도 솔직히 적어둡니다. 오픈소스 두 모델 모두 한국어에 미묘한 외국어 억양이 남았습니다. 진짜 자연스러운 한국어, 실전 수익화에 내놓을 품질이라는 기준에서는 토종 서비스(Supertone, Typecast)가 여전히 한 수 위라는 생각이 들었습니다. 무료 로컬이 모든 자리를 대체하지는 못했습니다.
그럼에도 로컬 오픈소스에는 분명한 자리가 있었습니다. 돈을 들이지 않고 음성 합성의 감각을 익히기에 좋았고, 본인 콘텐츠나 학습·실험 용도로는 더없이 충분했으며, 완전히 무료인 채 상업적 결과물까지 필요할 때는 Chatterbox가 그 빈자리를 메워주었습니다.
돌이켜 생각해보면, 이번 AI 음성 클로닝 실험에서 제가 진짜로 손에 쥔 것은 "내 목소리를 복제했다"는 결과가 아니었습니다. 무료라는 말 뒤에 그어진 경계 — 어디까지가 정말 공짜이고, 어디부터는 라이선스나 품질이라는 값을 치러야 하는지를 직접 더듬어본 경험이었습니다. 클로닝 자체보다, 그 경계를 알게 된 쪽이 오래 남을 듯합니다.
관련 글
영상에서 텍스트를 뽑고 싶었다 — ffmpeg, whisper-cpp, VAD로 로컬 STT 파이프라인 만들기
영상 파일에서 텍스트를 추출하는 로컬 STT 파이프라인을 구축한 경험입니다. ffmpeg가 오디오를 왜 16kHz 모노 PCM으로 변환하는지, whisper-cpp가 Python 없이 어떻게 동작하는지, VAD가 STT 품질을 어떻게 개선하는지 하나씩 따라가봅니다.
whisper와 Claude로 영상 자막·무음 컷 자동화하기 — 동작 원리
자기소개 쇼츠 하나를 만들려다, 자막과 무음 컷을 외부 SaaS 없이 자동화한 기록입니다. whisper·ffmpeg 같은 결정적 도구가 타이밍과 렌더링을, 옆에 켜둔 대화 세션의 Claude가 '어디서 자르고 묶을지'라는 판단을 맡는 분업의 동작 원리를 풀어냈습니다.
큰 작업의 거처를 챗봇 UI에서 로컬 하네스로 — 옆에서 함께 옮긴 이야기
주변에서 외부 챗봇의 커스텀 기능 위에 무거운 작업을 굴리던 분이 매번 같은 자리에서 막히는 걸 보고, 그 작업의 거처를 Claude Code 위 로컬 하네스로 옮겨드린 과정. 옆에서 본 네 가지 막힘과 함께 갖춰둔 여섯 가지 패턴을 정리했습니다.