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
然后运行以下查询: