음성 복제
짧은 레퍼런스 오디오 샘플에서 어떤 음성이든 복제합니다. Qwen3-TTS와 CosyVoice3 모두 각각 ECAPA-TDNN (1024차원)과 CAM++ (192차원)의 서로 다른 화자 인코더로 음성 복제를 지원합니다.
동작 방식
- 대상 음성의 레퍼런스 오디오 샘플을 녹음하거나 제공합니다
- 화자 임베딩 추출 — 화자 인코더가 레퍼런스 오디오를 고정 차원 임베딩 벡터로 처리합니다
- 임베딩 주입 — 화자 임베딩이 합성 중 TTS 모델을 조건화합니다
- 음성 합성 — TTS 모델이 레퍼런스 샘플의 음성 특성과 일치하는 음성을 생성합니다
엔진
음성 복제는 두 TTS 엔진 모두에서 사용할 수 있습니다. 각각 다른 화자 인코더를 사용합니다:
| 엔진 | 화자 인코더 | 임베딩 | 백엔드 |
|---|---|---|---|
| Qwen3-TTS | ECAPA-TDNN | 1024차원 x-vector | MLX (GPU) |
| CosyVoice3 | CAM++ | 192차원 | CoreML (Neural Engine) |
CosyVoice3 + CAM++
CosyVoice3는 Alibaba의 3D-Speaker 프로젝트의 CAM++ (Context-Aware Masking++) 화자 인코더를 사용합니다. 192차원 임베딩은 CosyVoice3와 함께 공동 학습된 affine projection 레이어(192 → 80)를 통해 DiT flow 모델을 조건화합니다.
CAM++ 아키텍처
| 단계 | 설명 |
|---|---|
| FCM | 프론트엔드 컨볼루션 모듈 (Conv2d + 2개 ResBlock, 32 채널) |
| TDNN | Time Delay Neural Network (320 → 128 채널, 커널 크기 5) |
| D-TDNN 블록 | context-aware masking이 적용된 3개의 밀집 연결 블록 (12/24/16 레이어) |
| Stats Pool | Mean + standard deviation pooling (전역 통계) |
| Dense | 192차원 임베딩으로의 선형 투영 |
CoreML 모델(약 14 MB, FP16)은 Neural Engine에서 실행됩니다. 첫 사용 시 aufklarer/CamPlusPlus-Speaker-CoreML에서 자동으로 다운로드됩니다.
Qwen3-TTS 음성 복제
Qwen3-TTS는 두 가지 음성 복제 모드를 지원합니다:
ICL 모드 (권장)
In-Context Learning 모드는 Mimi speech tokenizer 인코더를 통해 레퍼런스 오디오를 코덱 토큰으로 인코딩하고 레퍼런스 전사 앞에 추가합니다. 이를 통해 모델이 전체 음향 컨텍스트를 얻게 되며 — 더 높은 품질과 안정적인 EOS를 제공합니다 (짧은 텍스트와 비영어 언어의 문제를 해결합니다).
let (model, encoder) = try await Qwen3TTSModel.fromPretrainedWithEncoder()
let audio = model.synthesizeWithVoiceCloneICL(
text: "Target text to synthesize.",
referenceAudio: refSamples,
referenceSampleRate: 24000,
referenceText: "Exact transcript of reference audio.",
language: "english",
codecEncoder: encoder
)
X-Vector 모드
1024차원 x-vector를 생성하는 ECAPA-TDNN 인코더를 사용합니다. 전사가 필요하지 않지만 품질이 낮습니다. 짧은 텍스트나 특정 언어에서 EOS를 방출하지 못할 수 있습니다.
ECAPA-TDNN 아키텍처
| 단계 | 설명 |
|---|---|
| TDNN | Time Delay Neural Network (128 → 512 채널, 커널 크기 5) |
| SE-Res2Net 블록 | Squeeze-and-Excitation이 있는 3개 블록 (512 채널, dilation 2/3/4) |
| MFA | Multi-layer Feature Aggregation (1536 채널 + ReLU) |
| ASP | Attentive Statistics Pooling (1536 채널, 시간에 대한 softmax) |
| FC | Fully connected 레이어 (3072 → 1024 차원) |
가중치(76 파라미터)는 Qwen3-TTS safetensors에 포함되어 있습니다 — 별도 다운로드가 필요 없습니다.
CLI 사용법
# CosyVoice3 음성 복제 (CAM++, CoreML Neural Engine)
.build/release/audio speak "Text in the cloned voice" \
--engine cosyvoice --voice-sample reference.wav -o output.wav
# Qwen3-TTS 음성 복제 (ECAPA-TDNN, MLX GPU)
.build/release/audio speak "Text in the cloned voice" \
--voice-sample reference.wav -o output.wav
예시
# CosyVoice3: 다언어 음성 복제 (9개 언어)
.build/release/audio speak "Hello, this is my cloned voice." \
--engine cosyvoice --voice-sample my_voice.wav -o cloned_hello.wav
# CosyVoice3: 다른 언어로 음성 복제
.build/release/audio speak "Guten Tag, das ist meine geklonte Stimme." \
--engine cosyvoice --voice-sample my_voice.wav --language german -o german.wav
# Qwen3-TTS: 영어 음성 복제
.build/release/audio speak "The quick brown fox jumps over the lazy dog." \
--voice-sample recording_15s.wav -o cloned_fox.wav
다화자 대화
CosyVoice3는 화자별 음성 복제가 적용된 다화자 대화를 지원합니다. --speakers 플래그를 사용해 화자 태그를 레퍼런스 오디오 파일에 매핑하세요:
# 음성 복제가 적용된 두 화자 대화
.build/release/audio speak "[S1] Hello there! [S2] Hey, how are you?" \
--engine cosyvoice --speakers s1=alice.wav,s2=bob.wav -o dialogue.wav
# 감정 태그 + 음성 복제가 적용된 대화
.build/release/audio speak "[S1] (happy) Great news! [S2] (surprised) Really? Tell me more." \
--engine cosyvoice --speakers s1=alice.wav,s2=bob.wav -o emotional_dialogue.wav
# 턴 사이 침묵 조정
.build/release/audio speak "[S1] First line. [S2] Second line." \
--engine cosyvoice --speakers s1=a.wav,s2=b.wav --turn-gap 0.5 -o gapped.wav
각 화자의 레퍼런스 오디오는 CAM++ 인코더를 통해 처리되어 192차원 임베딩이 추출됩니다. 모델은 한 번 로드되고 모든 화자에 재사용됩니다. 대화 문법과 감정 태그의 자세한 내용은 CosyVoice3 가이드를 참조하세요.
레퍼런스 오디오 팁
- 지속 시간: 5 ~ 15초의 음성이 가장 좋습니다. 더 짧은 클립은 충분한 음성 특성을 포착하지 못할 수 있으며, 더 긴 클립은 체감 향상이 줄어듭니다.
- 단일 화자: 레퍼런스는 한 화자만 포함해야 합니다. 다화자 오디오는 예측할 수 없는 결과를 생성합니다.
- 깨끗한 오디오: 배경 잡음, 음악, 반향을 최소화하세요. 복제 전에 잡음 레퍼런스를 정리하려면 음성 향상 모듈을 사용하세요.
- 자연스러운 음성: 속삭임, 고함, 노래보다는 대화체의 자연스러운 음성을 사용하세요.
Qwen3-TTS에서 음성 복제는 base 모델에서만 동작합니다 — customVoice에서는 동작하지 않습니다. CosyVoice3 음성 복제는 기본 모델과 함께 동작합니다.
Swift API
import CosyVoiceTTS
// CosyVoice3 음성 복제
let model = try await CosyVoiceTTSModel.fromPretrained()
let speaker = try await CamPlusPlusSpeaker.fromPretrained()
// 레퍼런스 오디오에서 192차원 화자 임베딩 추출
let embedding = try speaker.embed(audio: refSamples, sampleRate: 16000)
// 복제된 음성으로 합성
let audio = model.synthesize(
text: "Hello in a cloned voice!",
speakerEmbedding: embedding
)
// 커스텀 지시문 + 화자 임베딩
let styledAudio = model.synthesize(
text: "Hello!",
instruction: "Speak happily and with excitement.",
speakerEmbedding: embedding
)
// 다화자 대화
let segments = DialogueParser.parse("[S1] (happy) Hi! [S2] Hey there.")
let embeddings = ["S1": aliceEmbedding, "S2": bobEmbedding]
let dialogueAudio = DialogueSynthesizer.synthesize(
segments: segments,
speakerEmbeddings: embeddings,
model: model,
language: "english"
)
import Qwen3TTS
// Qwen3-TTS 음성 복제
let model = try await Qwen3TTSModel.fromPretrained()
let audio = model.synthesizeWithVoiceClone(
text: "Hello in a cloned voice!",
referenceAudio: refSamples,
referenceSampleRate: 24000
)