FImageSearch: мультимодальний пошук для AI-агента-стиліста
КейсКлієнт будував персонального AI-стиліста в месенджерах: надсилаєш йому street-style фото — він знаходить кожну річ образу в каталозі магазину. Агентові-стилісту потрібне пошукове ядро, яке можна викликати, — і цей проєкт саме воно: shop-the-look рушій, що знаходить кожну річ на фото й шукає її серед 105 100 товарів каталогу за пару сотень мілісекунд. Фото, текст, фото + текстове уточнення, ручний кроп — усі чотири режими запитів живуть в одному векторному просторі. Перше робоче демо запустилося за один вечір.
Записано з телефона на живому демо: аналіз усього образу, відсотки збігу, ручний кроп і текстове уточнення на реальному каталозі у 105 тисяч товарів.
Демо працює на GPU-боксі, який орендується за запитом, тож між показами воно спить — якщо посилання не відкривається, напишіть мені, і я його розбуджу.
Цифри
Як фото стає ранжованими результатами
Один HTTP-запит проганяє весь пайплайн. Головний фокус — батчинг: усі кропи речей плюс кроп людини ембедяться одним GPU-проходом, а всі слоти йдуть у векторну базу одним батчевим запитом.
photo ──▶ person detection RT-DETRv2, ~15 ms
──▶ garments in person crop YOLOS-Fashionpedia, 46 classes
──▶ 9 slots, head to toe headwear → … → shoes, max 7 per look
──▶ ONE GPU batch all crops + person, fashionSigLIP, 768-d
──▶ ONE batched Qdrant query hard filters: group / category / gender
──▶ CIELAB color re-rank ──▶ ranked results with % matchСамої векторної схожості мало — пошук гібридний. Поверх кожного запиту стоять жорсткі метафільтри: кроп черевика шукає лише в Shoes, чоловічий образ — лише в чоловічих розділах, а «курткові» категорії виключені зі слотів топів, щоб багатошаровий образ не тонув у пуховиках. Уже всередині цих меж вектор ранжує за схожістю.
Чого моделі не вміли з коробки
Найцікавіша інженерія — у прірві між «ембединги працюють» і «результати виглядають правильно». Усе нижче знайдено на реальних фото й виправлено вимірюваннями, а не на око:
SigLIP майже не бачить колір базових речей
Чорна й бежева базові футболки відрізняються на Δcos ≈ 0.01 — навіть на чистому лоскуті тканини. Фікс: передрахований домінантний CIELAB-колір усіх 105 тисяч товарів і колірний ре-ранк (вага 0.12, світлота в пів ваги — юзерські фото живуть у тінях, а каталог у студійному світлі).
Каталог перекошує голосування про стать
Перша спроба визначати стать — голосуванням за видачею — зайшла в глухий кут: каталог 3:1 жіночий, тож чоловічі кропи легітимно тягнуть жіночі речі. Фікс: zero-shot проба — кроп людини проти текстових якорів «a man» / «a woman» у тому самому батчі. ~2 мс, 7/7 на референсних фото.
Телефон читається як окуляри
У дзеркальних селфі fashion-детектор бачить телефон на рівні обличчя як окуляри (слот повертав чохли для телефонів). Фікс: бокси cell phone з того самого проходу детектора людей — нуль додаткової вартості — глушать окуляри/головні убори, що з ними перетинаються.
Паддинг затягує куртку в футболку
Топ під розстебнутою курткою погано ембедиться з контекстним відступом — кроп затягує блейзер і повертає жакети. Перевірено свипом: багатошарові топи ембедяться взагалі без паддингу, зі зниженим порогом прийняття.
Пара взуття — це здебільшого асфальт
Union-бокс навколо обох туфель у кроці — переважно дорожнє покриття, яке отруює ембединг. UI підсвічує обидві туфлі, але ембедиться лише більша й менш перекрита.
Сирі косинуси не мають візуального сенсу
Текстові й картиночні косинуси живуть у різних діапазонах; лінійний clamp показував усім результатам рівно 100%. Фікс: логістична калібровка на модальність — бейдж «97% match» реально ранжує видачу й ніколи не досягає ста.
Що я збудував
Двостадійна детекція
RT-DETRv2 знаходить людей і обирає головну; YOLOS-Fashionpedia (46 класів одягу) працює всередині її кропу — 2–4× ефективної роздільності на дрібних речах на кшталт окулярів і взуття.
Таксономія образу на 9 слотів
Детекції збираються у слоти «з голови до ніг» (головний убір → взуття) з правилами для конфлікту «сукня чи топ+низ», багатошарових образів і слот-специфічного паддингу кропів — усе відкалібровано свипами на референсних фото.
Один спільний векторний простір
marqo-fashionSigLIP кладе зображення й текст в один косинусний простір на 768 вимірів. Фото + «but in red» — зважена сума векторів (0.6 фото + 0.4 текст), а мультимовні запити працюють безкоштовно.
Гібридний пошук поверх Qdrant
Батчеві запити з жорсткими payload-фільтрами на слот (група, категорія, розділ статі) плюс keyword-індекси — векторна схожість ранжує лише в межах правильної полиці магазину.
Індексація, що пережила смерть сервера
Ембединги зберігаються інкрементальними шардами; індекс відновлюється без ре-ембедингу. Перший GPU-бокс фізично знищили посеред проєкту, потім усе мігрувало Німеччина → Польща → Каліфорнія — без жодного повторного GPU-прогону.
Фронтенд із чесним UX
Mobile-first UI на Next.js 14: автоаналіз при завантаженні, точки на фото, синхронізовані з рядками результатів, ручний кропер, % на кожній картці й банер «точного збігу нема — ось найближчі» замість вдавання.
Стек
Python · FastAPI · PyTorch fp16 · open_clip · marqo-fashionSigLIP · RT-DETRv2 · YOLOS-Fashionpedia · Qdrant · Next.js 14 · Tailwind + shadcn/ui · Vast.ai GPU · Cloudflare Tunnel + R2
Потрібен візуальний пошук по вашому каталогу?
Ядро не прив’язане до домену: детектор → слоти → ембединги → фільтрований векторний пошук → ре-ранк. Сьогодні це мода; меблі, інтер’єри чи будь-який візуальний каталог — тиждень калібрування. Якщо вашому продукту потрібне «знайди мені отаке» — напишіть.
Зв’язатисяСоло-проєкт, липень 2026. Демо на публічному датасеті H&M з Kaggle (2022); ціни в демо ілюстративні. Клієнт і комерційні деталі — під NDA.





