Перейти к основному содержимому

Архитектура решения

Обзор

Новый сервис распознавания объединяет функциональность 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 одним запросом

Процесс:

  1. Распознать лица и/или номера согласно настройкам (VkVision или Athlete для лиц, Athlete для номеров)
  2. Валидировать номера по стартовому списку (удалить отсутствующие)
  3. Если нет ни одного номера (или в будущем — если количество номеров ≠ количеству лиц) — создать задачу ручного тегирования
  4. Отправить результаты в PhotoService

Только ручное

  • Создается задача ручного тегирования
  • Результаты из автоматического распознавания, если они есть, не используются

Сначала авто, потом ручное

Процесс:

  1. Распознать лица (VkVision или Athlete)
  2. Распознать номера (Athlete)
  3. Валидировать номера по стартовому списку (удалить отсутствующие)
  4. Если нет ни одного номера (или в будущем — если количество номеров ≠ количеству лиц) — создать задачу ручного тегирования
  5. Отправить результаты в PhotoService

Авто и ручное

  • Параллельно выполняется автоматическое распознавание
  • Параллельно создается задача ручного тегирования
  • Результаты обоих процессов объединяются

Отключено

  • Распознавание не выполняется
  • Задачи не создаются

Опциональность распознавания лиц

Во всех стратегиях распознавание лиц может быть отключено:

  • Только автоматическое распознавание номеров
  • Только ручное тегирование номеров
  • Комбинации без распознавания лиц

Модель задач

В зависимости от провайдеров создаются разные типы задач:

VkVision для лиц + Athlete для номеров

  • Задача распознавания лиц (VkVision)
  • Задача распознавания номеров (Athlete)
  • Опционально: задача ручного тегирования

Athlete для лиц и номеров

  • Единая задача распознавания лиц и номеров (Athlete)
  • Опционально: задача ручного тегирования

Текущая модель задач пересматривается с учетом возможности Athlete распознавать лица и номера одновременно.

Валидация результатов

Фильтрация по стартовому списку

  • Оставляются только номера, присутствующие в стартовом списке
  • Если после фильтрации остался хотя бы один номер — результат считается корректным

Проверка соответствия лиц и номеров

Будущая доработка. Если на фото несколько персон, а после валидации остался только один номер:

  • Результат считается некорректным
  • Фото отправляется на ручное тегирование
  • Критерий: несоответствие количества номеров и лиц

Плохой результат распознавания

В стратегии "Сначала авто, потом ручное":

  • Если номеров не найдено — отправить на ручное тегирование
  • Будущая доработка. Если количество номеров ≠ количеству лиц — отправить на ручное тегирование

Разрядность номеров

Текущая реализация:

  • Разрядность передается в Athlete
  • Athlete не возвращает номера с меньшим количеством символов

Проблемы:

  • Невозможность перепроверить результаты без повторного распознавания
  • Зависимость от ошибок менеджеров в настройках
  • Сложность повторного распознавания при изменении разрядности

Решение: пока оставляем как есть.

  • Оставить учет разрядности на стороне Athlete для корректных взаиморасчетов
  • Athlete получает разрядность и фильтрует результаты
  • В будущем можно рассмотреть перенос фильтрации на нашу сторону

Изменение стратегии распознавания

Проблема текущей реализации

При изменении стратегии запускается джоба, перебирающая все фотографии альбома:

  • Длительный процесс
  • Высокая нагрузка на БД
  • Риск сбоев
  • Повторная обработка уже распознанных фото

Новая реализация

Принципы:

  1. Не перебирать все фотографии альбома
  2. Обрабатывать только фото, требующие распознавания согласно новой стратегии
  3. Хранить признаки состояния распознавания на записи фото

Признаки состояния (примеры):

  • FaceRecognized — лица распознаны
  • NumberRecognized — номера распознаны
  • ManualTaggingCompleted — ручное тегирование завершено

Процесс изменения стратегии:

  1. Остановить текущий процесс обработки
  2. Определить фото, требующие обработки согласно новой стратегии
  3. Выбрать фото по признакам состояния
  4. Запустить обработку только выбранных фото
  5. Не повторять уже выполненную работу

AlbumPhotosProcessingJob:

  • Обрабатывает только нераспознанные фото
  • Учитывает наличие тегов и персон
  • Применяет логику стратегии для определения необходимости обработки

ПРОБЛЕМА новой реализации

Противоречие: Если при изменении стратегии выбирать для обработки только фото, нераспознанные по нужному признаку (согласно новой стратегии), не получится удалить из PhotoService теги, отсутствующие в новой стратегии.

Примеры:

  • Стратегия "Авто и ручное" полностью завершилась, выбрали стратегию "Только авто" - из PhotoService нужно удалить результаты ручного тегирования.
  • Стратегия "Только авто" полностью завершилась, выбрали стратегию "Только ручное" - из PhotoService нужно удалить результаты автоматического тегирования.

Приоритеты обработки

Текущие проблемы

Проблема 1: Обработка новых фото

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

Проблема 2: Обработка колбеков

  • Обработка по событиям, а не по приоритету
  • Athlete не учитывает приоритет
  • При большой очереди колбеков приоритет не работает

Проблема 3: Изменение параметров

  • При изменении разрядности фото переотправляются в Athlete
  • Athlete обрабатывает их в общей очереди без приоритета

Возможное решение

Polling таблиц с учетом приоритета:

  • Polling таблицы Photo для обработки новых фото
  • Polling таблицы Callback для обработки результатов
  • Выборка с сортировкой по приоритету альбома

Ограничение:

  • Усложняет реализацию
  • Требует дополнительной нагрузки на БД

Решение: Вопрос приоритетов выносится отдельно и прорабатывается после реализации основного функционала.

Оптимизация обработки

Устранение промежуточных статусов

Текущая реализация:

  1. Создание фото → запись в БД
  2. Создание задач → запись в БД
  3. Изменение статуса на Processing → запись в БД
  4. Обработка фото → чтение из БД
  5. Сохранение результата → запись в БД

Новая реализация:

  1. Создание фото → запись в БД
  2. Обработка фото сразу (распознавание в VkVision или делегирование в Athlete)
  3. Сохранение результата и создание задач → одна запись в БД

Максимум полезной работы между чтением и записью.

Оптимизация Hangfire и Redis

Текущая реализация:

  • Hangfire-джоба создается на каждое фото.
  • Высокая нагрузка на Redis.
  • При нехватке памяти обработка ломается.

Новая реализация:

  1. При получении события PhotoCreated обработать фото сразу.
  2. При успехе — завершить подписку.
  3. При ошибке — создать Hangfire-джобу для повторной обработки.
  4. При необходимости добавить retry (2 попытки) перед созданием Hangfire-джобы. Однако при этом, если в момент времени происходит слишком много повторных попыток (постоянные ошибки при инфраструктурных проблемах), retry нужно отключать, чтобы не удваивать нагрузку на систему при длительных сбоях.
  5. Если Redis недоступен и джоба не создалась — подписка упадет и повторится автоматически.

Преимущества:

  • Минимальная нагрузка на Redis
  • Обработка продолжается при недоступности Redis
  • Автоматическое восстановление через механизм подписок

Кастомные теги

Механизм кастомных тегов (AlbumCustomTag) сохраняется без изменений:

  • Администратор может добавить произвольные теги для альбома
  • Кастомные теги передаются в TagatorService
  • Тегаторы могут использовать кастомные теги при разметке
  • Кастомные теги учитываются при валидации результатов

Распознавание по селфи

Функциональность распознавания по селфи переносится в новый сервис:

  • Загрузка селфи пользователя
  • Распознавание лица на селфи
  • Поиск фотографий с этим лицом в альбоме
  • Возврат результатов клиенту
  • Хранение SelfieId и Preview (для отображения на клиенте на странице корзины или заказа)