DoubleCloud 即将停止运营。迁移到 ClickHouse,享受限时免费迁移服务。立即联系我们 ->->

博客 / 工程

使用 ClickHouse 进行向量搜索 - 第 1 部分

author avatar
Dale McDiarmid
2023 年 5 月 31 日

立即开始使用 ClickHouse Cloud 并获得 300 美元的信用额度。要详细了解我们的基于用量的折扣,请联系我们或访问我们的定价页面

简介

在过去的一年中,大型语言模型 (LLM) 以及 ChatGPT 等产品抓住了全世界的想象力,并推动了建立在其之上的新一波功能浪潮。向量和向量搜索的概念是为推荐、问答、图像/视频搜索等功能提供支持的核心。

因此,我们看到社区对向量搜索的兴趣显著增加。特别是,人们越来越关注何时需要专门的向量数据库,以及何时不需要。

在关注这些模型的同时,我们借此机会回顾向量之前的搜索,探索向量(和嵌入)是什么,了解向量搜索及其应用,以及此功能如何融入更广泛的数据领域。

对于那些已经熟悉基本向量搜索概念并希望直接了解如何在 ClickHouse 中执行向量搜索的读者,您可以在此处找到第二部分此处

向量之前的搜索

让我们简要介绍一下传统引擎(如 Elasticsearch 和 Solr)是如何进行搜索的(注意:这些技术现在也提供了向量搜索功能)。

这些引擎专注于提供文本搜索功能,依靠用户将其内容分解成称为文档的离散文本单元,每个单元都有一个 ID。这些文档可以包含从书籍或网页中的所有文本到单个句子中的任何内容,具体取决于用户需要查找相关内容的粒度(长度也会影响搜索有效性)。

然后,每个文档的文本将通过称为标记化的过程拆分为其组成词,该过程会生成一个词袋。在最简单的形式中,标记化将涉及一个在空格处拆分、小写和删除标点符号的顺序过程。这些词也称为术语,然后将用于构建类似于书籍末尾索引的索引。此索引将包含文本中每个词的计数、它们出现的文档 ID(称为帖子)以及每个术语在文档中出现的频率计数。

bag_of_words_inverted_index.png

请注意,以上内容是一个简化版本,省略了标记化、词干提取、词形还原和停用词等过程的细节,以及用于提供快速搜索的定位索引和巧妙的内部数据结构。

在搜索时,将访问索引并识别匹配的文档。然后将对每个文档执行计算,将搜索文本与文档术语进行比较,以根据相关性对其进行排序。这种“相关性计算”通常基于匹配术语在整个语料库和文档本身中出现的频率。

在更广泛的语料库中很少见但在匹配文档中常见的词,将比诸如“和”之类的通用词对文档得分贡献更大,因为通用词几乎没有意义。这些常用词称为“停用词”,鉴于它们对相关性的贡献较低,可以在一定程度上损失功能的情况下,选择性地从索引中省略。这种在 1970 年代提出的简单观察形成了词频/逆文档频率 (TF/IDF) 公式的基础,该公式虽然简单,但通常很有效。

tf_idf.png

以上内容是一个简化版本。它假设术语之间存在逻辑 AND,并且每个术语的分数只是简单地相加。多术语搜索可以不那么严格,例如 OR,使用更复杂的评分函数,例如BM25,以及组合术语分数的方法。

这种方法面临的挑战是它无法捕捉词语本身的含义或上下文。如果搜索词语靠得很近,位置信息可以使文档权重更高,但这仍然无法捕捉它们之间的语义关系。例如,这种方法无法区分

"猫饶有兴趣地透过窗户看着鸟"和"鸟饶有兴趣地透过窗户看着猫。"

此外,这种方法也存在词汇不匹配问题。更具体地说,如果语料库的词汇与查询文本的词汇不同,用户会发现相关性很差。

虽然手动标记概念、同义词和使用分类法可以部分解决这些挑战,但这些方法不够灵活,难以维护,而且很少能够扩展。重要的是,这种方法仅适用于文本内容,无法(轻松地)应用于其他数据媒介,例如图像。

什么是向量和嵌入?

在我们解释向量如何解决跨词语捕获语义关系并允许搜索更丰富的数据类型的难题之前,让我们从基本原理开始,并提醒自己向量是什么。

在数学和物理学中,向量被正式定义为既有大小又有方向的对象。这通常采用空间中的线段或箭头的形式,可用于表示速度、力加速度等量。在计算机科学中,向量是数字的有限序列。换句话说,它是一种用于存储数值的数据结构。

在机器学习中,向量与我们在计算机科学中讨论的数据结构相同,但其中存储的数值具有特殊的含义。当我们获取一段文本或图像,并将其提炼成它所代表的关键概念时,这个过程称为编码。最终的输出是机器以数值形式表示这些关键概念。这就是嵌入,并存储在一个向量中。换句话说,当这种上下文含义嵌入到一个向量中时,我们可以将其称为嵌入

虽然所有嵌入都是向量,但并非所有向量都是嵌入——可以将向量视为超类,可用于表示任何数据,而嵌入是一种特定类型的向量表示,它针对捕获对象语义或上下文含义进行了优化。

这些嵌入向量通常非常大,长度可能包含数百甚至数千个值。此长度也称为维度,它取决于向量的生成方式及其打算表示的信息。对于大多数数据库(包括 ClickHouse)而言,向量只是一个浮点数数组,即 Array(Float32)

10_dimensional_vector.png

Embedding.png

这里我们将一个单词表示为嵌入,但同样,嵌入也可以表示短语、句子甚至一段文本。通常,特定维度的概念难以推理或附加标签,尤其是在更高维度的情况下,但在组合时可以使单词在概念上得到理解。可能更重要的是,向量还可以用于表示其他数据类型,例如图像和音频。这为搜索历史上对基于倒排索引的方法具有挑战性的格式提供了可能性。

为什么向量和嵌入很有用?

将图像或文本编码为这些通用表示形式,可以比较它们及其所代表的信息,即使内容的原始形式不同。

为了理解如何将向量嵌入相互比较,我们可以将嵌入想象成高维空间中的一个点。两个嵌入将是此空间中的两个点。如果这两个嵌入表示彼此在概念上相似的对象,则这些空间中的点在几何距离和角度上将非常接近。

对于二维或三维空间,我们可以轻松地可视化并理解这种距离。下面,我们假设三个单词“月光”、“手电筒”和“动物”的概念可以在 3 维空间中有效表示。

vector_search.png

不幸的是,三个维度不足以编码大量文本中的所有概念,更不用说图像了!幸运的是,用于计算两个向量之间角度或距离的数学方法(通常是余弦相似度欧几里得距离)可以扩展到 N 维,即使我们人类无法直观地理解它。嵌入通常具有小于 1000 的维度——足以编码文本语料库中的大多数概念。当然,这假设我们可以很好地选择我们的概念并将我们的嵌入准确地编码到空间中。

据估计,多达80%90% 的所有数据都是非结构化的。因此,这种比较能力为神经网络和 LLM 等算法提供了基础,这些算法可以处理历史上对企业而言提取见解并据此做出决策具有挑战性和成本高昂的一类数据。

目前,假设我们有一种使用算法生成这些嵌入的方法,并且已经为我们希望使其可搜索的所有文本生成了嵌入。这样做会让我们得到一组嵌入,可能包含数亿个,甚至数十亿个

当用户想要搜索此文本库(我们现在拥有相应的嵌入)时,需要将用户的搜索本身转换为嵌入。然后,可以将用户的搜索嵌入与文本库的嵌入集进行比较,以找到最接近的匹配项。当然,最接近的匹配嵌入表示与用户搜索最匹配的文本。

最简单的形式是,用户可能只是通过按距离排序来搜索最相关的文档或一组文档,从而复制传统的搜索引擎。但是,这种查找与查询在概念上相似的上下文文档的能力对其他机器学习管道(包括 ChatGPT)很有价值。请记住,嵌入是通过向量空间中它们之间的角度或距离来比较的。

linear_search.png

