Клонирование голоса
Клонирование любого голоса из короткого референсного аудиосэмпла. И Qwen3-TTS, и CosyVoice3 поддерживают клонирование голоса с разными speaker-энкодерами — ECAPA-TDNN (1024-мерный) и CAM++ (192-мерный) соответственно.
Как это работает
- Запишите или предоставьте референсный аудиосэмпл целевого голоса
- Извлечение эмбеддинга спикера — speaker-энкодер обрабатывает референсное аудио в вектор эмбеддинга фиксированной размерности
- Внедрение эмбеддинга — эмбеддинг спикера обуславливает TTS-модель во время синтеза
- Синтез речи — TTS-модель генерирует речь, соответствующую вокальным характеристикам референса
Движки
Клонирование голоса доступно с обоими TTS-движками. Каждый использует свой speaker-энкодер:
| Движок | Speaker-энкодер | Эмбеддинг | Бэкенд |
|---|---|---|---|
| Qwen3-TTS | ECAPA-TDNN | 1024-мерный x-vector | MLX (GPU) |
| CosyVoice3 | CAM++ | 192-мерный | CoreML (Neural Engine) |
CosyVoice3 + CAM++
CosyVoice3 использует speaker-энкодер CAM++ (Context-Aware Masking++) из проекта 3D-Speaker от Alibaba. 192-мерный эмбеддинг обуславливает flow-модель DiT через аффинный проекционный слой (192 → 80), который обучен совместно с CosyVoice3.
Архитектура CAM++
| Этап | Описание |
|---|---|
| FCM | Front-end свёрточный модуль (Conv2d + 2 ResBlocks, 32 канала) |
| TDNN | Time Delay Neural Network (320 в 128 каналов, kernel size 5) |
| D-TDNN-блоки | 3 плотно связанных блока (12/24/16 слоёв) с context-aware masking |
| Stats Pool | Пулинг среднего + стандартного отклонения (глобальная статистика) |
| Dense | Линейная проекция в 192-мерный эмбеддинг |
CoreML-модель (~14 МБ, FP16) работает на Neural Engine. Она автоматически скачивается из aufklarer/CamPlusPlus-Speaker-CoreML при первом использовании.
Клонирование голоса в Qwen3-TTS
Qwen3-TTS поддерживает два режима клонирования голоса:
Режим ICL (рекомендуется)
Режим In-Context Learning кодирует референсное аудио в codec-токены через энкодер Mimi speech-токенизатора и добавляет их перед референсным транскриптом. Это даёт модели полный акустический контекст — выше качество и надёжный 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
Использует энкодер ECAPA-TDNN, выдающий 1024-мерный x-vector. Транскрипт не нужен, но качество ниже. Может не выдать EOS на коротких текстах или некоторых языках.
Архитектура ECAPA-TDNN
| Этап | Описание |
|---|---|
| TDNN | Time Delay Neural Network (128 в 512 каналов, kernel size 5) |
| SE-Res2Net-блоки | 3 блока со Squeeze-and-Excitation (512 каналов, dilation 2/3/4) |
| MFA | Multi-layer Feature Aggregation (1536 каналов + ReLU) |
| ASP | Attentive Statistics Pooling (1536 каналов, softmax по времени) |
| FC | Полносвязный слой (3072 в 1024 измерения) |
Веса (76 параметров) включены в safetensors Qwen3-TTS — отдельная загрузка не требуется.
Использование 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
)