Автоматическое создание субтитров для пользовательского контента может выглядеть довольно простой задачей: берем готовую ASR‑модель, распознаем аудио из видео и сохраняем результат.
Именно таким и был наш первый MVP в RUTUBE — сервис на базе Whisper, который позволил быстро проверить гипотезу и запустить субтитры в production. Но очень быстро стало понятно, что между «распознать речь» и «сделать субтитры для всего контента» лежит огромный пласт работы.
Миллионы новых видео, ролики длиной до 24 часов, неизвестный язык, шумный пользовательский контент, требования к качеству текста и жесткие ограничения по скорости обработки — всё это превратило задачу из простого ASR в полноценную платформу с микросервисной архитектурой и собственной системой распознавания речи.
Меня зовут Дима Лукьянов, я лид команды обработки речи и аудио в RUTUBE TECH. В этой статье расскажу, как мы прошли путь от MVP на Whisper до собственной масштабируемой платформы с пропускной способностью около 1200 видео в час на один ASR и какие инженерные решения оказались ключевыми.
Зачем вообще нужны субтитры
На первый взгляд кажется, что субтитры — это небольшая функциональность для отдельной аудитории. Но на практике всё иначе: субтитры нужны гораздо большему числу людей, чем принято думать.
Во‑первых, они критичны:
-
для пользователей с нарушениями слуха,
-
для тех, кто смотрит видео без звука (метро, офис, поездки),
-
в шумной или, наоборот, слишком тихой обстановке,
-
и для контента, где субтитры требуются по закону.
Но есть и менее очевидная, хотя куда более важная часть:
субтитры — это текстовое представление видео.
А значит, они становятся источником для целого набора сервисов:
-
автогенерации названий и описаний,
-
тегирования и классификации,
-
полнотекстового поиска по видео,
-
ускорения модерации и автоматических проверок.
Когда появляется столько внутренних потребителей, требования к системе резко возрастают: нужна высокая скорость, стабильное качество и способность масштабироваться под большие объёмы трафика.
Требования к системе
Понимая, какую роль субтитры играют в платформе и какие сервисы на них опираются, мы сформулировали набор требований к системе распознавания речи:
-
Покрытие всего пользовательского контента (UGC).
Обрабатывать нужно всё — от вертикальных роликов до многочасовых записей стримов. -
Высокая скорость.
Целевой ориентир — не более 1 минуты обработки для видео продолжительностью ~15 минут.
Это критично, если на платформе ежедневно появляются десятки тысяч новых роликов. -
Качество распознавания.
Мы ориентировались на WER ~0.1–0.2 в среднем по домену. Ниже — лучше, выше — уже заметно пользователю. -
Пунктуация и капитализация.
Это must‑have для хорошей читаемости субтитров и для поиска по тексту. -
Масштабирование на другие языки.
Даже если сейчас язык один, архитектура должна позволять горизонтальное расширение.
MVP: «Давайте возьмем Whisper»
Наше первое решение было максимально простым:
-
Кладем ссылку на видео в очередь Kafka.
-
Worker забирает сообщение из очереди.
-
Извлекаем аудиодорожку из видео.
-
Отправляем её в ASR на базе Whisper.
-
По полученному распознаванию формируем файл субтитров.
Это позволило быстро получить рабочее решение, но уже на этапе пробной эксплуатации довольно быстро проявились проблемы. Вот основные:
1. Производительность
Мы использовали Faster Whisper для инференса и в однопоточном режиме получили около 30 видео/час на один инстанс.
Быстрый расчет показал, что для продакшена с ~1 млн видео в день потребуется порядка 1400 инстансов. Очевидно, это не вариант.
2. Ограничения Whisper
Модель сложно адаптировать под конкретный домен из‑за особенностей архитектуры:
-
отсутствует явный alignment между аудио и текстом;
-
ошибки носят генеративный характер и могут приводить к «галлюцинациям»;
-
компоненты нельзя улучшать независимо друг от друга.
В результате качество получалось нестабильным, особенно на сложном пользовательском контенте.
3. Монолит
Весь пайплайн был реализован внутри одного сервиса, что приводило к типичным проблемам:
-
последовательная обработка;
-
неэффективное использование ресурсов;
-
отсутствие гибкости;
-
невозможность переиспользовать результаты распознавания.
В итоге: MVP работает, но не масштабируется, так как. Whisper — отличная универсальная модель, но она не предназначена для высоконагруженного доменного продакшена.
Поэтому мы приняли решение полностью переработать архитектуру. На практике оказалось, что дешевле и предсказуемее построить собственный ASR pipeline, чем пытаться масштабировать исходное решение.
Архитектура production‑платформы
В продакшене мы разделили систему на две ключевые части: Speech Worker и ASR.
Speech Worker отвечает за управление задачами, интеграции с внешними сервисами и формирование финальных субтитров.
ASR занимается непосредственно распознаванием речи — превращением аудио в текст. Она состоит из двух основных компонентов:
-
ASR Backend, который выполняет предобработку и постобработку аудио, а также управляет сессиями распознавания;
-
Triton Inference Server, обеспечивающий GPU‑инференс модели.
Такое разделение позволило изолировать вычислительно тяжёлую часть (ASR) и независимо её масштабировать.
Как мы управляем задачами
В основе системы взаимодействия лежит Kafka — через неё проходят все задачи на обработку.
Обработка устроена следующим образом:
-
мы читаем сообщения из Kafka батчами;
-
каждое сообщение превращается в отдельную задачу (1 видео = 1 задача);
-
ограничиваем количество одновременно выполняемых задач;
-
при достижении лимита просто перестаём читать новые сообщения.
Ключевой момент — лимит параллельных задач определяется пропускной способностью ASR, как самого тяжёлого этапа обработки.
Это даёт простой и эффективный механизм масштабирования: если нужно увеличить пропускную способность, достаточно добавить новые инстансы ASR и поднять лимит параллельных задач.
Почему субтитры — это не просто текст
Субтитры часто воспринимают как обычный набор строк, но на самом деле это куда более сложная конструкция:
субтитры = текст + тайминги + читаемость
Любая ошибка заметна сразу:
-
если тайминги «плывут» — зритель теряет контекст;
-
если строки разбиты плохо — текст становится тяжёлым или даже бессмысленным.
Проблема читаемости
Неправильный перенос строки может исказить смысл, замедлить чтение, ухудшить восприятие фразы. Например:
❌
Он в итоге принял
решение начать всё сначала
«принял решение» — это единая конструкция.
✅
Он в итоге принял решение
начать всё сначала
Другой пример:
❌
Мы увеличили throughput
в двадцать раз по сравнению с прошлой системой
акцент («в двадцать раз») уехал на вторую строку.
✅
Мы увеличили throughput в двадцать раз
по сравнению с прошлой системой
Это может показаться незначительным, но именно из таких мелочей складывается пользовательский опыт.
Как мы это решали
Мы взяли за основу правила ручной верстки субтитров:
-
оптимальная длина строк,
-
корректные точки переноса слов,
-
комфортная скорость чтения,
-
время отображения текста на экране.
И построили собственный пайплайн, который включает:
-
формирование предложений,
-
разбиение фраз на строки,
-
корректировка таймингов.
Ключевой элемент здесь — NLP на базе Spacy: он анализирует слова в тексте и подсказывает, когда переносить слово, а когда это нарушит смысл или ритм чтения.
В итоге субтитры выглядят так, как будто их верстал человек, а не алгоритм.
ASR: где начались настоящие сложности
Оффлайн‑распознавание аудио в пользовательских видео оказалось значительно сложнее, чем казалось на первый взгляд. На практике нам пришлось работать с четырьмя ключевыми проблемами:
-
произвольная длина аудио (от секунд до десятков часов),
-
неизвестный язык,
-
отсутствие речи в части роликов,
-
шумы и артефакты самой разной природы.
Чтобы справиться с этим, мы собрали собственный ASR‑пайплайн, который состоит из трех больших этапов: предобработка аудио, инференс акустической модели и постобработка текста.
Предобработка
-
Подготовка аудио.
Экстракция аудио дорожки, ресемплинг, поддержка HLS/DASH. Всё это позволяет работать с любым входом и нормализовать сигнал. -
Детекция речи (На базе WebRTC VAD).
Быстрая фильтрация тишины, музыки и нерелевантных фрагментов. Это существенно снижает нагрузку при распознавании. -
Детекция языка (AmberNet).
Мы берём 5 случайных 12-секундных фрагментов, конкатенируем их и отправляем в детектор языка. Такой подход хорошо работает даже для шумных и нерегулярных данных. -
Обработка длинных видео.
Мы научились читать аудио кусками до 1 часа и корректно восстанавливать временные метки. Это позволяет работать с многочасовыми видео без потери качества и в условиях ограниченной памяти.
Акустическая модель
В качестве акустической модели мы выбрали FastConformer‑L CTC с BPE‑токенайзером. Модель обучена на ~10k часов данных с онлайн‑аугментациями, которые мы разделили на два типа:
-
фоновые — длительные шумы окружения;
-
кратковременные — щелчки, хлопки, перебивки.
Все аугментации накладываются в режиме реального времени, что даёт практически бесконечное количество комбинаций «чистый сигнал + шум».
В результате — стабильное качество на UGC и заметно меньше галлюцинаций по сравнению с Whisper. Итоговые замеры качества мы проводили на специально подготовленном тестовом датасете, разбитом на категории в соответствие с категориями видео на RUTUBE.
Инференс
Для инференса мы используем Triton Inference Server.
Обрабатывать многочасовое аудио целиком — не вариант: это потребовало бы слишком много GPU‑памяти, причём из‑за неравномерной длины роликов большая часть этой памяти простаивала бы впустую.
Поэтому мы применили простой, но очень эффективный приём:
режем аудио на чанки по 8 секунд с перекрытием 1.6 секунды.
Это даёт два ключевых преимущества:
-
эффективный батчинг — GPU загружен равномерно, нет пустых прогонов;
-
лучший контекст — модель видит больше, чем при чистом стриминге, но без лишних вычислений.
Благодаря этому 1 час аудио обрабатывается примерно за 11 секунд, что примерно в 19 раз быстрее Whisper при сопоставимом качестве.
Постобработка
Чтобы получить качественный читаемый текст, мы используем несколько вспомогательных блоков:
-
словарь замен (нормализация доменных сущностей);
-
детектор числительных (корректировка чисел и количественных выражений);
-
KenLM как языковую модель;
-
BERT‑пунктуатор для восстановления пунктуации и капитализации.
Все эти компоненты доводят черновой текст до финального вида, который уже можно использовать в поиске, модерации и отображении субтитров.
Результаты
В итоге нам удалось достичь целевых метрик:
-
в среднем ~5 секунд на полную обработку видео длиной ~15 минут;
-
при параллельной обработке — порядка 1200 видео/час на один ASR.
|
Показатель |
Время обработки, сек |
||
|
Видео 15 мин |
Видео 1 ч |
Видео 2 ч |
|
|
Экстракция аудио |
1.12 |
3.90 |
7.30 |
|
Детекция речи |
0.23 |
0.90 |
1.78 |
|
Детекция языка |
0.95 |
||
|
Распознавание |
2.71 |
11.34 |
20.52 |
|
Субтитры |
0.08 |
0.28 |
0.66 |
|
Общее время |
5.09 |
17.37 |
31.21 |
Что оказалось важным
По ходу работы мы сделали несколько практических выводов:
-
Стриминговый подход работает даже для оффлайн‑задач.
Чанкование и батчинг дают выигрыш и по скорости, и по эффективности использования ресурсов. -
Собственная модель — это необходимость.
Публичные решения хорошо показывают себя в бенчмарках, но плохо адаптируются под конкретный домен. -
Качество субтитров ≠ только низкий WER.
Читаемость, переносы, пунктуация и тайминги влияют на пользовательский опыт не меньше. -
Часть препроцессинга можно убрать.
Если модель правильно обучена, она сама становится устойчивой к шуму и артефактам.
Вывод
На практике задача создания субтитров быстро выходит за рамки распознавания речи. Это и распределённая архитектура, и ML, и работа с текстом, и требования к UX.
Система, которая начиналась как экспериментальный MVP, сегодня обрабатывает тысячи часов пользовательского контента в день — и делает это за секундные задержки.
Это стало возможно только благодаря тому, что мы не стали рассматривать компоненты изолированно и оптимизировали весь процесс целиком.
Подписывайтесь на этот блог и канал Смотри за IT, если хотите знать больше о создании медиасервисов. Там рассказываем об инженерных тонкостях и продуктовых находках, делимся видео выступлений и кадрами из жизни команд Цифровых активов «Газпром-Медиа Холдинга» таких, как RUTUBE, PREMIER, Yappy.
Автор: dmitriy_weez