执行此向量比较过程通常需要一个数据存储,该数据存储可以持久化这些向量,然后公开查询语法,其中可以传递向量或潜在的原始查询输入(通常是文本)。这导致了向量数据库(例如 Pinecone 和 Weviate)的开发,除了简单地存储向量之外,它们还提供了一种将向量生成过程集成到其数据加载管道和查询语法中的方法——从而在数据加载和查询时自动执行嵌入编码过程。同时,现有的搜索引擎(如 Solr 和 Elasticsearch)也增加了对向量搜索的支持,并集成了新的函数以允许用户加载和搜索嵌入。

此外,具有完整 SQL 支持的传统数据库(如 Postgres 和 ClickHouse)也增加了对向量存储和检索的原生支持。在 Postgres 的情况下,这是通过pg_vector实现的。ClickHouse 支持将向量存储为数组列类型(Array<Float32>),并提供计算搜索向量与列值之间距离的函数。

精确结果与估计

当利用支持向量搜索的数据存储时,用户可以使用两种高级方法

  • 使用线性搜索获得精确结果 - 将输入向量与数据库中的每个向量进行完整比较,按最接近的距离对结果进行排序,并限制为 K 个命中。这种方法通常称为 K 最近邻 (KNN),虽然它可以提供精确的结果并保证最佳质量匹配,但通常难以扩展到 1 亿以上,除非对匹配进行大量并行化和/或使用 GPU。根据其定义,匹配时间与需要匹配的向量数量成正比(假设所有其他变量保持不变),即 O(n)。

euclidean.png

  • 使用近似最近邻获得近似结果 - 虽然有时需要完全最接近的匹配,但近似值通常就足够了,尤其是在具有许多高质量匹配的大型数据集上。旨在通过牺牲一定程度的准确性来加快搜索过程的算法,通过降低召回率来换取速度。ANN 算法使用各种技术快速识别最有可能成为查询向量最佳匹配的一小部分最近邻。这可以大大减少搜索大型数据集所需的时间。虽然 ANN 算法可能并不总是返回完全 K 个最近邻,但它们对于许多应用来说通常足够准确。ANN 算法在数据集很大且需要快速执行搜索的应用中很有益。此处的示例包括分层可导航小世界 (HNSW) 和 Annoy 算法。

annoy.png

Annoy 算法 来源:Alexey Milovidov

上图显示了 Annoy 算法。它的工作原理是在语料库上构建基于树的索引。此树结构是通过根据使用的距离度量(通常是欧几里得距离)递归地将数据划分为较小的子空间来构建的。分区过程持续进行,直到子空间包含少量数据点或达到树的特定深度为止。当发出查询时,将从根节点开始遍历树。在树的每一层,选择最接近查询点的节点,并评估其子节点。搜索持续进行,直到到达叶节点,该节点包含最接近查询点的数据点的子集。然后可以通过计算查询点与叶节点中的数据点之间的距离来找到最近邻。

生成嵌入

文本或更丰富的媒体(如图像)的编码详细过程是一个很大的主题,我们将在以后的博文中介绍。总之,这依赖于利用能够识别内容和含义的机器学习算法,为语言或特定领域生成数学表示,称为模型。然后,这些模型可用于将后续文本(或其他资产)转换为向量。基于 Transformer 的模型是已被证明在生成文本内容向量方面特别有效的结构。此类模型的早期版本包括 Google 开发的流行 BERT 模型。Transformer 本身不仅仅是将文本转换为向量,它们也比这更灵活,并且构成了最先进的语言翻译和最近流行的聊天机器人 ChatGPT 的基础。

如前所述,向量超越了概念嵌入。用户还可以选择构建或向向量添加其他特征。这些特征可以通过其他模型学习,或者由特定领域的专家仔细选择,这些专家试图确保两个向量的接近距离捕捉业务问题的含义。请参阅下面的应用以了解一些示例。

图像嵌入的生成也是近年来备受关注的研究领域,卷积神经网络架构在生成嵌入方面的质量方面占据主导地位。最近,Vision Transformer (ViT) 在图像分类和特征提取任务中显示出令人鼓舞的结果,尤其是在大规模数据集上。

