Набор данных LAION 5b содержит 5,85 миллиарда эмбеддингов для пар «изображение‑текст» и
соответствующие метаданные изображений. Эмбеддинги были сгенерированы с использованием модели OpenAI CLIPViT-L/14. Размерность каждого вектора эмбеддинга составляет 768.
Этот набор данных можно использовать для моделирования аспектов проектирования, масштабирования и производительности
крупномасштабного векторного поискового приложения, ориентированного на реальные сценарии. Набор данных можно использовать как для поиска изображений по текстовым запросам, так и для поиска изображений по другим изображениям.
Полный набор данных доступен в виде комбинации файлов форматов npy и Parquet на сайте the-eye.eu.
ClickHouse предоставил подмножество из 100 миллионов векторов в бакете S3.
Бакет S3 содержит 10 файлов формата Parquet, каждый файл Parquet содержит 10 миллионов строк.
Мы рекомендуем сначала выполнить оценку размеров, чтобы определить требования к хранилищу и памяти для этого набора данных, обратившись к документации.
id — это просто инкрементное целое число. Дополнительные атрибуты можно использовать в предикатах для работы с
векторным поиском по сходству в сочетании с постфильтрацией/префильтрацией, как описано в документации
Чтобы загрузить набор данных из всех файлов Parquet, выполните следующую SQL-команду:
INSERT INTO laion_5b_100m SELECT * FROM s3('https://clickhouse-datasets.s3.amazonaws.com/laion-5b/laion5b_100m_*.parquet');
Загрузка 100 миллионов строк в таблицу займёт несколько минут.
Также можно выполнить отдельные SQL-запросы для загрузки определённого количества файлов или строк.
INSERT INTO laion_5b_100m SELECT * FROM s3('https://clickhouse-datasets.s3.amazonaws.com/laion-5b/laion5b_100m_part_1_of_10.parquet');
INSERT INTO laion_5b_100m SELECT * FROM s3('https://clickhouse-datasets.s3.amazonaws.com/laion-5b/laion5b_100m_part_2_of_10.parquet');
⋮
Выполните поиск векторного сходства методом полного перебора
Поиск KNN (k ближайших соседей) или поиск методом полного перебора заключается в вычислении расстояния от каждого вектора в наборе данных до вектора поискового эмбеддинга с последующим упорядочиванием расстояний для получения ближайших соседей. В качестве поискового вектора можно использовать один из векторов из самого набора данных. Например:
SELECT id, url
FROM laion_5b_100m
ORDER BY cosineDistance( vector, (SELECT vector FROM laion_5b_100m WHERE id = 9999) ) ASC
LIMIT 20
Вектор в строке с id = 9999 является эмбеддингом изображения ресторана-деликатеса.
Зафиксируйте время выполнения запроса, чтобы затем сравнить его с временем выполнения запроса ANN (с использованием векторного индекса).
При 100 миллионах строк выполнение данного запроса без векторного индекса может занять от нескольких секунд до нескольких минут.
Выполните следующий SQL-запрос для определения и создания индекса векторного сходства для столбца vector таблицы laion_5b_100m:
ALTER TABLE laion_5b_100m ADD INDEX vector_index vector TYPE vector_similarity('hnsw', 'cosineDistance', 768, 'bf16', 64, 512);
ALTER TABLE laion_5b_100m MATERIALIZE INDEX vector_index SETTINGS mutations_sync = 2;
Параметры и аспекты производительности при создании индекса и выполнении поиска описаны в документации.
В приведённой выше инструкции используются значения 64 и 512 для гиперпараметров HNSW M и ef_construction соответственно.
Необходимо тщательно подбирать оптимальные значения этих параметров, оценивая время построения индекса и качество результатов поиска для выбранных значений.
Построение и сохранение индекса может занять несколько часов для полного набора данных из 100 миллионов записей в зависимости от количества доступных ядер ЦП и пропускной способности системы хранения.
Векторы эмбеддингов набора данных LAION 5b были созданы с помощью модели OpenAI CLIPViT-L/14.
Ниже приведен пример скрипта Python, демонстрирующий программную генерацию
векторов эмбеддингов с использованием API CLIP. Полученный вектор эмбеддинга для поиска
затем передается в качестве аргумента функции cosineDistance() в запросе SELECT.
import torch
import clip
import numpy as np
import sys
import clickhouse_connect
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-L/14", device=device)
# Поиск изображений, содержащих и собаку, и кошку
text = clip.tokenize(["a dog and a cat"]).to(device)
with torch.no_grad():
text_features = model.encode_text(text)
np_arr = text_features.detach().cpu().numpy()
# Укажите здесь учётные данные ClickHouse
chclient = clickhouse_connect.get_client()
params = {'v1': list(np_arr[0])}
result = chclient.query("SELECT id, url FROM laion_5b_100m ORDER BY cosineDistance(vector, %(v1)s) LIMIT 100",
parameters=params)
# Запись результатов в простую HTML-страницу для открытия в браузере. Некоторые URL могут быть устаревшими.
print("<html>")
for r in result.result_rows:
print("<img src = ", r[1], 'width="200" height="200">')
print("</html>")