Перейти к содержанию

ML-сервис

Назначение

ML-сервис — микросервис компьютерного зрения для автоматической классификации предметов одежды, генерации векторных представлений (эмбеддингов) и рекомендаций образов. Работает как отдельный сервис, доступный бэкенду по внутренней сети кластера.

Технологический стек

Компонент Технология Назначение
Язык Python 3.11 Основной язык
Фреймворк FastAPI 0.115 REST API
Сервер Uvicorn 0.32 ASGI-сервер
Deep Learning PyTorch 2.0+ (CPU) Инференс моделей
Визуальные модели TorchVision 0.15+ ResNet, ConvNeXt, EfficientNet
ML scikit-learn 1.3+ Модели совместимости
Сериализация joblib 1.3+ Сохранение/загрузка моделей
Удаление фона rembg 2.0.50+ Удаление фона фотографий
Обработка изображений Pillow 10.0+ Ресайз, нормализация

Функции ML-сервиса

1. Классификация вещей

По фотографии вещи модель предсказывает три атрибута:

Атрибут Количество классов Примеры
Article Type (тип вещи) 26 Tshirts, Jeans, Dresses, Boots, Handbags, Sunglasses
Base Colour (основной цвет) 19 Black, White, Blue, Beige, Red, Multi
Season (сезон) 5 Spring, Summer, Fall, Winter, Unknown

Модель: ConvNeXt-Tiny (Multi-Task Learning) — три классификационных головы на общем backbone.

Режимы инференса: - mtl — единая модель с тремя головами (быстрее) - single_heads — отдельная модель на каждый атрибут (точнее) - auto — пробует single_heads, при неудаче переключается на mtl

Предобработка изображения: RGB → ресайз 224×224 → нормализация ImageNet (mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]).

Ответ включает предсказанные метки, confidence-скоры (softmax-вероятности) для каждого атрибута, версию и имя модели.

2. Генерация эмбеддингов

Каждая вещь представляется вектором в многомерном пространстве для расчёта сходства и рекомендаций.

Модель Размерность Назначение
ResNet18 512 Легаси, обратная совместимость
ResNet50 → Linear 1024 Основной формат для outfit-моделей

Pipeline: изображение → ResNet50 backbone (2048d) → линейная проекция → 1024-мерный вектор.

3. Оценка совместимости образа

Модель оценивает, насколько гармонично сочетаются вещи в образе.

  • Вход: список вещей с эмбеддингами и категориями
  • Признаки: среднее эмбеддингов + попарные метрики (cosine similarity, L2 distance) + распределение категорий
  • Выход: score от 0 до 1 (степень совместимости)
  • Модель: outfit_compat_best.joblib (scikit-learn)

4. Рекомендация вещей

Для незаполненного слота образа подбирается наиболее подходящая вещь из гардероба.

  • Вход: частичный образ (заполненные слоты), целевая категория, кандидаты
  • Методы: similarity (30%), compatibility (70%), hybrid (по умолчанию)
  • Модель: rec_model_v2.joblib

5. Поиск похожих образов

Находит образы, визуально похожие на заданный.

  • Метод: cosine similarity на средних эмбеддингах образов
  • Без отдельной модели — чисто векторная операция

6. Удаление фона

Подготовка фотографий: удаление фона для чистого отображения вещей.

  • Библиотека: rembg (на основе ONNX Runtime)
  • Выход: PNG с альфа-каналом

API-эндпоинты

Эндпоинт Метод Вход Выход
/api/ml/remove-bg POST multipart file (JPEG/PNG) PNG с альфа-каналом
/api/ml/attributes POST multipart file JSON: article_type, base_colour, season + confidences
/api/ml/embed POST multipart file, ?dim=1024 JSON: embedding[] + dim
/api/ml/outfit/score POST JSON: items[] (embedding, category) JSON: score (0–1)
/api/ml/outfit/build POST JSON: all items[], top_k JSON: outfits[] (item_ids, score)
/api/ml/outfit/recommend POST JSON: partial_items, target, candidates, method JSON: recommendations[]
/api/ml/outfit/similar POST JSON: query_embedding, candidates, top_k JSON: similar[] (outfit_id, score)
/api/ml/health GET JSON: status + состояние моделей

Интеграция с фронтендом

Классификация при добавлении вещи

sequenceDiagram
    participant U as Пользователь
    participant F as Frontend
    participant B as Backend
    participant ML as ML Service
    participant S as MinIO

    U->>F: Выбирает фото вещи
    F->>B: POST /api/media (multipart)
    B->>S: Сохранение файла (S3 PUT)
    B->>ML: POST /api/ml/attributes (file)
    ML-->>B: {article_type, base_colour, season, confidences}
    B-->>F: MediaUploadResponse + predictions
    F->>F: Автозаполнение формы (категория, цвет, сезон)
    U->>F: Корректирует / подтверждает
    F->>B: POST /api/items
    B-->>F: Item created

Диаграмма

Фронтенд получает ML-предсказания вместе с ответом на загрузку медиа и автоматически заполняет поля формы добавления вещи. Пользователь может скорректировать предсказания перед сохранением.

Генерация и использование эмбеддингов

sequenceDiagram
    participant B as Backend
    participant ML as ML Service
    participant DB as PostgreSQL
    participant F as Frontend

    B->>ML: POST /api/ml/embed (file, dim=1024)
    ML-->>B: {embedding: float[1024], dim: 1024}
    B->>DB: Сохранение вектора в item_embeddings

    Note over F: При запросе похожих образов
    F->>B: GET /api/outfits/{id}/similar
    B->>DB: Загрузка эмбеддингов
    B->>ML: POST /api/ml/outfit/similar
    ML-->>B: [{outfit_id, score}, ...]
    B-->>F: Похожие образы

Диаграмма

Эмбеддинги генерируются однократно при загрузке фото и сохраняются в БД. Далее используются для поиска похожих образов и рекомендаций без повторного обращения к модели.

Обучение моделей

Классификация (v2)

  • Данные: Kaggle Fashion Product Images (~44k изображений после фильтрации)
  • Архитектура: ConvNeXt-Tiny backbone + 3 классификационные головы (MTL)
  • Обучение: 35 эпох, batch 48, lr 0.00025, AdamW
  • Loss: Composite (type: 0.5, color: 0.3, season: 0.2) + auxiliary 0.15
  • Качество фильтрации: min 224×224, aspect ratio ≤ 2.2, entropy ≥ 3.5

Совместимость и рекомендации

  • Модели: scikit-learn (joblib-формат)
  • Признаки: 1024d эмбеддинги + попарные метрики + категориальное распределение
  • Роли вещей: top (верх + верхняя одежда), bottom (низ), shoes (обувь)

Структура проекта

ml-service/
├── app/
│   ├── main.py              # Инициализация FastAPI
│   ├── config.py             # Конфигурация (пути к моделям, env)
│   ├── routes.py             # API-эндпоинты
│   └── services/
│       ├── attributes.py     # Классификация (MTL / single-head)
│       ├── embeddings.py     # ResNet18/50 эмбеддинги
│       ├── outfit.py         # Scoring, build, recommend, similar
│       └── remove_bg.py      # Удаление фона (rembg)
├── models/                   # Веса моделей (.pth, .joblib)
├── configs/attr_v2/          # Конфигурации обучения
├── scripts/                  # Скрипты обучения и оценки
└── tests/                    # Тесты API и моделей