Laion-400M 数据集
The Laion-400M dataset 包含 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 索引的暴力近似最近邻搜索
要运行暴力的近似最近邻搜索,请运行:
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
然后运行以下查询: