跳到主要内容
跳到主要内容

Laion-400M 数据集

Laion-400M 数据集 包含 4 亿张带有英文图片标题的图片。如今 Laion 提供了 一个更大的数据集,但使用起来会类似。

该数据集包含图片的 URL、图像和图像标题的嵌入、图像和图像标题之间的相似度分数,以及元数据,例如图像的宽度/高度、许可证和 NSFW 标志。我们可以使用该数据集来演示 ClickHouse 中的 近似最近邻搜索

数据准备

嵌入和元数据存储在原始数据的单独文件中。数据准备步骤下载数据,合并文件,转换为 CSV 并将其导入到 ClickHouse 中。您可以使用以下 download.sh 脚本:

脚本 process.py 定义如下:

要启动数据准备管道,请运行:

数据集被分成 410 个文件,每个文件包含约 100 万行。如果您想要处理较小的数据子集,只需调整限制,例如 seq 0 9 | ...

(上述 python 脚本非常慢(每个文件约 2-10 分钟),占用大量内存(每个文件 41 GB),生成的 csv 文件也很大(每个 10 GB),所以请小心。如果您有足够的 RAM,请增加 -P1 数量以提高并行性。如果这仍然太慢,请考虑想出更好的引入程序 - 也许将 .npy 文件转换为 parquet,然后用 clickhouse 进行所有其他处理。)

创建表

要创建一个没有索引的表,请运行:

要将 CSV 文件导入 ClickHouse:

运行暴力 ANN 搜索(没有 ANN 索引)

要运行暴力近似最近邻搜索,请运行:

target 是一个 512 元素的数组和一个客户端参数。获取此类数组的方便方法将在文章末尾呈现。现在,我们可以用一张随机猫的图片嵌入作为 target

结果

运行带有 ANN 索引的 ANN

创建一个带有 ANN 索引的新表并从现有表中插入数据:

默认情况下,Annoy 索引使用 L2 距离作为度量。关于索引创建和搜索的进一步调优选项在 Annoy 索引 文档 中描述。现在我们再次使用相同的查询检查:

结果

速度显著提高,但准确性有所下降。这是因为 ANN 索引仅提供近似搜索结果。请注意,上面的示例是搜索相似的图像嵌入,但也可以搜索正面的图像标题嵌入。

使用 UDF 创建嵌入

通常,人们希望为新图像或新图像标题创建嵌入,并在数据中搜索相似的图像/图像标题对。我们可以使用 UDF 来创建 target 向量,而无需离开客户端。重要的是使用相同的模型来创建数据以及进行搜索的新嵌入。以下脚本利用了 ViT-B/32 模型,该模型也用于该数据集。

文本嵌入

首先,将以下 Python 脚本存储在 ClickHouse 数据路径的 user_scripts/ 目录中,并使其可执行(chmod +x encode_text.py)。

encode_text.py:

然后在您的 ClickHouse 服务器配置文件中创建 encode_text_function.xml,路径由 <user_defined_executable_functions_config>/path/to/*_function.xml</user_defined_executable_functions_config> 引用。

您现在可以简单地使用:

第一次运行会很慢,因为它加载模型,但重复运行会很快。然后我们可以将输出复制到 SET param_target=...,并可以轻松编写查询。

图像嵌入

图像嵌入的创建方法类似,但我们将提供给 Python 脚本一个本地图像的路径,而不是图像标题文本。

encode_image.py

encode_image_function.xml

然后运行以下查询: