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 и моделей