0

如何使用向量数据库为您的语义搜索注入超能力 向量空间讲座

Demetrios Brinkmann

·

2024年1月9日

How to Superpower Your Semantic Search Using a Vector Database Vector Space Talks

如何与 Nicolas Mauti 一起使用向量数据库为您的语义搜索注入超能力

“我们在 Qdrant 中找到了性能与精度之间的权衡,这比我们在 Elasticsearch 中找到的权衡更适合我们。”
– Nicolas Mauti

希望在自由职业者搜索中获得精度和性能?Malt 迁移到 Qdrant 数据库是明智之举,提供了地理空间过滤和无缝扩展。Malt 的 Nicolas Mauti 及其团队是如何确定需要为其自由职业者匹配应用程序过渡到检索器-排序器架构的?

Nicolas Mauti 毕业于里昂国立应用科学学院(INSA Lyon)工程学校计算机科学专业,从软件开发转向数据领域。他于 2021 年加入 Malt 担任数据科学家,专门研究自由职业者与公司市场中的推荐系统和自然语言处理模型。随着发展,Nicolas 成为一名 MLOps 工程师,熟练地结合数据科学、开发和运维知识,以增强 Malt 的模型开发工具和流程。此外,自 2020 年以来,他还在一所法国工程学校兼职授课。值得一提的是,在 2023 年,Nicolas 在 Malt 成功大规模部署了 Qdrant,为新匹配系统的实施做出了贡献。

您可以在 Spotify、Apple Podcast、Podcast addicts、Castbox 上收听本集。您也可以在 YouTube 上观看本集。

主要收获

深入了解 Malt 的 MLOps 工程师 Nicolas Mauti 如何增强语义搜索的复杂细节。了解 Nicolas 及其团队在 Malt 如何彻底改变自由职业者与项目对接的方式。

在本集中,Nicolas 深入探讨了 Malt 如何通过实施包含多语言 Transformer 模型的检索器-排序器架构来增强语义搜索,通过迁移到 Qdrant 将自由职业者与项目匹配的延迟从 10 秒缩短到 1 秒,并提升了平台的整体性能和扩展能力。

从本集中学习的 5 个要点

  1. 性能提升策略:了解 Malt 由于自由职业者数量扩展到五十多万而面临的延迟增加的技术挑战,以及他们采取的解决方案。
  2. 高级匹配架构:了解 Malt 采用的检索器-排序器模型,该模型结合了语义搜索和 KNN 搜索,以提高项目与自由职业者配对的效率。
  3. 前沿模型训练:了解多语言 Transformer 编码器的部署,该编码器能有效地创建高保真嵌入,从而简化匹配过程。
  4. 数据库选择过程:Mauti 讨论了影响 Malt 选择数据库系统的因素,这些因素有助于在高性能和准确过滤能力之间取得平衡。
  5. 运营改进:了解 Malt 在部署后取得的显著进展,包括应用程序延迟的显著降低及其对可扩展性和匹配质量的积极影响。

趣闻:Malt 使用多语言 Transformer 编码器模型生成 384 维嵌入,从而提高了他们的语义搜索能力。

讲座笔记

00:00 匹配应用遇到严重的性能问题。
04:56 过滤自由职业者并采用检索器-排序器架构。
09:20 用于调整语义空间的多语言编码器模型。
10:52 查看、重新训练、分类和组织自由职业者的回复。
16:30 地理空间过滤数据库的麻烦
17:37 搜索算法的性能和精度基准测试。
21:11 部署在 Kubernetes 中。存储在 Git 仓库中,与 Argo CD 同步。
27:08 快速提高了延迟,验证了架构,并协调了步骤。
28:46 邀请讨论使用特定方法的工作。

更多来自 Nicolas 的引言

“所以 GitHub 的方法基本思想是,你的 git 仓库是你 Kubernetes 集群中必须拥有的东西的真相来源。”
– Nicolas Mauti

“所以我们可以看到,我们的空间似乎组织得很好,技术类自由职业者彼此接近,而平面设计师等等则离技术大家庭很远。”
– Nicolas Mauti

“还有一件事让我们很感兴趣,那就是它是多语言的。而且由于 Malt 是一家欧洲公司,我们必须拥有一个多语言模型。”
– Nicolas Mauti

文字记录

Demetrios:我们正在直播。我们本人就在直播。Nicholas,很高兴你来到这里,伙计。欢迎所有向量空间的探索者。我们又回来了,带来了另一期向量空间讲座。今天我们要讨论如何与我的伙计 Nicholas,Malt 的一名 ML 运维工程师,一起为你的语义搜索注入超能力,如果你不了解 Malt 在做什么的话。他们正在进行配对,他们正在创建一个市场。他们连接自由职业者和公司。

Demetrios:Nicholas,你在推荐系统方面做了很多工作,对吗?

Nicolas Mauti:是的,没错。

Demetrios:太棒了。好吧,正如我提到的,我现在处在一个有趣的地方,因为我正在听你讲座的同时,尽量多吸收一些维生素 D。所有正在和我们一起收听的朋友,请参与进来。告诉我们你在哪里收听或观看。也请随时在聊天中提问。如果需要的话,我会插话并打断 Nicholas。但我知道你为我们准备了一个小小的演示,伙计,你想开始吗?

Nicolas Mauti:谢谢你的介绍,大家好。当然,也谢谢你们邀请我来做这个讲座。那么,我们开始吧。开始!

Demetrios:我喜欢!超能力。

Nicolas Mauti:是的,本次演示结束时,我们将拥有超能力。那么,大家好。我想介绍已经由 Dimitrios 完美完成了。我是 Nicola,是的,我在 Malt 担任 ML 运维工程师。此外,我还在一所法国工程学校兼职教学,教授一些 ML 运维课程。那么,让我们深入今天的主题。事实上,正如 Dimitrio 所说,Malt 是一个市场,因此我们的目标是一方面将自由职业者进行匹配。这些自由职业者有很多属性,例如描述、一些技能和一些很棒的技能。他们还有一些偏好,以及一些并非专门针对语义的属性。因此,这将是今天我们话题的关键点。另一方面,我们有所谓的公司提交的项目。这些项目也有很多属性,例如描述、需要寻找的技能以及一些偏好。因此,我们最终的目标是在这两个实体之间执行匹配。为此,我们已经有一个匹配应用在生产中。事实上,我们这个应用有一个主要问题,就是它的性能,因为它变得非常慢。P50 延迟约为 10 秒。

Nicolas Mauti:你们从中需要记住的是,如果你们的延迟过高,将无法执行某些场景。有时你们希望有一个同步场景,填写完项目后,立刻就能看到与该项目匹配的自由职业者。如果花费太多时间,你们就无法实现这一点。因此,你们将不得不采用异步场景,例如通过电子邮件等。这不是一个很好的用户体验。而且这个问题也因为平台的指数增长而加剧。没错,我们正在增长。给你们一些数字,我两年前来的时候,我们的自由职业者数量是现在的一半。而今天,今天我们在库里有大约 60 万自由职业者。所以它正在增长。伴随这种增长,我们遇到了一些问题。

Nicolas Mauti:关于这个匹配应用,我们必须记住一件事。它不仅仅是一个语义应用,这个应用中有两件事不是语义的。我们有所谓的硬性过滤器。硬性过滤器是 Malt 项目团队定义的硬性规则。这些规则很严格,我们必须遵守。例如,在 Malt,我们有一个本地化策略,所以我们希望提供项目附近的自由职业者。因此,我们需要过滤自由职业者,并为此设置硬性过滤器,确保我们遵守这些规则。另一方面,正如 Demetrius 你所说,我们在这里谈论的是推荐系统。在一个推荐系统中,你们还需要考虑其他一些参数,例如自由职业者的偏好,以及自由职业者在平台上的活动情况等等。因此,在我们的系统中,我们必须牢记这一点并使其正常工作。

Nicolas Mauti:所以如果我们概览一下我们的系统是如何工作的,我们一开始有一个带有硬性过滤器的 API,然后是主要基于语义的 ML 模型,然后是一些带有其他参数的重新评分函数。因此,我们决定重塑这个架构,采用检索器-排序器架构。在这种架构中,您将拥有自由职业者池。这里是您的整个数据库,也就是您的 60 万自由职业者。然后您将有一个称为检索的第一步,我们将从中挑选一部分自由职业者。然后您可以应用您的排序算法。这基本上就是我们目前的应用。所以第一步,从语义上讲,它会很快,而且必须快,因为您必须快速筛选出您更感兴趣的自由职业者,并且它旨在提高召回率,因为在这一步您要确保您选择了所有相关的自由职业者,并且不希望在此步排除任何相关的自由职业者,因为排序无法将这些自由职业者重新纳入。另一方面,排序可以包含更多特征,不仅仅是语义,它对时间要求较低。如果您的检索部分总是给出固定数量的自由职业者,那么您的排序就不需要扩展,因为您的输入中总是有相同数量的自由职业者。这一步旨在提高准确率。

Nicolas Mauti:在这一点上,您不希望保留不相关的自由职业者,您必须能够对他们进行排序,并且在这一部分您必须达到最先进的水平。所以让我们关注第一部分。这正是我们今天感兴趣的内容。所以对于第一部分,事实上,我们必须构建这个语义空间,在这个空间中,技能或工作相似的自由职业者在这个空间中也相互接近。因此,我们将构建这个语义空间。然后当我们收到一个项目时,我们只需将这个项目投射到我们的空间中。之后,您只需进行搜索,进行 KNN(最近邻)搜索。实际上我们不做 KNN 搜索,因为它太昂贵了,但我们做 ANN(近似最近邻)搜索。请记住这一点,这将在我们后面的幻灯片中很有趣。

Nicolas Mauti:因此,为了获得这个语义空间并进行搜索,我们需要两样东西。第一是模型,因为我们需要一个模型来计算向量,并将我们的机会、项目和自由职业者投射到这个空间中。另一方面,您需要一个工具来操作这个语义步骤。也就是说,存储向量并执行搜索。对于第一部分,也就是模型,我会快速介绍一下我们是如何构建它的。这一部分更多是数据科学家负责的。数据科学家从一个 E5 模型开始。E5 模型为您提供关于语言的通用知识。另外,吸引我们的一点是它是多语言的。由于 Malt 是一家欧洲公司,我们必须拥有一个多语言模型。在此基础上,我们构建了基于 Transformer 架构的自己的编码器模型。这个模型负责适应 Malt 的案例,并将这个非常通用的语义空间转化为用于技能和工作的语义空间。这个模型还能够考虑自由职业者个人资料的结构,因为您有描述、工作、一些技能、一些经验。所以这个模型能够将这些因素考虑进去。关于训练,我们使用平台上的历史互动来训练它。当自由职业者收到项目时,他可以选择接受或不接受。所以我们用这些来训练模型。最终我们得到了 384 维的嵌入向量。

Demetrios:我这边有个问题,抱歉现在打断你。你们会进行任何类型的评审或反馈,并将其添加到模型中吗?

Nicolas Mauti:是的。事实上,我们会继续收到自由职业者的一些回复。因此,我们也会对它们进行评审,有时是手动评审,因为有时回复不太好,或者我们没有得到我们想要的确切信息等等,所以我们可以评审它们。此外,我们还会定期重新训练模型,这样我们就可以纳入自由职业者的新反馈。

Nicolas Mauti:所以现在我们有了模型,如果我们想看看它是什么样子的。这里我画了一些点,并根据自由职业者的类别对它们进行了着色。所以在平台上,自由职业者可以有类别,例如技术类、图形设计类或即将有的设计师类等等。所以我们可以看到,我们的空间似乎组织得很好,技术类自由职业者彼此接近,而例如平面设计师则远离技术大家庭。

Nicolas Mauti:所以它看起来组织得很好。现在我们有了一个好的模型。好吧,现在我们有了模型,我们必须找到一种方法来操作它,也就是存储这些向量并执行搜索。因此,向量数据库似乎是一个不错的选择。但如果你关注新闻,你会发现向量数据库非常流行,市场上有很多参与者。所以很难找到你心仪的那一个。我会尽量告诉你们我们有哪些标准,以及为什么最终选择了 Qdrant。所以我们的第一个标准是性能。

Nicolas Mauti:我想我之前已经说过这些点了,但是的,我们需要性能。第二个标准是 ANN(近似最近邻)质量。正如我之前所说,我们不能每次都进行 KNN 搜索,即暴力搜索。所以我们必须找到一种近似的方法,但要足够接近,并且在这些方面足够好。否则我们就无法发挥模型的性能优势。最后一个,我之前没有详细谈论过,是过滤。过滤对我们来说是一个大问题,因为我们有很多过滤器,硬性过滤器,正如我之前所说。所以如果我们考虑我的架构,我们可以说,好的,那么过滤就不是问题。您只需一个三步流程:过滤、语义搜索,然后排序;或者语义搜索、过滤,然后排序。但在两种情况下,如果这样做,您都会遇到一些麻烦。

Nicolas Mauti:第一种是如果你想应用预过滤。也就是过滤、语义搜索、排序。如果你这样做,事实上,你将会有,我们会拥有这种架构。如果你这样做,你实际上需要在使用向量数据库并执行搜索之前,给每个自由职业者打上标记,标记他们是否可能被选中。这样,你基本上会在你的自由职业者池上创建一个二进制掩码。随着你拥有的自由职业者数量增长,你的二进制掩码也会增长。所以它不是很具可扩展性。关于性能,随着你的自由职业者库增长,性能会下降。而且你还会遇到另一个问题。许多向量数据库,Qdrant 是其中之一,使用 HNSW 算法进行 ANN 搜索。这类算法基于图。如果你这样做,你会在图中停用一些节点,你的图会变得不连通,你将无法在图中导航。所以你的匹配质量会下降。因此,应用预过滤绝对不是一个好主意。

Nicolas Mauti:所以,不,如果我们在这里进行后过滤,我认为问题更清楚。您将拥有这种架构。事实上,如果您这样做,您将不得不从您的向量数据库中检索大量的自由职业者。如果您应用了非常严格的过滤并且通过过滤排除了大量的自由职业者,您将不得不向您的向量数据库请求大量的自由职业者,因此您的性能将受到影响。所以过滤是个问题。我们不能进行预过滤或后过滤。因此,我们必须找到一个能够同时进行过滤、匹配以及语义匹配和搜索的数据库。Qdrant 是其中之一,市场上还有其他一些数据库。但在我们的案例中,有一个过滤器给我们带来了很多麻烦。这个过滤器就是地理空间过滤,很少有数据库支持这种过滤,我认为 Qdrant 是其中一个支持它的。但支持它们的数据库并不多。而我们绝对需要这个,因为我们采取本地化策略,我们希望确保推荐项目附近的自由职业者。所以现在我说完了所有这些,我们有三个候选数据库进行了测试和基准测试。我们有 Elasticsearch、PGvector(它是 PostgreSQL 的一个扩展)和 Qdrant。在这张幻灯片上,您可以看到例如 Pinecone,Pinecone 被排除是因为缺乏地理空间过滤。

Nicolas Mauti:因此,我们对它们进行了 QPS(每秒查询次数)的基准测试。这是关于性能的,您可以看到 Qdrant 远远领先于其他数据库,我们还对其精度进行了基准测试,我们如何计算精度,我们使用了一个叫做 Textmax 的语料库,Textmax 语料库提供了 100 万个向量和 1000 个查询。对于每个查询,您都有最接近向量的真实结果。他们为此使用了暴力 KNN。我们将这些向量存储在我们的数据库中,运行查询,并检查我们找到的多少向量在真实结果中。这样,他们就为您提供了 ANN 算法精度的衡量标准。对于这个指标,您可以看到 Elasticsearch 比 Qdrant 稍微好一些,但实际上我们能够微调 HNSW 算法的参数和索引。最终,我们在 Qdrant 中找到了一个更好的权衡点,我们在性能和精度之间找到了一个对我们来说比在 Elasticsearch 中找到的更好的权衡点。

Nicolas Mauti:所以最终我们决定选择 Qdrant。我想我们现在都了解了,我们有了模型,并且有了操作它们、操作我们模型的工具。所以本次演示的最后一部分将是关于部署。我会稍微谈谈它,因为我认为它很有趣,而且它也是我作为 ML 运维工程师工作的一部分。关于部署,首先我们决定将 Qdrant 部署在集群配置中。我们决定从三个节点开始,然后我们将我们的集合。所以在 Qdrant 中,集合是存储所有向量的地方,就像 SQL 中的表或 Elasticsearch 中的索引一样。我们决定将我们的集合分成三个节点。这就是我们所说的分片。所以在每个节点上您都有一个集合的分片,然后对于每个分片,您有一个副本。副本基本上是分片的一个副本,它位于与主分片不同的另一个节点上。这样,您就在另一个节点上拥有了一个副本。所以在正常操作条件下,您的查询将分散到三个节点上,您也将相应地获得响应。但有趣的是,如果我们丢失了一个节点,例如这个节点,可能是因为我们正在执行滚动升级,或者因为 Kubernetes 总是终止 Pod,我们仍然能够正常运行,因为我们有副本可以获取数据。所以这个配置非常健壮,我们对此非常满意。

Nicolas Mauti:关于部署。正如我所说,我们将其部署在 Kubernetes 中。我们使用了 Qdrant 的官方 Helm Chart。事实上,我们对其进行了子图定制,因为我们需要在集群中添加一些额外的组件和一些自定义配置。我之前没有谈到这一点,但 Helm Chart 就是一堆 Yaml 文件,它们描述了您在集群中运行数据库所需的 Kubernetes 对象,它是一组文件和模板。当您拥有这些文件后,在 Malt,我们使用一种称为 GitHub 的方法。所以 GitHub 的方法基本思想是,你的 git 仓库是关于你 Kubernetes 集群中必须拥有的东西的真相来源。我们将这些文件和 Helm Chart 存储在 git 中,然后我们有一个名为 Argo CD 的工具,它会在某个时间拉取我们的 git 仓库,并检查我们在 git 中的内容与我们在集群中的内容以及集群中正在运行的内容之间的差异。然后它会直接将我们在 git 中的内容同步到我们的集群中,无论是自动还是手动进行。

Nicolas Mauti:所以这是一种非常好的协作方式,可以确保 git 中的内容与您集群中的内容一致。并且只需查看 git 仓库即可确定集群中的状态。我想这就是我所要说的全部了,还有最后一张幻灯片,我想您会感兴趣。它是关于项目成果的,因为我们在 Malt 做了这些。我们构建了这个架构,第一阶段使用 Qdrant 进行语义匹配并应用我们所有的过滤器。第二部分我们保留了我们原有的排序系统。所以如果我们看看我们应用的延迟,我们应用的 P50 延迟,这是一个包含两个步骤、过滤器、语义匹配和排序的完整应用。如您所见,我们在 10 月中旬开始了 A/B 测试。在那之前延迟约为 10 秒,正如我在演讲开始时所说。然后我们已经看到了应用延迟的巨大下降,我们决定在 12 月全面上线,然后我们看到了另一个大幅下降。所以我们之前大约是 10 秒,现在大约是 1 秒多一点。所以我们将延迟缩短了五倍以上。这对我们来说是非常好的消息,首先它更具可扩展性,因为检索器非常可扩展,并且通过 Qdrant 的集群部署,如果需要,我们可以添加更多节点来扩展这个阶段。之后,进入匹配部分的自由职业者数量是固定的。所以匹配部分就不需要扩展了。

Nicolas Mauti:另一个好消息是,既然我们能够扩展并且第一部分之后有了固定的输入大小,我们就可以构建更复杂、更好的匹配模型,并且我们将能够提高匹配的质量,因为现在我们能够扩展并处理更多的自由职业者。

Demetrios:太不可思议了。

Nicolas Mauti:是的,当然。这对我们来说是个非常好的消息。就这样了。所以可能你们有很多问题,我们可以接着讨论。

Demetrios:好的,首先,我想向可能正在观看或阅读此文的自由职业者喊话,现在正是加入 Malt 的好时机,我想。它似乎每天都在变得更好。我知道会有问题不断涌入,但我们已经收到了 Luis 的一个问题。你好,Luis!他问在考虑 Qdrant 之前,你们实际使用的是哪个库或服务来处理 ANN(近似最近邻搜索)。

Nicolas Mauti:所以在那之前,我们没有使用任何库或服务,或者说我们没有像现在这样进行 ANN 搜索或语义搜索。我们只有一个模型,将自由职业者和项目同时输入模型,最后得到相关性评分。这就是为什么它也很慢,因为您必须构建每个对,并将每个对发送到您的模型。而现在我们无需这样做,所以它好多了。

Demetrios:是的,这说得通。我这边有个问题是,你们花了多久?你好像说过 10 月份开始 A/B 测试,然后 12 月份才推广开来。你最后那张幻灯片是什么?

Nicolas Mauti:是的,就是那张。

Demetrios:为什么会有犹豫?为什么从 10 月到 12 月才推广?你对哪一部分不确定?因为看起来你那里看到了巨大的下降,那为什么还要等到 12 月呢?

Nicolas Mauti:是的,关于延迟和延迟的下降,结果非常快就明确了。我想也许一周后,我们就确信延迟变好了。首先,我们的想法是验证架构,但第二个原因是确保我们没有降低匹配的质量,因为我们有一个两步流程。风险在于两个模型可能互不一致。因此,如果你的第一步和第二步的交集不够好,你最终只会得到空结果,因为你的第一部分会选择一部分自由职业者,第二部分会选择另一部分,然后它们的交集是空的。所以我们的目标是评估这两个步骤是否一致,从而我们没有降低匹配的质量。考虑到我们拥有的项目数量,我们不得不等待大约两个月。

Demetrios:完全说得通。好吧,伙计,我非常感谢你的分享。你能回到展示如何联系你的那张幻灯片吗?如果他们想联系并进一步交流的话。我鼓励大家这样做。非常感谢,Nicholas。这太棒了,伙计。

Nicolas Mauti:谢谢。

Demetrios:好的,各位。顺便说一句,如果你想加入我们,谈谈你正在做什么工作,以及你如何使用 Qdrant,或者你在语义空间或语义搜索或向量空间等有趣的事情,请联系我们。我们非常欢迎你来到这里。Nicholas,最后一个问题给你。有人提问了。你使用什么索引方法?它适合使用 OpenAI 嵌入向量吗?

Nicolas Mauti:所以,在我们的案例中,我们有自己的模型来构建嵌入向量。

Demetrios:是的,我记得你一开始就说过。好的,太棒了。好的,伙计,非常感谢,我们下周再见,带来另一期向量空间讲座。感谢大家的加入,请保重。保重。谢谢。

免费开始使用 Qdrant

开始使用

以先进、高性能的向量相似性搜索技术赋能下一代 AI 应用。

Qdrant 向量数据库

Qdrant 云

Qdrant 混合云

Qdrant 企业解决方案

高级搜索

推荐系统