立即开始使用 ClickHouse Cloud 并获得 300 美元的积分。要了解更多关于我们基于容量的折扣的信息,请联系我们或访问我们的价格页面。
简介
在过去的一年里,大型语言模型 (LLM) 以及 ChatGPT 等产品抓住了全世界的想象力,并且一直在推动基于它们构建的新一波功能。向量和向量搜索的概念是为推荐、问答、图像/视频搜索等功能提供动力的核心。
因此,我们看到社区对向量搜索的兴趣显著增加。特别是,人们越来越关注于更好地理解何时需要专门的向量数据库,以及何时不需要。
随着这些模型成为关注的焦点,我们有机会重新审视向量之前的搜索,探索什么是向量(和嵌入),了解向量搜索、其应用程序以及此功能如何融入更广泛的数据领域。
对于那些已经熟悉基本向量搜索概念并希望直接跳转到如何在 ClickHouse 中进行向量搜索的读者,您可以在此处找到第二部分。
向量之前的搜索
让我们简要介绍一下使用像 Elasticsearch 和 Solr 这样的传统引擎是如何进行搜索的(注意:这些技术现在也提供向量搜索功能)。
这些引擎专注于提供文本搜索功能,依靠用户将他们的内容分解成称为文档的离散文本单元,每个文档都有一个 ID。这些文档可以包含从一本书或网页中的所有文本到单个句子中的任何内容,具体取决于用户需要查找相关内容的粒度(长度也会影响搜索效果)。
然后,来自每个文档的文本将通过称为标记化的过程分解成其组成词,从而产生一个词袋。在最简单的形式中,标记化将涉及按空格、小写和删除标点符号的顺序进行拆分。这些词(也称为词项)将被用于构建类似于书籍末尾索引的索引。此索引将包含文本中每个词的计数,它们出现的文档 ID(称为发布项)以及每个词项在文档中出现的次数。
请注意,以上是简化,省略了标记化、词干提取、词形还原和停用词等过程的细节,以及用于提供快速搜索的职位索引和巧妙的内部数据结构。
在搜索时,将访问索引并识别匹配的文档。然后,将对每个文档执行计算,将搜索文本与文档词项进行比较,以按相关性对它们进行排序。这种“相关性计算”通常基于匹配词项在整个语料库和文档本身中出现的频率。
在更广泛的语料库中很少见但在匹配文档中常见的词,对文档分数的贡献将大于像“and”这样的一般常见词,因为它们几乎没有意义。这些频繁出现的词(称为“停用词”)可以选择性地从索引中省略,因为它们对相关性的贡献很低,但会损失一些特征。这种在 1970 年代做出的简单观察构成了词频/逆文档频率 (TF/IDF) 公式的基础,尽管简单,但往往很有效。
以上是简化。它假设词项之间的逻辑 AND,并且每个词项的分数只是简单的加和。多词搜索可以不太严格,例如 OR,使用更复杂的评分函数,例如BM25,以及组合词项分数的方法。
这种方法的挑战在于它无法捕捉到词语本身的含义或语境。位置信息可以在搜索词项接近时更高地权衡文档,但这仍然无法捕捉到它们之间的语义关系。例如,这种方法无法区分
"猫很有兴趣地通过窗户看着鸟"和"鸟很有兴趣地通过窗户看着猫"。
此外,这种方法还存在词汇不匹配的问题。更具体地说,如果语料库的词汇与查询文本的词汇不同,用户会发现相关性很差。
虽然手动标记概念、同义词和使用分类法可以部分解决这些挑战,但它们不够灵活,难以维护,而且很少扩展。重要的是,这种方法仅适用于文本内容,不能(轻松地)应用于其他数据媒介,例如图像。
什么是向量和嵌入?
在我们解释向量如何解决捕捉跨词语的语义关系和允许搜索更丰富的数据类型的问题之前,让我们从基本原理开始,提醒自己什么是向量。
在数学和物理学中,向量被正式定义为同时具有大小和方向的对象。这通常采取空间中线段或箭头的形式,可用于表示速度、力、加速度等量。在计算机科学中,向量是由有限数量的数字组成的序列。换句话说,它是一种用于存储数值的数据结构。
在机器学习中,向量与我们在计算机科学中讨论的数据结构相同,但存储在它们中的数值具有特殊含义。当我们将一段文本或图像提炼成它所代表的关键概念时,这个过程称为编码。产生的输出是机器以数字形式表示这些关键概念的表示。这就是一个嵌入,并存储在一个向量中。换句话说,当这种上下文含义被嵌入到一个向量中时,我们可以将其称为嵌入。
虽然所有嵌入都是向量,但并非所有向量都是嵌入 - 向量可以看作是超类,它可以用来表示任何数据,而嵌入是向量表示的一种特定类型,它针对捕获对象的语义或上下文含义进行了优化。
这些嵌入向量通常相当大,可以有数百甚至数千个值。这种长度(也称为维数)根据向量的生成方式和它们要表示的信息而异。对于大多数数据库(包括 ClickHouse)来说,向量只是一个浮点数数组,即 Array(Float32)
。
我们将词语表示为嵌入,同样的,嵌入也可以代表短语、句子甚至一段文字。通常特定维度上的概念难以理解或标记,尤其是在高维情况下,但允许将词语在组合时进行概念化理解。可能更重要的是,向量还可以用于表示其他数据类型,例如图像和音频。这打开了搜索格式的可能性,而这些格式在历史上对于基于倒排索引的方法来说是具有挑战性的。
为什么向量和嵌入很有用?
将图像或文本编码为这些通用表示形式,允许对它们及其所代表的信息进行比较,即使内容的原始形式不同。
为了理解如何将向量嵌入相互比较,我们可以将嵌入想象成高维空间中的一个点。两个嵌入将是这个空间中的两个点。如果这两个嵌入代表彼此在概念上相似的对象,那么空间中的这些点在距离和角度上将几何上接近。
对于二维或三维,我们可以轻松地可视化并理解这种距离。下面,我们假设三个词语“月光”、“手电筒”和“动物”的概念可以在 3 维空间中有效地表示。
不幸的是,三维空间不足以编码大量文本中的所有概念,更不用说图像了!幸运的是,用于计算两个向量之间角度或距离的数学(通常是余弦相似度或欧氏距离)可以扩展到 N 维,即使我们人类无法直观地理解它。嵌入通常具有小于 1000 的维度 - 足以编码文本语料库中的大多数概念。当然,这假设我们能够很好地选择我们的概念并准确地将我们的嵌入编码到空间中。
据估计,高达80%到90% 的所有数据都是非结构化的。因此,这种比较功能为神经网络和大型语言模型 (LLM) 等算法奠定了基础,这些算法可以处理一类数据,而这些数据在历史上对企业来说提取见解和作为决策基础是具有挑战性和成本高昂的。
执行向量搜索
现在,假设我们有一种方法可以使用算法生成这些嵌入,并且已经对我们希望进行搜索的所有文本进行了此操作。这样做留给我们一组嵌入,其长度可能在数亿甚至数十亿。
当用户想要搜索这个文本库(我们现在有相应的嵌入)时,用户的搜索需要被转换为一个嵌入。然后,用户的搜索嵌入可以与文本库的嵌入集进行比较,以找到最接近的匹配。最匹配的嵌入当然代表与用户搜索最匹配的文本。
在最简单的形式中,用户可能只是通过按距离排序来搜索最相关的文档或一组文档,从而复制传统的搜索引擎。但是,这种找到与查询在概念上相似的上下文文档的能力对其他机器学习管道,包括 ChatGPT 有价值。记住,嵌入在向量空间中通过它们之间的角度或距离进行比较。
执行此向量比较过程通常需要一个数据存储,它可以持久化这些向量,然后公开一个查询语法,在其中可以传递向量或潜在的原始查询输入(通常是文本)。这导致了向量数据库的开发,例如 Pinecone 和 Weviate,它们不仅仅简单地存储向量,还提供了一种将向量生成过程集成到其数据加载管道和查询语法中的方法 - 从而自动在数据加载和查询时执行嵌入编码过程。同时,现有的搜索引擎,例如 Solr 和 Elasticsearch,添加了对向量搜索的支持,其中包含新的函数,允许用户加载和搜索嵌入。
此外,具有完整 SQL 支持的传统数据库,例如 Postgres 和 ClickHouse,添加了对向量存储和检索的原生支持。在 Postgres 的情况下,这是通过pg_vector实现的。ClickHouse 支持将向量存储为数组列类型 (Array<Float32>),提供函数来计算搜索向量与列值之间的距离。
精确结果与估计
当使用支持向量搜索的数据存储时,用户可以选择两种高级方法:
- 使用线性搜索获取精确结果 - 将输入向量与数据库中的每个向量进行完整比较,按最接近的距离排序结果并限制为 K 个命中。这种方法通常称为 K 最近邻 (KNN),尽管它提供了精确的结果,并保证了最佳质量匹配,但在不进行大量匹配并行化或使用 GPU 的情况下,通常无法轻松扩展到 1 亿以上。根据定义,匹配时间与需要匹配的向量数量成正比(假设所有其他变量都保持不变),即 O(n)。
- 使用近似最近邻获取近似结果 - 虽然有时需要完全最接近的匹配,但近似值通常就足够了,尤其是在具有许多高质量匹配的大型数据集上。旨在通过牺牲一定程度的准确性来加快搜索过程的算法,通过降低召回率来提高速度。ANN 算法使用各种技术来快速识别一小部分最接近的邻居,这些邻居可能是查询向量最佳匹配的可能性最大。这可以显著减少搜索大型数据集所需的时间。虽然 ANN 算法可能并不总是返回完全最接近的 K 个邻居,但它们通常对于许多应用程序来说足够准确。ANN 算法在数据集很大且需要快速执行搜索的应用程序中很有用。此处的示例包括分层可导航小世界 (HNSW) 和 Annoy 算法。
Annoy 算法 来源:Alexey Milovidov
上图显示了 Annoy 算法。它的工作原理是在语料库上构建基于树的索引。这个树结构是通过基于所使用的距离度量(通常是欧氏距离)递归地将数据划分为更小的子空间来构建的。划分过程持续进行,直到子空间包含少量数据点或达到树的某个深度。当发出查询时,会从根节点开始遍历树。在树的每一层,选择距离查询点最近的节点,并评估其子节点。搜索持续进行,直到到达叶节点,该节点包含距离查询点最近的数据点子集。然后可以通过计算查询点与叶节点中的数据点之间的距离来找到最近的邻居。
生成嵌入
编码文本或更丰富媒体(如图像)的详细过程是一个大的主题,我们将留待以后的博文介绍。总之,这依赖于使用能够识别内容和含义的机器学习算法,为语言或特定领域生成数学表示,称为模型。这些模型可以用来将后续文本(或其他资产)转换为向量。基于 Transformer 的模型是已被证明在为基于文本的内容生成向量方面特别有效的结构。该类别的早期版本包括由 Google 开发的流行的 BERT 模型。Transformer 本身比简单地将文本转换为向量更灵活,并且构成了最先进的语言翻译和最近流行的聊天机器人 ChatGPT 的基础。
如前所述,向量超越了概念嵌入。用户也可以选择构建或添加其他特征到向量。这些特征可以通过其他模型学习,也可以由试图确保两个向量的接近距离反映业务问题含义的特定领域专家仔细选择。请参阅下面的应用程序,以获取一些示例。
图像嵌入的生成也是近年来受到高度关注的研究领域,卷积神经网络架构在生成嵌入方面以其质量而占据主导地位。最近,视觉 Transformer (ViT) 在图像分类和特征提取任务中表现出了良好的效果,尤其是在大型数据集上。
多模态模型可以处理和编码多种数据类型,例如图像、文本和音频。例如,它们可以为图像和文本生成一个向量,有效地生成一个联合嵌入空间,在那里它们都可以进行比较。这可以用来允许用户使用词语进行搜索并找到概念上匹配的图像!OpenAI 在 2021 年发布了一种名为CLIP(对比语言图像预训练)的算法。这种特殊的算法(我们将在以后的博文中使用其嵌入)学习图像及其关联的文本标题(在训练期间提供)的联合表示,使得相关图像和标题的嵌入在空间中彼此靠近。除了简单的搜索用例之外,这还允许执行图像字幕和零样本图像分类等任务。
来源:CLIP - https://openai.com/research/clip
幸运的是,训练一个模型来生成嵌入并不总是必要的,因为现在已经有一些开源的预训练模型可以用来生成这些嵌入,可以从Hugging Face等资源中下载。这些模型可以在一个称为“迁移学习”或“微调”的过程中,通过最少的额外训练来适应新领域。用户还可以下载为数据集生成好的嵌入以供实验。一旦用户生成了或下载了一组嵌入,通常需要一个存储介质 - 这导致了向量数据库的采用。
向量搜索的示例应用程序
这篇博文重点介绍了通过生成向量嵌入、存储和检索来提供语义搜索的概念。除了增强现有的传统企业或应用程序搜索体验之外,这种功能还有许多应用。可能的用途包括但不限于
- 推荐 - 特别适用于电子商务网站,向量搜索可用于查找相关产品。除了将文本含义嵌入到向量中之外,还可以将页面浏览量和过去购买等特征编码到向量中。
- 问答 - 问答系统在历史上一直具有挑战性,因为用户很少使用与问题相同的术语。但是,可以用彼此接近的向量来编码等效的含义,例如 X 和 Y。
- 图像和视频搜索 - 使用上面描述的多模态模型,用户可以根据文本搜索图像和视频 - 这对于音乐和电影推荐系统、产品推荐和新闻文章推荐等应用非常有用。
- 欺诈检测 - 通过将用户的行为或登录模式编码为向量,我们可以找到相似或不相似的事务。这些可能是异常行为,可以防止欺诈。
- 基因组分析 - 向量数据库可以用来存储和检索基因组序列的嵌入,这对基因表达分析、个性化医疗和药物发现等应用很有用。
- 多语言搜索 - 与其为每种语言建立索引(通常是一项昂贵的操作,成本与语言数量成正比),多语言模型允许使用相同的概念在两种语言中进行跨语言搜索,并将它们编码为相同的向量。
- 提供上下文 - 最近,向量数据库被用于为由 ChatGPT 等 API 提供支持的聊天应用程序提供上下文内容。例如,内容可以被转换为向量并存储在向量数据库中。当最终用户提出问题时,数据库会被查询,并识别相关的文档。这些文档不会直接返回给用户,而是用于为 ChatGPT 提供额外的上下文,以便生成更可靠的答案。我们 Supabase 的朋友 最近实现了这种架构,为他们的文档提供了一个聊天机器人。
结论
在这篇文章中,我们对向量嵌入和向量数据库进行了高级介绍。我们涵盖了它们的价值以及它们与传统搜索方法的联系,以及大规模匹配向量的通用方法 - 无论是精确匹配还是近似匹配。
在我们的 下一篇文章中,我们将探讨 ClickHouse 的实际示例,并回答“何时将 ClickHouse 用于向量搜索?”这个问题。
有关计算语言理解历史的更多阅读材料,我们 推荐这篇文章。
立即开始使用 ClickHouse Cloud 并获得 300 美元的积分。在您 30 天的试用期结束后,您可以继续使用按需付费计划,或者 联系我们 了解有关我们基于使用量的折扣的更多信息。访问我们的 价格页面 了解更多详情。