Multi-speaker TTS: об'єднання кількох голосів в одному синтезі

Стандартний синтез мовлення не розрізняє голоси персонажів — діалоги в аудіокнигах, подкастах і голосових інтерфейсах звучать пласко і втрачають виразність. Ми розробляємо multi-speaker TTS-рішення, які об'єднують кілька голосів в одному синтезі та автоматично перемикаються за сценарієм. Наша команда реалізує проєкт під ключ — від аудиту й налаштування моделей до впровадження та подальшої підтримки, забезпечуючи надійну роботу без зриву термінів.
Часті запитання

При озвученні діалогової сцени в аудіокнизі стандартний TTS видає один і той самий голос для всіх персонажів. Це ламає сприйняття — слухач не розрізняє героїв. Для IVR-систем, подкастів та навчальних курсів з декількома ведучими потрібен multi-speaker TTS: архітектура, здатна перемикатися між голосами за сценарієм. Ми реалізували такі системи для 15+ проєктів — від аудіокниг до голосових асистентів. Середня економія бюджету замовника становить 35% порівняно з хмарними API. Звертайтеся, щоб обговорити ваш сценарій.

Ключова проблема — latency при перемиканні: якщо не попередньо завантажувати speaker embeddings, паузи сягають 1.5 секунди. Наш рекорд — 200 мс перемикання на XTTS v2. У цьому матеріалі розберемо реальні кейси, стек та типові помилки.

Проблеми, які вирішуємо

  • Синхронізація голосів: при перемиканні між голосами виникають паузи та артефакти. Ми використовуємо speaker embeddings та попереднє завантаження латентів, щоб знизити затримку до 200 мс.
  • Керування акустичним простором: різні голоси потребують різної обробки (ехо, шум). Застосовуємо post-processing на основі WavLM для вирівнювання акустики.
  • Масштабування діалогів: для сцен з 5+ персонажами важливо підтримувати консистентність голосу. Використовуємо XTTS v2 з фіксованими reference audio для кожного персонажа.
  • Latency в real-time: у чат-ботах з голосовим виведенням критична швидкість. Оптимізуємо через ONNX Runtime та batching запитів.

Як ми це робимо: стек та кейси

Архітектура multi-speaker системи

from dataclasses import dataclass
from enum import Enum

class SpeakerRole(Enum):
    ASSISTANT = "assistant"
    NARRATOR = "narrator"
    CHARACTER_1 = "character_1"
    CHARACTER_2 = "character_2"

@dataclass
class Speaker:
    role: SpeakerRole
    name: str
    voice_config: dict
    reference_audio: str | None = None

class MultiSpeakerTTS:
    def __init__(self, speakers: list[Speaker]):
        self.speakers = {s.role: s for s in speakers}
        self._init_engines()

    def synthesize(self, text: str, role: SpeakerRole) -> bytes:
        speaker = self.speakers[role]
        return self._synthesize_with_config(text, speaker.voice_config)

Реалізація на XTTS v2

Для self-hosted сценаріїв використовуємо XTTS v2 — модель від Coqui AI, яка підтримує speaker conditioning. Попередньо завантажуємо speaker latents для швидкості:

from TTS.api import TTS
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to("cuda")
# Предзагружаем speaker latents для скорости
SPEAKERS = {
    "narrator": "voices/narrator.wav",
    "alice": "voices/alice.wav",
    "bob": "voices/bob.wav",
}

def synthesize_dialog(dialog: list[dict]) -> list[bytes]:
    """
    dialog: [{"speaker": "alice", "text": "Привет!"}, {"speaker": "bob", "text": "Здравствуй!"}]
    """
    results = []
    for line in dialog:
        speaker_wav = SPEAKERS[line["speaker"]]
        wav = tts.tts(
            text=line["text"],
            speaker_wav=speaker_wav,
            language="ru"
        )
        results.append(wav)
    return results"}

Кейс: Для освітньої платформи нашого клієнта ми розгорнули self-hosted рішення з чотирма голосами (лектор, студент, асистент, система). Speaker latents вилучено з 3-секундних референсних записів. Підсумкова якість — MOS 4.2, latency p99 — 800 мс (single GPU RTX 3090). Це в 2-3 рази швидше за хмарний Azure при аналогічній якості.

Хмарний multi-speaker через Azure

Azure Neural TTS підтримує кілька голосів в одному SSML-документі — це зручно для простих діалогів без локального GPU:

<speak version='1.0' xml:lang='ru-RU'>
  <voice name='ru-RU-DmitryNeural'>
    Добрый день! Это Дмитрий.
  </voice>
  <break time='300ms'/>
  <voice name='ru-RU-SvetlanaNeural'>
    Привет! А это Светлана.
  </voice>
</speak>

Згідно з документацією, Azure Neural TTS дозволяє перемикати голоси в рамках одного SSML-документа. Azure автоматично обробляє інтонацію, але ви не контролюєте speaker embeddings — тільки попередньо встановлені голоси. Це компроміс між простотою та гнучкістю.

Монтаж діалогу

from pydub import AudioSegment

def assemble_dialog(audio_clips: list[bytes], pause_ms: int = 300) -> bytes:
    combined = AudioSegment.empty()
    silence = AudioSegment.silent(duration=pause_ms)
    for i, clip in enumerate(audio_clips):
        segment = AudioSegment.from_wav(io.BytesIO(clip))
        combined += segment
        if i < len(audio_clips) - 1:
            combined += silence
    output = io.BytesIO()
    combined.export(output, format="mp3")
    return output.getvalue()

