Архив семейных фотографий за пятнадцать лет — это обычно несколько сотен гигабайт в папках с названиями вроде «2019_08_дача» и полное отсутствие какой-либо навигации. Разработчик с Хабра решил эту проблему, написав Gailery — локальную веб-галерею, которая сама разбирается, кто изображён на снимках, и позволяет искать фотографии человеческими фразами. Система уже обрабатывает архив из более чем 100 тысяч фотографий и почти 10 тысяч видеороликов на сервере с процессором Intel Xeon E5-2680 v4 и видеокартой Tesla P104-100.
Тесла P104-100 — это карта, которую массово использовали майнеры криптовалют в 2017–2018 годах. После обвала рынка она осела на вторичке по цене около 30 долларов. Архитектурно это Pascal — то же поколение, что GTX 1070/1080, только без видеовыходов и с урезанными драйверами для потребительских задач. Для вычислений через CUDA она вполне пригодна: 8 ГБ видеопамяти хватает, чтобы запускать квантованные языковые модели и нейросети для распознавания лиц — просто не одновременно.
| Компонент | Модель / технология | Задача |
|---|---|---|
| Детектор лиц | InsightFace buffalo_l (SCRFD + ArcFace) | Построение 512-мерных векторов лиц |
| Кластеризация | DBSCAN (scikit-learn, eps=0.4, косинусная метрика) | Группировка лиц по персонам |
| VLM-описание | Qwen2.5-4B GGUF Q4_K_M (порт 8101) | Базовое описание содержимого снимка |
| LLM-агент | Qwen2.5-4B (порт 8103, Tool Calling) | Обогащение описания именами и контекстом |
| Эмбеддер | Qwen3-Embedding-0.6B (1024-мерные векторы) | Векторизация описаний для RAG-поиска |
| Векторная БД | LanceDB | Хранение и поиск по эмбеддингам описаний |
| GPU | Tesla P104-100, 8 ГБ VRAM (~30 USD) | CUDA-ускорение всех нейросетевых этапов |
В основе Gailery два независимых механизма. Первый — распознавание и кластеризация лиц. Библиотека InsightFace с моделью buffalo_l (детектор SCRFD плюс эмбеддер ArcFace) строит для каждого обнаруженного лица 512-мерный вектор признаков. Затем алгоритм DBSCAN из scikit-learn группирует эти векторы в кластеры по косинусному расстоянию с порогом eps=0.4 — так система понимает, что на тысяче разных снимков изображён один и тот же человек. Пользователю остаётся открыть карточку кластера и один раз написать имя: «Это Анна» или «Это дедушка». После этого все фотографии — старые и новые — автоматически привязываются к профилю.
Поиск лиц построен на InsightFace (SCRFD + ArcFace) с кластеризацией DBSCAN; пользователь один раз подписывает имя — система связывает все фото.
Второй механизм — семантический поиск через RAG. Обычные галереи генерируют описания вроде «мужчина в чёрной куртке стоит рядом с девочкой» — для семейного архива это бесполезно. Gailery работает в два шага: мультимодальная модель Qwen2.5-4B в формате GGUF сначала описывает, что происходит на снимке, а затем отдельный LLM-агент на той же модели обогащает описание контекстом. Агент запрашивает SQLite-базу через инструменты (Tool Calling): узнаёт имена людей по ID распознанных лиц, достаёт даты рождения и родственные связи. Если в базе записано, что ребёнок родился в 2013 году, а фото сделано 12 мая 2018-го, агент сам вычисляет возраст и пишет: «Алиса, 5 лет». Итоговые описания векторизуются моделью Qwen3-Embedding-0.6B и укладываются в векторную базу LanceDB в виде 1024-мерных векторов. Поисковый запрос «Алексей Петров на даче с дочкой» превращается в вектор и сравнивается с базой — система выдаёт точные результаты.
Есть важная деталь, связывающая оба механизма. Когда пользователь впервые подписывает имя в кластере лиц или меняет уже существующее, система автоматически помечает описания всех фотографий с этим человеком как устаревшие. На следующем проходе пайплайна агент заново генерирует описания и эмбеддинги — уже с правильным именем. Весь процесс происходит без участия пользователя.
Фоновый пайплайн спроектирован как строго последовательный бесконечный цикл — никакого параллелизма нейросетей. При 8 ГБ видеопамяти одновременный запуск нескольких моделей просто исчерпал бы ресурс. Цикл состоит из жёстких шагов: сначала дисковый обход с хешированием файлов через xxh128 и дедупликацией, затем чтение EXIF-метаданных (дата, GPS, модель камеры), потом детекция лиц пачками по 600 фотографий, и наконец генерация описаний через LLM-агент. GPU задействован только на этапах детекции и описания — остальное работает на процессоре.
Философия проекта сформулирована прямо: никто никуда не торопится. Архив копился пятнадцать лет, и нет смысла пытаться проиндексировать его за ночь, перегревая сервер. Галерея полностью работоспособна с первого дня: можно смотреть папки и пользоваться базовыми функциями, пока пайплайн в фоне постепенно наполняет её смыслом. Оригинальные файлы при этом монтируются в LXC-контейнер в режиме только чтения — никакой записи в медиапапку система не производит.
Подход интересен как пример того, что локальный ИИ для персональных данных перестал требовать дорогого оборудования. Аналогичные задачи — распознавание лиц, семантический поиск по фото — решают облачные сервисы Google Photos и Apple Photos, но они требуют загрузки данных на серверы компании. Gailery предлагает сопоставимый функционал полностью офлайн, на железе, которое можно купить на Авито.


