Автоматическое создание субтитров для пользовательского контента может показаться простой задачей: взять готовую модель 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.
- Формируется файл субтитров.
Это позволило быстро запустить MVP, но уже на этапе тестирования выявились серьёзные проблемы.
Проблемы MVP
Производительность. С Faster Whisper в однопоточном режиме мы получали около 30 видео/час на инстанс. Для обработки миллиона видео в день потребовалось бы около 1400 инстансов — неприемлемо.
Ограничения Whisper. Модель сложно адаптировать под домен из-за особенностей архитектуры:
- отсутствие явного alignment между аудио и текстом,
- генеративные ошибки и «галлюцинации»,
- невозможность независимого улучшения компонентов.
Качество было нестабильным, особенно на шумном пользовательском контенте.
Монолитная архитектура. Весь пайплайн — в одном сервисе. Это приводило к:
- последовательной обработке,
- неэффективному использованию ресурсов,
- отсутствию гибкости,
- невозможности переиспользовать результаты.
MVP работал, но не масштабировался. Whisper — отличная универсальная модель, но не для высоконагруженного доменного продакшена.
Мы приняли решение перестроить архитектуру с нуля. Оказалось, что дешевле и надёжнее построить собственный ASR-пайплайн, чем пытаться масштабировать Whisper.
Архитектура production-платформы
В продакшене система разделена на два ключевых компонента: Speech Worker и ASR.
Speech Worker отвечает за управление задачами, интеграции и формирование финальных субтитров.
ASR занимается непосредственно распознаванием — превращением аудио в текст. Он состоит из:
- ASR Backend — пред- и постобработка, управление сессиями,
- Triton Inference Server — GPU-инференс модели.
Такое разделение позволило изолировать вычислительно тяжёлую часть и масштабировать её независимо.
Управление задачами
В основе — Kafka. Все задачи передаются через неё.
Обработка устроена так:
- чтение сообщений из Kafka батчами,
- каждое сообщение — отдельная задача (1 видео = 1 задача),
- ограничение числа одновременных задач,
- при достижении лимита — новые сообщения не считываются.
Лимит параллельных задач определяется пропускной способностью ASR — самого тяжёлого этапа.
Это даёт простой механизм масштабирования: добавляем инстансы ASR — поднимаем лимит — растёт пропускная способность.
Почему субтитры — это не просто текст
Субтитры = текст + тайминги + читаемость
Любая ошибка сразу бросается в глаза:
- если тайминги «плывут» — зритель теряет контекст,
- если строки разбиты плохо — текст становится трудно читать или теряет смысл.
Проблема читаемости
Неправильный перенос строки может исказить смысл, замедлить чтение, нарушить восприятие.
❌ Он в итоге принял решение начать всё сначала
«принял решение» — единая конструкция.
✅ Он в итоге принял решение начать всё сначала
Другой пример:
❌ Мы увеличили throughput в двадцать раз по сравнению с прошлой системой
Акцент «в двадцать раз» уехал на вторую строку.
✅ Мы увеличили throughput в двадцать раз по сравнению с прошлой системой
На первый взгляд — мелочи. Но именно из них складывается пользовательский опыт.
Как мы это решали
За основу взяты правила ручной верстки субтитров:
- оптимальная длина строк,
- корректные точки переноса,
- комфортная скорость чтения,
- время отображения текста.
Мы построили собственный пайплайн, включающий:
- формирование предложений,
- разбиение на строки,
- корректировку таймингов.
Ключевой элемент — NLP на базе Spacy. Он анализирует текст и определяет, где можно, а где нельзя делать перенос, чтобы не нарушить смысл или ритм.
В итоге субтитры выглядят так, будто их верстал человек.
ASR: где начались настоящие сложности
Оффлайн-распознавание в пользовательских видео оказалось сложнее, чем казалось. Основные проблемы:
- произвольная длина аудио — от секунд до десятков часов,
- неизвестный язык,
- отсутствие речи в части роликов,
- шумы и артефакты разной природы.
Чтобы справиться, мы собрали собственный ASR-пайплайн из трёх этапов: предобработка, инференс акустической модели, постобработка.
Предобработка
- Подготовка аудио. Экстракция дорожки, ресемплинг, поддержка HLS/DASH — всё для нормализации сигнала.
- Детекция речи (WebRTC VAD). Быстрая фильтрация тишины и музыки — снижает нагрузку.
- Детекция языка (AmberNet). Анализ 5 случайных 12-секундных фрагментов. Подходит даже для шумных данных.
- Обработка длинных видео. Аудио читается кусками до 1 часа с восстановлением временных меток — позволяет работать с длинными записями при ограниченной памяти.
Акустическая модель
Мы выбрали FastConformer-L CTC с BPE-токенайзером. Модель обучена на ~10 тыс. часов данных с онлайн-аугментациями двух типов:
- фоновые — длительные шумы,
- кратковременные — щелчки, хлопки, перебивки.
Аугментации накладываются в реальном времени, создавая почти бесконечное число комбинаций «сигнал + шум».
Результат — стабильное качество на UGC и меньше галлюцинаций по сравнению с Whisper. Тестирование проводилось на специальном датасете, разбитом по категориям RUTUBE.
Для инференса используется Triton Inference Server. Обрабатывать всё аудио целиком — невозможно: слишком много GPU-памяти, большая часть которой простаивала бы.
Мы применили эффективный приём:
режем аудио на чанки по 8 секунд с перекрытием 1.6 секунды.
Это даёт два преимущества:
- эффективный батчинг — GPU загружен равномерно,
- лучший контекст — модель видит больше, чем при стриминге, но без лишних вычислений.
Благодаря этому 1 час аудио обрабатывается за ~11 секунд — примерно в 19 раз быстрее, чем Whisper, при сопоставимом качестве.
Постобработка
Чтобы получить качественный текст, мы используем несколько компонентов:
- словарь замен — нормализация доменных сущностей,
- детектор числительных — корректировка чисел,
- KenLM — языковая модель,
- BERT-пунктуатор — восстановление пунктуации и капитализации.
Все они доводят черновой текст до финального вида, пригодного для поиска, модерации и отображения.
Результаты
Нам удалось достичь целевых метрик:
- в среднем — ~5 секунд на полную обработку видео длиной ~15 минут,
- при параллельной обработке — до 1200 видео/час на один ASR.
Что оказалось важным
По ходу работы мы сделали несколько ключевых выводов:
- Стриминговый подход работает даже для оффлайн-задач. Чанкование и батчинг дают выигрыш по скорости и эффективности.
- Собственная модель — необходимость. Публичные решения хороши в бенчмарках, но плохо адаптируются под домен.
- Качество субтитров — это не только низкий WER. Читаемость, переносы, пунктуация и тайминги влияют на UX не меньше.
- Часть препроцессинга можно убрать. Хорошо обученная модель сама устойчива к шуму и артефактам.
Задача создания субтитров быстро выходит за рамки распознавания речи. Это и распределённая архитектура, и ML, и работа с текстом, и требования к UX.
Система, начавшаяся как MVP, сегодня обрабатывает тысячи часов контента в день — с задержкой в секунды. Это стало возможно благодаря комплексной оптимизации всего пайплайна, а не отдельных компонентов.