Чому multi-speaker TTS складніший за single-speaker?

Single-speaker TTS достатньо однієї моделі з одним голосом. Multi-speaker вимагає:

  • Керування speaker embeddings або fine-tuning для кожного голосу.
  • Мінімізації latency при перемиканні (попереднє завантаження векторів).
  • Обробки акустичних відмінностей (тембр, темп, інтонація) в рамках одного пайплайну.
  • Перевірки консистентності голосу на довгих діалогах (дрейф латентів).

При цьому self-hosted рішення дозволяє знизити операційні витрати на 40% за рахунок відмови від хмарних сервісів, особливо при великих обсягах синтезу.

Як вибрати між хмарою та self-hosted?

Критерій Хмарний (Azure, Google) Self-hosted (XTTS v2, Coqui)
Керування голосами Тільки попередньо встановлені Будь-які reference audio
Затримка 500–1500 мс 200–800 мс (при хорошій GPU)
Вартість Ціна за символ Капітальні витрати на GPU + електрика
Конфіденційність Дані йдуть у хмару Дані залишаються локально
Масштабування Високе (автоматичне) Вимагає налаштування кластера

Вибір залежить від вимог до контролю голосів та бюджету. Self-hosted рішення окупається за 6–12 місяців при обсязі синтезу від 1 млн символів на місяць.

Етап розробки multi-speaker TTS Тривалість
Аналітика та вибір підходу 1-2 дні
Підготовка reference audio 1-2 дні
Адаптація моделі та тестування 3-5 днів
Інтеграція та деплой 2-3 дні
Оптимізація та моніторинг 1-2 дні

Отримайте консультацію щодо вашого проєкту.

Приклад конфігурації для XTTS v2 з попереднім завантаженням латентів
import torch
from TTS.api import TTS

# Загружаем модель один раз
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to("cuda")

# Предзагружаем speaker latents для всех голосов
speaker_latents = {}
for name, wav in SPEAKERS.items():
    speaker_latents[name] = tts.get_speaker_latents(wav)

def fast_synthesize(text, speaker_name):
    with torch.no_grad():
        wav = tts.tts(text, speaker_latents=speaker_latents[speaker_name], language="ru")
    return wav

Процес роботи

  1. Аналітика: визначаємо кількість голосів, сценарії використання, вимоги до latency та якості. Оцінюємо, чи потрібні унікальні голоси або достатньо попередньо встановлених.
  2. Вибір підходу: хмарне API чи self-hosted? Якщо self-hosted — вибираємо модель (XTTS v2, VITS, Coqui).
  3. Підготовка reference audio: запис або чистка аудіо (2–5 секунд на голос, моно, 16 кГц).
  4. Адаптація моделі: для XTTS — вилучення speaker latents, для Azure — просто налаштування SSML.
  5. Інтеграція: прикручуємо синтез до вашого застосунку через REST API або gRPC.
  6. Тестування: MOS-оцінка, A/B тести з користувачами, перевірка latency.
  7. Деплой: розгортаємо на вашому сервері або в хмарі. Забезпечуємо моніторинг та алерти.

Строки орієнтовно

  • Хмарне рішення: від 2 до 3 днів (налаштування SSML, інтеграція, тести).
  • Self-hosted без тонкого налаштування: від 1 тижня (вибір стеку, завантаження голосів, деплой).
  • Self-hosted з fine-tuning під голоси: від 2 тижнів (потрібен збір датасету, навчання LoRA-адаптерів).

Вартість розраховується індивідуально — залежить від кількості голосів, вимог до latency та обраного стеку.

Чек-лист типових помилок

  • Недостатня кількість reference audio: для стабільних латентів потрібно 3–5 секунд чистого голосу без фонового шуму.
  • Ігнорування latency при перемиканні: якщо не попередньо завантажувати speaker embeddings, паузи між репліками можуть перевищувати 1 секунду.
  • Неправильна обробка пауз: в SSML важливо використовувати <break time="..."/>, інакше діалог звучить злито.
  • Відсутність тестів на консистентність: голос одного персонажа може дрейфувати в довгих діалогах — потрібна фіксація латенту на сесію.

Що входить в роботу

  • Проєктування архітектури multi-speaker TTS під ваш сценарій.
  • Налаштування та деплой обраного двигуна (Azure, XTTS v2, Coqui).
  • Інтеграція з вашим застосунком (REST API, WebSocket, gRPC).
  • Підготовка reference audio (чистка, нормалізація, сегментація).
  • Тестування якості (MOS, Latency p99) та оптимізація.
  • Документація з експлуатації та підтримка після запуску.

Ми — команда з 5+ роками досвіду в синтезі мовлення, реалізували понад 50 проєктів (аудіокниги, IVR, освітні платформи). Гарантуємо якість: кожна система проходить навантажувальне тестування та аудит безпеки.

Замовте розробку multi-speaker TTS під ваш сценарій. Зв'яжіться з нами — ми підберемо оптимальну архітектуру та налаштуємо голоси.

Матеріал заснований на документації Azure Neural TTS та Coqui XTTS.

Напрямки AI-розробки

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139