多模态模型可以处理和编码多种数据类型,例如图像、文本和音频。例如,它们可以同时为图像和文本生成向量,有效地生成一个联合嵌入空间,以便可以比较两者。这可以用于允许用户使用单词进行搜索并查找在概念上匹配的图像!OpenAI 在 2021 年引入了一种名为CLIP(对比语言-图像预训练)的算法。这种特殊的算法(我们将在以后的文章中使用其嵌入)学习图像及其关联文本标题(在训练期间提供)的联合表示,以便相关图像和标题的嵌入在空间中彼此靠近。除了简单的搜索案例之外,这还允许执行诸如图像字幕零样本图像分类等任务。

clip.png 来源:CLIP - https://openai.com/research/clip

值得庆幸的是,训练模型以生成嵌入并不总是必要的,因为现在有开源的预训练模型可用于生成此类嵌入,可以从Hugging Face等资源下载。这些模型可以在一个称为“迁移学习”或“微调”的过程中,通过最少的额外训练适应新的领域。用户还可以下载数据集的生成嵌入以进行实验。一旦用户生成了或下载了一组嵌入,通常就需要一个存储介质——从而导致采用向量数据库。

这篇博文重点介绍了通过生成向量嵌入、存储和检索来提供语义搜索的概念。除了增强现有的传统企业或应用程序搜索体验之外,此功能还有许多应用。可能的用途包括但不限于

  • 推荐 - 特别适用于电子商务网站,向量搜索可用于查找相关产品。除了将文本含义简单地嵌入到向量中之外,还可以将页面浏览量和过去购买等特征编码到向量中。
  • 问答 - 问答系统历史上一直具有挑战性,因为用户很少使用与问题相同的术语。但是,可以使用彼此接近的向量来编码等价含义,例如 X 和 Y。

  • 图像和视频搜索 - 使用上面描述的多模态模型,用户可以根据文本搜索图像和视频 - 这对于音乐和电影推荐系统、产品推荐和新闻文章推荐等应用非常有用。
  • 欺诈检测 - 通过将用户的行为或登录模式编码成向量,我们可以找到相似或不相似的事务。这些可以识别异常行为并防止欺诈。
  • 基因组分析 - 向量数据库可以用于存储和检索基因组序列的嵌入,这对于基因表达分析、个性化医疗和药物发现等应用很有用。
  • 多语言搜索 - 与为每种语言构建索引(通常是一项昂贵且成本与语言数量成线性关系的操作)不同,多语言模型允许使用相同概念的两种语言编码成相同的向量进行跨语言搜索。
  • 提供上下文 - 最近,向量数据库已被用于为由 ChatGPT 等 API 提供支持的聊天应用程序提供上下文内容。例如,内容可以转换为向量并存储在向量数据库中。当最终用户提出问题时,会查询数据库并识别相关文档。与其直接将这些文档返回给用户,不如将其用于为 ChatGPT 提供更多上下文,以便生成更强大的答案。我们 Supabase 的朋友 最近实现了这样的架构,为他们的文档提供聊天机器人。

结论

在这篇文章中,我们对向量嵌入和向量数据库进行了高级介绍。我们介绍了它们的值以及它们与更传统的搜索方法的关系,以及大规模匹配向量的一般方法 - 无论是精确匹配还是近似匹配。

在我们的 下一篇文章中,我们将探讨 ClickHouse 的实际示例,并回答“何时使用 ClickHouse 进行向量搜索?”这个问题。

有关计算语言理解历史的更多阅读,我们 推荐这篇博文

立即开始使用 ClickHouse Cloud 并获得 300 美元的信用额度。在 30 天试用期结束时,您可以继续使用按需付费计划,或 联系我们 了解有关我们基于容量的折扣的更多信息。请访问我们的 定价页面 获取详细信息。

分享此文章

订阅我们的时事通讯

及时了解功能发布、产品路线图、支持和云产品!
正在加载表单...
关注我们
Twitter imageSlack imageGitHub image
Telegram imageMeetup imageRss image