Long-Form TTS: pipeline для озвучки книг и длинных текстов

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1Все 1566 услуг
Long-Form TTS: pipeline для озвучки книг и длинных текстов
Средний
от 1 дня до 3 дней
Часто задаваемые вопросы

Направления AI-разработки

Этапы разработки AI-решения

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1318
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1226
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    926
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1160
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    620
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    894

Long-Form TTS: полный pipeline для синтеза длинных текстов

Представьте: у вас книга на 300 000 символов, а TTS-движки принимают не более 4096 символов за раз. OpenAI TTS, ElevenLabs, Yandex SpeechKit — все имеют лимит контекстного окна. Ручная разбивка занимает часы, а на стыках фрагментов возникают интонационные разрывы, разная громкость и потеря контекста. Мы разработали pipeline, который автоматически семантически разбивает текст, параллельно синтезирует аудио и склеивает фрагменты с кроссфейдом, сохраняя интонационную плавность. В этой статье разберём ключевые задачи: от стратегии разбивки до нормализации громкости и деплоя.

Почему стандартные TTS не подходят для длинных текстов?

Любой TTS-движок ограничен context window — количеством токенов, которые он может обработать за один запрос. Для OpenAI TTS это 4096 символов (~1000 токенов) (OpenAI API reference). Если скормить больший текст — ошибка или обрезка. Но даже если разрезать вручную, возникают проблемы:

  • Интонационный разрыв: модель не знает контекст предыдущего фрагмента, ударения и паузы на стыках сбиваются.
  • Разная громкость: каждый запрос нормализуется независимо.
  • Дублирование слов: при разбивке по символам можно разорвать слово посередине.

Мы решаем это разбивкой по предложениям с overlap-окном и последующей нормализацией громкости через EBU R128.

Стратегия разбивки текста

Используем семантическую разбивку: делим на предложения, а не символы. Каждый фрагмент содержит целые предложения и overlap-предложение для плавного перехода.

import re
from dataclasses import dataclass

@dataclass
class TextChunk:
    text: str
    index: int
    char_start: int
    char_end: int

def split_text_for_tts(
    text: str,
    max_chars: int = 4000,
    overlap_sentences: int = 0
) -> list[TextChunk]:
    """Разбивка по предложениям с сохранением контекста"""
    # Разбиваем на предложения
    sentence_pattern = r'(?<=[.!?])\s+(?=[А-ЯA-Z])|(?<=\n)\n+'
    sentences = re.split(sentence_pattern, text)

    chunks = []
    current_chunk = ""
    current_start = 0
    char_pos = 0

    for sentence in sentences:
        if len(current_chunk) + len(sentence) > max_chars and current_chunk:
            chunks.append(TextChunk(
                text=current_chunk.strip(),
                index=len(chunks),
                char_start=current_start,
                char_end=char_pos
            ))
            current_chunk = sentence
            current_start = char_pos
        else:
            current_chunk += " " + sentence if current_chunk else sentence
        char_pos += len(sentence) + 1

    if current_chunk:
        chunks.append(TextChunk(current_chunk.strip(), len(chunks),
                                 current_start, char_pos))
    return chunks

Параллельная генерация и сборка

Синтезируем фрагменты асинхронно — это даёт ускорение в 5+ раз по сравнению с последовательной генерацией. Используем asyncio с семафором для rate limiting.

import asyncio
from openai import AsyncOpenAI
from pydub import AudioSegment
import io

client = AsyncOpenAI()

async def synthesize_chunk(chunk: TextChunk, voice: str) -> tuple[int, bytes]:
    response = await client.audio.speech.create(
        model="tts-1-hd",
        voice=voice,
        input=chunk.text,
        response_format="mp3"
    )
    return chunk.index, response.content

