Инженерия

Как мы сохраняем результат, когда обработка встречи обрывается

Отдельный обработчик, сохранённая расшифровка и повтор неудачного этапа. Что помогает пережить сбой и где восстановление останавливается.

· · 6 минут

При обработке длинной встречи распознавание речи может завершиться, а разметка спикеров — оборваться. Мы добавили сохранение результатов отдельных этапов, чтобы после сбоя продолжать с незавершённого. Так готовая расшифровка сохраняется, даже если разметку спикеров пока не удалось закончить.

Одна запись остановила веб-интерфейс

В сентябре при обработке длинной записи процесс, обслуживающий веб-интерфейс, занял почти 5 ГБ памяти. Linux завершил его из-за нехватки памяти. Сервис автоматически перезапустился, но импорт встречи прервался. В это время выкладки новой версии не было.

До этого тяжёлая обработка запускалась внутри процесса, который обслуживал сайт. Из-за этого подготовка аудио могла повлиять на доступность интерфейса, а перезапуск сайта — оборвать работу над записью. По журналу инцидента нельзя было установить, какая именно операция вызвала рост памяти. Однако сама зависимость уже требовала исправления.

Мы вынесли обработку в отдельный фоновый процесс — worker. Сайт принимает файл и сохраняет задание в базе данных. Обработчик забирает его из очереди и выполняет существующие этапы. Теперь интерфейс можно перезапустить, пока обработчик продолжает работу.

Одного переноса оказалось мало. После аварии оставались вопросы: какие результаты успели сохраниться, работает ли ещё старый процесс и можно ли безопасно запустить следующий.

Повторять только незавершённый этап

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

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

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

Задание также связано с конкретной версией обработчика. Новая версия может иначе читать сохранённые данные, поэтому автоматически отдавать ей незавершённую встречу рискованно. Для перехода мы отдельно проверяем совместимость аудио, текста и контрольной точки. Только после этого меняем версию для нужного задания.

Перед повтором нужно остановить прежнюю попытку

Обработчик периодически сообщает, что он жив. Но отсутствие такого сообщения ещё не доказывает, что вычисления закончились. Процесс мог потерять соединение с базой, пока его дочерняя программа продолжала обрабатывать аудио. Если сразу выдать ту же работу следующему процессу, на сервере окажутся две тяжёлые обработки.

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

Повторный запрос на перезапуск тоже должен быть безопасным. Пользователь может нажать кнопку ещё раз, если ответ страницы задержался. Повторное нажатие не создаёт ещё одну обработку: система возвращает состояние той же попытки.

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

Ручные исправления требуют отдельной защиты

Повторная обработка усложняется, когда человек уже проверил встречу. В тексте могли исправить слова, а у реплик — подтвердить спикеров. При восстановлении нужно сохранить эту работу.

Для очищенного текста мы используем соответствующую контрольную точку вместе с журналом правок. С подтверждёнными вручную спикерами обнаружилось ограничение: первая версия сохранённого результата не содержала прежних автоматических назначений. Без них нельзя было безопасно восстановить исходное состояние.

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

Что показали испытания со сбоями

Мы проверяли восстановление на отдельном Linux-стенде с настоящими процессами, базой данных и службой запуска. Тяжёлые вызовы моделей там заменяли тестовые обработчики. Так можно многократно воспроизвести нужный сбой и проверить сохранённые данные.

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

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

Что произошлоЧто сохраняетсяЧто делать дальше
Перезапустился веб-интерфейсЗадание и работа отдельного обработчикаПродолжить наблюдение за текущей обработкой
Обработка оборвалась после получения текстаСохранённый текст и подготовленное аудиоПроверить остановку прежней попытки и продолжить с незавершённого этапа
Нужен повтор диаризации, но спикеры уже подтверждены вручнуюПодтверждённая человеком разметкаОстановить штатный повтор и отдельно решить, как сохранить ручные назначения
Диаризация превысила лимит времениРезультаты успешно завершённых этаповЗафиксировать частичный результат и разобрать причину остановки

Разметка восьмичасовой записи осталась незавершённой

Реальная длинная встреча показала предел этих изменений. В сентябре мы восстанавливали обработку примерно восьмичасовой записи, сохраняя уже полученный текст. После восстановления задание очереди завершилось, но результат встречи остался частичным: Community-1 достигла лимита времени на диаризацию.

Задание в очереди уже закрыто, процесс закончил работу, сохранённые данные на месте. Однако полного результата с распределением реплик по спикерам всё ещё нет. В журнале восстановления это ограничение зафиксировали отдельно.

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

Материал может пригодиться коллегам? Отправьте им ссылку на статью.