Архитектура решения
Обзор
Новый сервис распознавания объединяет функциональность RecognitionService и TaggingService, обеспечивая единый процесс обработки фотографий от получения события до отправки результатов в PhotoService и TagatorService.
Основные принципы:
- Единое место для управления распознаванием лиц и номеров
- Минимизация дублирования данных
- Оптимизация работы с БД и инфраструктурой
- Гибкая поддержка различных провайдеров и стратегий
Провайдеры распознавания
VkVision
Возможности:
- Распознавание только лиц
- Синхронный ответ
Особенности:
- Ограничение 75 000 лиц в одном спейсе
- При достижении лимита возвращает последнее лицо для любой фотографии
- Требуется управление несколькими аккаунтами и спейсами для масштабирования
Архитектура для масштабирования:
- Для каждого тенанта можно завести несколько аккаунтов VkVision
- Каждый аккаунт поддерживает до 10 спейсов
- При создании события администратор выбирает аккаунт и спейс
- Контроль заполненности спейсов по количеству лиц
Athlete
Возможности:
- Распознавание лиц
- Распознавание стартовых номеров
- Одновременное распознавание лиц и номеров одним вызовом
Особенности:
- Асинхронный результат через callback
- Передача
recognition type = FACE_NUMBER - Возврат
personsиtagsв одном колбеке
Требования к качеству распознавания
Лица
- Фотография с фронтальным лицом распознается с точностью ≥ 99%
- Персона определяется при видимости лица ≥ 30%
- Скорость распознавания ≥ скорости распознавания номеров
- Одной персоне не должны присваиваться разные лица
- Одному лицу из 100 фото присваивается ≤ 3 персон
Номера
- Определен номер, соответствующий участнику на фотоснимке
- Фотоснимку присвоен корректный тег
- Обработка ≤ 1 часа на 100 000 фотоснимков
- Найдено ≥ 90% номеров участников
- Корректность найденных номеров ≥ 80%
Стратегии распознавания
Режимы работы
Только авто
Варианты:
- Лица через VkVision + номера через Athlete
- Лица и номера через Athlete одним запросом
Процесс:
- Распознать лица и/или номера согласно настройкам (VkVision или Athlete для лиц, Athlete для номеров)
- Валидировать номера по стартовому списку (удалить отсутствующие)
- Если нет ни одного номера (или в будущем — если количество номеров ≠ количеству лиц) — создать задачу ручного тегирования
- Отправить результаты в PhotoService
Только ручное
- Создается задача ручного тегирования
- Результаты из автоматического распознавания, если они есть, не используются
Сначала авто, потом ручное
Процесс:
- Распознать лица (VkVision или Athlete)
- Распознать номера (Athlete)
- Валидировать номера по стартовому списку (удалить отсутствующие)
- Если нет ни одного номера (или в будущем — если количество номеров ≠ количеству лиц) — создать задачу ручного тегирования
- Отправить результаты в PhotoService
Авто и ручное
- Параллельно выполняется автоматическое распознавание
- Параллельно создается задача ручного тегирования
- Результаты обоих процессов объединяются
Отключено
- Распознавание не выполняется
- Задачи не создаются
Опциональность распознавания лиц
Во всех стратегиях распознавание лиц может быть отключено:
- Только автоматическое распознавание номеров
- Только ручное тегирование номеров
- Комбинации без распознавания лиц
Модель задач
В зависимости от провайдеров создаются разные типы задач:
VkVision для лиц + Athlete для номеров
- Задача распознавания лиц (VkVision)
- Задача распознавания номеров (Athlete)
- Опционально: задача ручного тегирования
Athlete для лиц и номеров
- Единая задача распознавания лиц и номеров (Athlete)
- Опционально: задача ручного тегирования
Текущая модель задач пересматривается с учетом возможности Athlete распознавать лица и номера одновременно.
Валидация результатов
Фильтрация по стартовому списку
- Оставляются только номера, присутствующие в стартовом списке
- Если после фильтрации остался хотя бы один номер — результат считается корректным
Проверка соответствия лиц и номеров
Будущая доработка. Если на фото несколько персон, а после валидации остался только один номер:
- Результат считается некорректным
- Фото отправляется на ручное тегирование
- Критерий: несоответствие количества номеров и лиц
Плохой результат распознавания
В стратегии "Сначала авто, потом ручное":
- Если номеров не найдено — отправить на ручное тегирование
- Будущая доработка. Если количество номеров ≠ количеству лиц — отправить на ручное тегирование
Разрядность номеров
Текущая реализация:
- Разрядность передается в Athlete
- Athlete не возвращает номера с меньшим количеством символов
Проблемы:
- Невозможность перепроверить результаты без повторного распознавания
- Зависимость от ошибок менеджеров в настройках
- Сложность повторного распознавания при изменении разрядности
Решение: пока оставляем как есть.
- Оставить учет разрядности на стороне Athlete для корректных взаиморасчетов
- Athlete получает разрядность и фильтрует результаты
- В будущем можно рассмотреть перенос фильтрации на нашу сторону
Изменение стратегии распознавания
Проблема текущей реализации
При изменении стратегии запускается джоба, перебирающая все фотографии альбома:
- Длительный процесс
- Высокая нагрузка на БД
- Риск сбоев
- Повторная обработка уже распознанных фото
Новая реализация
Принципы:
- Не перебирать все фотографии альбома
- Обрабатывать только фото, требующие распознавания согласно новой стратегии
- Хранить признаки состояния распознавания на записи фото
Признаки состояния (примеры):
FaceRecognized— лица распознаныNumberRecognized— номера распознаныManualTaggingCompleted— ручное тегирование завершено
Процесс изменения стратегии:
- Остановить текущий процесс обработки
- Определить фото, требующие обработки согласно новой стратегии
- Выбрать фото по признакам состояния
- Запустить обработку только выбранных фото
- Не повторять уже выполненную работу
AlbumPhotosProcessingJob:
- Обрабатывает только нераспознанные фото
- Учитывает наличие тегов и персон
- Применяет логику стратегии для определения необходимости обработки
ПРОБЛЕМА новой реализации
Противоречие: Если при изменении стратегии выбирать для обработки только фото, нераспознанные по нужному признаку (согласно новой стратегии), не получится удалить из PhotoService теги, отсутствующие в новой стратегии.
Примеры:
- Стратегия "Авто и ручное" полностью завершилась, выбрали стратегию "Только авто" - из PhotoService нужно удалить результаты ручного тегирования.
- Стратегия "Только авто" полностью завершилась, выбрали стратегию "Только ручное" - из PhotoService нужно удалить результаты автоматического тегирования.
Приоритеты обработки
Текущие проблемы
Проблема 1: Обработка новых фото
- Обработка происходит в порядке загрузки фото
- Приоритет альбома не учитывается
- При большой очереди фото обрабатываются без учета приоритета
Проблема 2: Обработка колбеков
- Обработка по событиям, а не по приоритету
- Athlete не учитывает приоритет
- При большой очереди колбеков приоритет не работает
Проблема 3: Изменение параметров
- При изменении разрядности фото переотправляются в Athlete
- Athlete обрабатывает их в общей очереди без приоритета
Возможное решение
Polling таблиц с учетом приоритета:
- Polling таблицы Photo для обработки новых фото
- Polling таблицы Callback для обработки результатов
- Выборка с сортировкой по приоритету альбома
Ограничение:
- Усложняет реализацию
- Требует дополнительной нагрузки на БД
Решение: Вопрос приоритетов выносится отдельно и прорабатывается после реализации основного функционала.
Оптимизация обработки
Устранение промежуточных статусов
Текущая реализация:
- Создание фото → запись в БД
- Создание задач → запись в БД
- Изменение статуса на
Processing→ запись в БД - Обработка фото → чтение из БД
- Сохранение результата → запись в БД
Новая реализация:
- Создание фото → запись в БД
- Обработка фото сразу (распознавание в VkVision или делегирование в Athlete)
- Сохранение результата и создание задач → одна запись в БД
Максимум полезной работы между чтением и записью.
Оптимизация Hangfire и Redis
Текущая реализация:
- Hangfire-джоба создается на каждое фото.
- Высокая нагрузка на Redis.
- При нехватке памяти обработка ломается.
Новая реализация:
- При получении события
PhotoCreatedобработать фото сразу. - При успехе — завершить подписку.
- При ошибке — создать Hangfire-джобу для повторной обработки.
- При необходимости добавить retry (2 попытки) перед созданием Hangfire-джобы. Однако при этом, если в момент времени происходит слишком много повторных попыток (постоянные ошибки при инфраструктурных проблемах), retry нужно отключать, чтобы не удваивать нагрузку на систему при длительных сбоях.
- Если Redis недоступен и джоба не создалась — подписка упадет и повторится автоматически.
Преимущества:
- Минимальная нагрузка на Redis
- Обработка продолжается при недоступности Redis
- Автоматическое восстановление через механизм подписок
Кастомные теги
Механизм кастомных тегов (AlbumCustomTag) сохраняется без изменений:
- Администратор может добавить произвольные теги для альбома
- Кастомные теги передаются в TagatorService
- Тегаторы могут использовать кастомные теги при разметке
- Кастомные теги учитываются при валидации результатов
Распознавание по селфи
Функциональность распознавания по селфи переносится в новый сервис:
- Загрузка селфи пользователя
- Распознавание лица на селфи
- Поиск фотографий с этим лицом в альбоме
- Возврат результатов клиенту
- Хранение SelfieId и Preview (для отображения на клиенте на странице корзины или заказа)