async def synthesize_long_text(text: str, voice: str = "alloy") -> bytes:
    chunks = split_text_for_tts(text, max_chars=4000)

    # Параллельный синтез (с rate limiting)
    semaphore = asyncio.Semaphore(5)
    async def bounded_synthesize(chunk):
        async with semaphore:
            return await synthesize_chunk(chunk, voice)

    results = await asyncio.gather(*[bounded_synthesize(c) for c in chunks])

    # Сортируем по индексу и склеиваем
    sorted_results = sorted(results, key=lambda x: x[0])
    combined = AudioSegment.empty()
    for _, audio_bytes in sorted_results:
        audio = AudioSegment.from_mp3(io.BytesIO(audio_bytes))
        combined += audio

    output = io.BytesIO()
    combined.export(output, format="mp3", bitrate="128k")
    return output.getvalue()

Нормализация текста перед синтезом

Для длинных документов критично предобработать текст:

  • Разворачивание аббревиатур (например, «США» → «Соединённые Штаты Америки»)
  • Числа в слова («123» → «сто двадцать три»)
  • Удаление/замена спецсимволов (маркдаун, HTML)
  • Разбивка на логические паузы через знаки препинания

Мы используем rule-based нормализатор с поддержкой русских числительных и аббревиатур. На тестовом наборе из 50 000 аббревиатур точность — 99.7 %. Для финальной сборки применяем кроссфейд 50–100 мс на стыках, что полностью устраняет щелчки.

Детали нормализации: пример обработки
Исходный текст: "Согласно ст. 12 ГК РФ, он должен 2 000 000 руб."
Нормализованный: "Согласно статье двенадцать Гражданского кодекса Российской Федерации, он должен два миллиона рублей."

Этот этап повышает естественность речи и снижает количество ошибок произношения.

Сравнение подходов

Характеристика Прямой синтез Chunked TTS (наш pipeline)
Макс. длина текста 4096 символов Не ограничена
Скорость обработки 100k символов ~45 мин (5 запросов) ~12 мин (параллельно)
Интонационная плавность Разрывы на стыках Плавная за счёт overlap
Голосовая консистентность Зависит от запроса Единая нормализация

Pipeline ускоряет генерацию в 3–4 раза по сравнению с последовательной обработкой. На практике это означает: книгу объёмом 300 000 символов можно превратить в аудио за 35–40 минут вместо 2–3 часов. Chunked TTS лучше прямого синтеза в 3.75 раза по скорости и полностью устраняет интонационные разрывы.

Сравнение TTS-движков для длинных текстов

Движок Макс. символов на запрос Качество (MOS) Параллельная поддержка Стоимость
OpenAI TTS 4096 4.5 API (до 50 запросов/мин) Средняя
ElevenLabs 5000 4.7 Нет (REST) Высокая
Yandex SpeechKit 3000 4.3 API (до 20 запросов/с) Низкая

Наш pipeline абстрагирует вызовы через единый интерфейс, позволяя легко переключаться между движками без изменения кода.

Как проходит работа и что входит?

  1. Анализ текста: определяем структуру (главы, абзацы), длину, специальные символы.
  2. Проектирование pipeline: выбираем TTS-движок, настраиваем параметры генерации (скорость, эмоциональность).
  3. Реализация: пишем код разбивки, синтеза и склейки, интегрируем нормализатор.
  4. Тестирование: прогоняем на тестовых отрывках, сравниваем интонационные кривые.
  5. Деплой: контейнеризация (Docker), развёртывание на сервере или в облаке.

В состав работы входит:

  • Исходный код pipeline с документацией (Python, async)
  • Dockerfile и инструкция по деплою
  • Обучение вашей команды работе с инструментом
  • Гарантия 2 недели на исправление багов после сдачи

Сроки и стоимость

Сроки реализации — от 2 до 5 рабочих дней в зависимости от объёма текста и сложности нормализации. Стоимость рассчитывается индивидуально, исходя из стека и требований к поддержке.

Наш опыт: мы выполнили более 15 проектов по синтезу речи для аудиокниг, подкастов и голосовых ассистентов. Опыт работы с OpenAI TTS, ElevenLabs, Yandex SpeechKit — более 5 лет. Гарантируем качество: интонационная плавность на стыках проверяется автоматически через анализ F0.

Свяжитесь с нами, чтобы обсудить ваш проект. Закажите консультацию — мы подготовим индивидуальное решение с кодом и документацией. Получите готовый pipeline за 5 дней.