Clonación de voz
Clona cualquier voz a partir de una muestra breve de audio de referencia. Tanto Qwen3-TTS como CosyVoice3 soportan clonación de voz con distintos encoders de hablante — ECAPA-TDNN (1024 dim) y CAM++ (192 dim) respectivamente.
Cómo funciona
- Graba o proporciona una muestra de audio de referencia de la voz objetivo
- Extracción del embedding de hablante — un encoder de hablante procesa el audio de referencia para obtener un vector de embedding de dimensión fija
- Inyección del embedding — el embedding del hablante condiciona al modelo TTS durante la síntesis
- Síntesis de voz — el modelo TTS genera voz que coincide con las características vocales de la muestra de referencia
Motores
La clonación de voz está disponible con ambos motores TTS. Cada uno utiliza un encoder de hablante distinto:
| Motor | Encoder de hablante | Embedding | Backend |
|---|---|---|---|
| Qwen3-TTS | ECAPA-TDNN | x-vector de 1024 dim | MLX (GPU) |
| CosyVoice3 | CAM++ | 192 dim | CoreML (Neural Engine) |
CosyVoice3 + CAM++
CosyVoice3 usa el encoder de hablante CAM++ (Context-Aware Masking++) del proyecto 3D-Speaker de Alibaba. El embedding de 192 dim condiciona el modelo DiT flow mediante una capa de proyección afín (192 → 80) entrenada conjuntamente con CosyVoice3.
Arquitectura de CAM++
| Etapa | Descripción |
|---|---|
| FCM | Módulo convolucional frontal (Conv2d + 2 ResBlocks, 32 canales) |
| TDNN | Time Delay Neural Network (de 320 a 128 canales, kernel de tamaño 5) |
| Bloques D-TDNN | 3 bloques densamente conectados (12/24/16 capas) con context-aware masking |
| Stats Pool | Pooling de media + desviación estándar (estadísticas globales) |
| Dense | Proyección lineal a un embedding de 192 dim |
El modelo CoreML (~14 MB, FP16) se ejecuta en el Neural Engine. Se descarga automáticamente desde aufklarer/CamPlusPlus-Speaker-CoreML en el primer uso.
Clonación de voz con Qwen3-TTS
Qwen3-TTS soporta dos modos de clonación de voz:
Modo ICL (recomendado)
El modo In-Context Learning codifica el audio de referencia en tokens de codec mediante el encoder del tokenizador de voz Mimi y los antepone a la transcripción de referencia. Esto proporciona al modelo un contexto acústico completo — mayor calidad y EOS fiable (soluciona los problemas con textos cortos e idiomas distintos del inglés).
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
)
Modo X-Vector
Usa un encoder ECAPA-TDNN que produce un x-vector de 1024 dim. No requiere transcripción pero ofrece menor calidad. Puede fallar al emitir EOS en textos cortos o en ciertos idiomas.
Arquitectura de ECAPA-TDNN
| Etapa | Descripción |
|---|---|
| TDNN | Time Delay Neural Network (de 128 a 512 canales, kernel de tamaño 5) |
| Bloques SE-Res2Net | 3 bloques con Squeeze-and-Excitation (512 canales, dilatación 2/3/4) |
| MFA | Multi-layer Feature Aggregation (1536 canales + ReLU) |
| ASP | Attentive Statistics Pooling (1536 canales, softmax sobre el tiempo) |
| FC | Capa totalmente conectada (de 3072 a 1024 dimensiones) |
Los pesos (76 parámetros) están incluidos en los safetensors de Qwen3-TTS — no requiere descarga adicional.
Uso de la CLI
# CosyVoice3 voice cloning (CAM++, CoreML Neural Engine)
.build/release/audio speak "Text in the cloned voice" \
--engine cosyvoice --voice-sample reference.wav -o output.wav
# Qwen3-TTS voice cloning (ECAPA-TDNN, MLX GPU)
.build/release/audio speak "Text in the cloned voice" \
--voice-sample reference.wav -o output.wav
Ejemplos
# CosyVoice3: multilingual voice cloning (9 languages)
.build/release/audio speak "Hello, this is my cloned voice." \
--engine cosyvoice --voice-sample my_voice.wav -o cloned_hello.wav
# CosyVoice3: clone voice in a different language
.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: English voice cloning
.build/release/audio speak "The quick brown fox jumps over the lazy dog." \
--voice-sample recording_15s.wav -o cloned_fox.wav
Diálogo multi-hablante
CosyVoice3 soporta diálogos multi-hablante con clonación de voz por hablante. Usa el flag --speakers para mapear las etiquetas de hablante a archivos de audio de referencia:
# Two-speaker dialogue with voice cloning
.build/release/audio speak "[S1] Hello there! [S2] Hey, how are you?" \
--engine cosyvoice --speakers s1=alice.wav,s2=bob.wav -o dialogue.wav
# Dialogue with emotion tags + voice cloning
.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
# Adjust silence between turns
.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
El audio de referencia de cada hablante se procesa a través del encoder CAM++ para extraer un embedding de 192 dim. El modelo se carga una sola vez y se reutiliza para todos los hablantes. Consulta la guía de CosyVoice3 para obtener más detalles sobre la sintaxis de los diálogos y las etiquetas de emoción.
Consejos para el audio de referencia
- Duración: De 5 a 15 segundos de habla funcionan mejor. Los clips más cortos pueden no capturar suficientes características vocales; los más largos ofrecen retornos decrecientes.
- Un único hablante: La referencia debe contener solo un hablante. El audio multi-hablante producirá resultados impredecibles.
- Audio limpio: Minimiza el ruido de fondo, la música y la reverberación. Usa el módulo de mejora de voz para limpiar referencias ruidosas antes de clonar.
- Habla natural: Utiliza un habla conversacional y natural en lugar de susurros, gritos o canto.
Para Qwen3-TTS, la clonación de voz solo funciona con el modelo base — no con customVoice. La clonación de voz de CosyVoice3 funciona con el modelo por defecto.
API de Swift
import CosyVoiceTTS
// CosyVoice3 voice cloning
let model = try await CosyVoiceTTSModel.fromPretrained()
let speaker = try await CamPlusPlusSpeaker.fromPretrained()
// Extract 192-dim speaker embedding from reference audio
let embedding = try speaker.embed(audio: refSamples, sampleRate: 16000)
// Synthesize with cloned voice
let audio = model.synthesize(
text: "Hello in a cloned voice!",
speakerEmbedding: embedding
)
// With custom instruction + speaker embedding
let styledAudio = model.synthesize(
text: "Hello!",
instruction: "Speak happily and with excitement.",
speakerEmbedding: embedding
)
// Multi-speaker dialogue
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 voice cloning
let model = try await Qwen3TTSModel.fromPretrained()
let audio = model.synthesizeWithVoiceClone(
text: "Hello in a cloned voice!",
referenceAudio: refSamples,
referenceSampleRate: 24000
)