Написать в Telegram@Odilient

ИИ И АВТОМАТИЗАЦИЯ

ИИ-аудиокниги Knigopoisk

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

Knigopoisk
Клиент
Книги и издательское дело
Отрасль
В развитии с 2026 года
Срок
2026
Год
С чего всё началось

Задача

Knigopoisk продаёт аудиоверсии книг, у которых ещё нет записи, а живые дикторы не масштабируются на длинный хвост русскоязычного каталога. Русский язык сложен для синтеза речи: ударение меняет смысл, в печатном тексте обычно пропускают букву ё, а некоторые модели галлюцинируют или выдают бессмыслицу. Выбор движка означал баланс между качеством, скоростью на одном CPU и условиями лицензии, а целая книга — это от десятков до сотен медленных вызовов синтеза, любой из которых может упасть.

Что мы сделали

Решение

Мы сравнили дюжину TTS-движков с поддержкой русского, опенсорсных и облачных, с ASR-проверкой на бессмыслицу, а затем построили пайплайн на очередях Laravel: извлечь текст, детерминированно его очистить, по желанию дать LLM найти мусор, характерный для конкретной книги, и назначить голоса персонажам, синтезировать, закодировать и опубликовать MP3 с ID3-тегами. Задачи продолжают работу с закэшированных сегментов, помечают дубли с тишиной или шумом и запускаются автоматически, когда кто-то покупает аудиокнигу без файла. Массовой озвучке на продакшене предшествовала проверка на пяти книгах.

Технологии
LaravelPythonGoogle GeminiDeepSeekFFmpegFilamentMySQLDocker
За кулисами

Как всё создавалось

ИИ-генерация аудиокниг для русскоязычного книжного магазина

Для Knigopoisk — русскоязычного магазина электронных книг и аудиокниг — мы построили пайплайн ИИ-генерации аудиокниг, который превращает цифровое издание в готовый товар-аудиокнигу: извлечение и очистка текста, голоса персонажей по желанию, синтез речи, кодирование в MP3, проставление тегов и публикация в каталоге. Сотрудники запускают его из админ-панели, а ещё он стартует автоматически, когда покупатель оплачивает аудиокнигу, для которой пока нет аудиофайла.

Шаг первый: бенчмарк русского TTS

Прежде чем писать код пайплайна, мы сравнили движки синтеза русской речи на железе без GPU: видеокарты Quadro T2000 на 4 ГБ не хватало для инференса крупных моделей. Один и тот же короткий русский фрагмент прошёл через движки, заточенные под русский язык (F5-TTS Russian, ESpeech, Silero v5, Vosk-TTS, Piper), мультиязычные модели (CosyVoice3, Chatterbox, VibeVoice, XTTS-v2, Bark) и облачные эталоны, в том числе Gemini 2.5 TTS. Для каждого мы записывали голоса, время синтеза и лицензию.

Три вывода определили то, что мы в итоге построили:

  • Ударения важны. С помощью RUAccent мы сделали копию фрагмента с расставленными ударениями и провели на ней A/B-тесты движков. ESpeech оказался первым движком в наборе, который действительно понимал знаки ударения +, а не зачитывал их вслух и не пропускал.
  • Проверка громкости не ловит тарабарщину. CosyVoice2 не поддерживает русский и выдаёт речь из случайных звуков, которая на индикаторе уровня выглядит совершенно нормально, тогда как CosyVoice3 работает. Чтобы ловить неразборчивый результат, мы добавили оценку полноты распознанных слов через Vosk ASR.
  • Скорость и лицензии сильно различаются. Silero и Piper озвучили фрагмент примерно за пять секунд на CPU, а F5-TTS Russian понадобился около часа; к тому же у нескольких моделей с лучшим звучанием некоммерческие лицензии.

Архитектура продакшен-пайплайна

Задачи генерации с возобновлением

Каждый рендер — это запись о генерации, которая проходит статусы pending → extracting → generating → encoding → done, с прогрессом и оценкой оставшегося времени в админке Filament. За одной и той же моделью стоят два движка: путь через Gemini TTS, который синтезирует текст по фрагментам в сырой PCM и кодирует его в один MP3 через FFmpeg, и собственный сервис рендеринга на Python, которым управляют по HTTP и который выдаёт по MP3 на главу. Прогресс сохраняется после каждого фрагмента, длинные запуски сами перезапускают себя до того, как очередь оборвёт их по тайм-ауту, а повторно отправленная задача продолжает работу с закэшированных сегментов. Пока не озвучена вся книга, ничего не публикуется.

Подготовка текста и распределение ролей

Детерминированный очиститель убирает номера страниц, колонтитулы, подписи, строки оглавления и знаки сносок, исправляет переносы, заново собирает абзацы и по словарю восстанавливает букву ё. Необязательный шаг аудита показывает DeepSeek небольшой фрагмент книги, а найденные им шаблоны мусора применяются ко всему тексту уже на PHP — так расходы на ИИ ограничиваются одним дешёвым вызовом независимо от объёма книги. Для озвучки на несколько голосов LLM разбивает прозу на реплики говорящих, а голоса назначаются персонажам по определённому полу; при любом сбое система возвращается к обычному чтению одним голосом.

Контроль качества и выдача

Для каждой генерации считается, сколько сегментов пришлось заменить тишиной и сколько так и остались с шумом после повторов, поэтому рендер с предупреждениями отправляется на прослушивание. Поглавный рендер, который получился неправдоподобно коротким для своего количества слов, отклоняется как обрезанный: его не публикуют, покупателю не отправляют письмо, а команда получает уведомление в Telegram. Готовые файлы содержат ID3-теги и обложку.

Автоматизация и запуск

Когда заказ переходит в статус «оплачен», слушатель в очереди запускает озвучку одним голосом, привязанную ровно к тому товару, который купил покупатель, а покупатель получает письмо, когда аудиокнига готова. Каждая проверка идемпотентна, поэтому одна и та же точка входа обслуживает слушатель оплаченных заказов, ночную догенерацию оплаченных аудиокниг, у которых всё ещё нет файлов, повторные попытки и ассистента в админке. По умолчанию книга, которая трижды подряд завершилась ошибкой, остаётся человеку.

Запуск проходил поэтапно. Сначала на продакшене прошла проверочная партия из пяти генераций под присмотром скрипта-наблюдателя: он выпускал остальную очередь только после того, как рендер завершался с полным прикреплённым аудиофайлом, и останавливался при первом же сбое. Затем более широкая догенерация шла под монитором, который показывал число активных, завершённых и упавших задач и останавливал процесс, если ошибок становилось больше порога. Ежечасная задача удерживает рабочее пространство рендеринга в пределах срока хранения и лимита по объёму.

Смежные работы

Этот пайплайн — часть нашей работы по внедрению ИИ и автоматизации для Knigopoisk. Смотрите также пайплайн крупного шрифта и Telegram-уведомления о заказах, которые сообщают о неудачных рендерах.

Создадим вместе

Хотите что-то вроде ИИ-аудиокниги Knigopoisk?

Расскажите, что должен делать ваш продукт. Мы определим объём работ, распишем сроки и пришлём фиксированную цену — бесплатно и без обязательств продолжать.

Бесплатная консультация Без обязательств Быстрый ответ