FastEmbed: 快速轻量级向量生成 - Nirant Kasliwal | 向量空间讲座
Demetrios Brinkmann
·January 09, 2024

“当事物真正相似时,或者我们如何定义相似性。它们彼此靠近;如果它们不相似,则彼此远离。这就是模型或向量模型试图做的事情。”
– Nirant Kasliwal
听说过 FastEmbed 吗?它是一个颠覆者。Nirant 分享了改进向量模型的技巧。你可能想试试!
FastEmbed 的创建者和维护者 Nirant Kasliwal 在 OpenAI Cookbook 的 Finetuning Cookbook 中做出了杰出贡献。他的贡献延伸到自然语言处理(NLP)领域,其 NLP 书籍已售出 5000 多册。
在 Spotify、Apple Podcast、Podcast addicts、Castbox 上收听本期节目。你也可以在 YouTube 上观看本期节目。
主要要点
Qdrant 的 AI 工程师 Nirant Kasliwal 加入我们的向量空间讲座,深入探讨 FastEmbed,这是一种闪电般快速生成向量的方法。
在本期节目中,Nirant 分享了见解、技巧以及增强向量生成的创新方法。
从本期节目中学习的 5 个要点
- Nirant 介绍了一些改进向量模型的“黑客”技巧——你一定不想错过这些!
- 了解量化向量模型如何提升 CPU 性能。
- 了解对 GPU 友好的量化模型的未来计划。
- 了解如何在 Qdrant 中根据 MTEB 基准选择默认模型,以及如何针对特定领域任务校准它们。
- 了解 Fast Embed(Nirant 创建的一个 Python 库)如何解决向量创建中的常见挑战,并提高你工作负载的速度和效率。
有趣的事实:生产环境中使用的最大 header 或 adapter 大小仅为 400-500 KB——证明越大并不总是越好!
节目笔记
00:00 Nirant 在向量空间讲座中讨论 FastEmbed。
05:00 Token 在 OpenAI 中既昂贵又缓慢。
08:40 FastEmbed 快速且轻量。
09:49 支持多模态向量是我们的计划。
15:21 没有发现。正在增强模型下载和性能。
16:59 向量创建在你的自有计算资源上进行,而非云端。控制和简洁性优先。
21:06 Qdrant 在向量相似度搜索方面速度很快。
24:07 工程师思维:做出有依据的猜测,设定预算。
26:11 使用问题和线性层优化向量。
29:55 使用混合精度向量进行快速、廉价的推理。
Nirant 的更多引语
“有一种学术的视角,有一种工程师的视角,还有一种‘黑客’的视角。我将按顺序给你这三种答案。”
– Nirant Kasliwal
“现在工程师的思维告诉你,构建某物的最佳方法是根据你预见的潜在工作负载或挑战,做出有依据的猜测。对吧。就像土木工程师建造一座桥梁时会考虑预计有多少车辆通过,他们显然不会建造一座能承载整船货物或一架飞机重量的桥梁,那是完全不同的。所以你以此为起点,然后说,好吧,这是我预期的请求数量,这是我的预算,而你的预算通常会涉及到延迟预算、计算资源和内存预算。”
– Nirant Kasliwal
“我认为更准确的说法是,我们更有效地利用了 CPU。”
– Nirant Kasliwal
文字稿
Demetrios: 欢迎大家回到另一场向量空间讲座。今天,我们邀请到了我的老伙计 Nirant,来和我们谈谈 FastEmbed。对于那些第一次参加我们向量空间讲座的朋友们来说,我们喜欢展示 Qdrant 社区正在做的一些很酷的事情。我们也很喜欢展示 Qdrant 自己推出的一些很酷的东西。今天就是我们展示 Qdrant 自身推出的 FastEmbed 的时候。我的老伙计 Nirant 就在现场某个地方。我要请他上台,我会先介绍一下 Nirant 的生平。那么,Nirant,怎么样,伙计?在我们开始之前,让我快速介绍一下你。
Demetrios: 你是一个身兼数职的人。你目前在 Qdrant 的 Devrel 团队工作,对吧?我喜欢你穿的那件衬衫。你从 2017 年起就一直在研究 ML 模型和向量。这太不可思议了。你还是 fast embed 的创建者和维护者。所以你是今天我们这个话题的最佳人选。现在,如果任何人有问题,请随时把它们放到聊天区,我会在 Nirant 讲解时提问。我也借此机会鼓励所有正在观看的朋友们,如果你还没加入 Qdrant 的 Discord,请加入我们。
Demetrios: 其次,我鼓励你,如果你正在用 Qdrant 或在向量数据库领域、或在 AI 应用领域做些什么,并且想展示出来,我们非常乐意邀请你在向量空间讲座上发言。那么,事不宜迟,Nirant,我的朋友,我把时间交给你,我想以这个问题开始:今天向量创建面临哪些挑战?
Nirant Kasliwal: 我认为向量创建并不是一个独立的问题,尽管你可能一开始会这样想,第一个想法是它是个独立问题。实际上是两个问题。一个是经典的计算问题,即如何处理任何媒体?所以你可以从几乎任何形式的媒体创建向量,文本、图像、视频。理论上,你可以从许多事物中创建。我最近看到有人用汤作为比喻。你可以用几乎任何东西煮汤。所以你可以从几乎任何东西创建向量。那么,我们真正想做什么呢?向量本质上是一种压缩形式。
Nirant Kasliwal: 所以现在我们要确保这种压缩捕获了我们感兴趣的内容。在这种情况下,我们要确保向量捕获了某种形式的意义,比如说,文本或图像的意义。当我们这样做时,捕获意味着什么?我们希望当事物真正相似时,或者说我们对相似性的定义是什么,它们彼此靠近;如果它们不相似,则彼此远离。这就是模型或向量模型主要试图做的事情。模型本身通常经过训练和构建,以保留学习新事物的能力。你可以更快地分离相似的向量等等。但当我们在生产环境中使用时,我们不需要所有这些能力,我们不需要训练时的能力。
Nirant Kasliwal: 这意味着你为训练时存储的所有额外计算资源、特性以及所有东西都在生产环境中被浪费了。这就好比每次我跟你说话,都得从头开始说:“你好,我是 Nirant,我是个人。”这非常令人恼火,但我们在向量处理中一直在做这件事,这正是 fast embed 主要试图解决的问题。我们从生产环境的角度来看待向量,并思考如何构建一个旨在追求速度、效率和准确性的 Python 库?这些就是核心理念。我认为人们非常能理解这个问题。比如,你可以在我们的 GitHub Issues 上看到。有人说:“哦,是的,它确实名副其实。”是的,这是件好事。比如,处理 800 万个 token,我们在 MacBook Pro M1 上花了大约 3 小时,而其他一些 Olama 向量化过程花了两天多。
Nirant Kasliwal: 你可以想象,在 OpenAI 上处理 800 万个 token 会花费多少,考虑到他们经常限制你的速率,速度又会是多么慢。举个例子,我们制作了一个包含 100 万个向量的数据集,其中 token 数量远不止 100 万个,这花了我们几百美元。它并不昂贵,但非常慢。所以作为一个批量处理过程,如果你想对大型数据集进行向量化,它会非常慢。我认为更生动的说法是,有人在 LinkedIn 上写道,Prithvira 在 LinkedIn 上写道,“你的向量将飞速前进”,我喜欢这个想法,我们优化了速度,让它飞快地运行。这就是理念。那么我们……我是说,让我们给这些特点命名,对吧?首先,我们希望它快速且轻量。我会解释“轻量”是什么意思。我们希望召回率(recall)能很快,对吧?我是说,我们一开始就讨论了向量是什么,我们希望确保相似的事物是相似的。
Nirant Kasliwal: 这就是我们所说的召回率(recall)。我们经常把它和准确性(accuracy)混淆,但在检索意义上,我们称之为召回率。我们希望确保它仍然易于使用,对吧?就像没有任何理由让它变得复杂。而且我们速度很快,我是说我们非常快。其中一部分原因,比如说,我们只使用了 BGE small En,这个英文模型。假设这些都是以 token/秒为单位,并且 token 是模型特有的。举例来说,BGE 计算 token 的方式可能与 OpenAI 计算 token 的方式不同,因为 tokenizers 略有差异,而且它们在略有差异的语料库上进行了训练。这就是核心思想。
Nirant Kasliwal: 我希望你们尝试一下,这样我就可以吹嘘你们用过了。
Demetrios: 那张幻灯片上的小字写了什么?基准测试是我第二喜欢用来吹嘘的方式。你第一喜欢用来吹嘘的方式是什么?
Nirant Kasliwal: 最好的方式是有人告诉我他们正在使用它。
Demetrios: 好的,就是这样。所以我想这是一个让人们尝试和使用它的简单方法。
Nirant Kasliwal: 是的,我很想让你们试试。告诉我们你们使用的情况,在哪里有效,在哪里有问题,所有这些。如果你报告问题,我甚至会非常感激,即使你对我大喊大叫,因为那意味着你没有忽视我。
Demetrios: 就这样。好的,就是这样。Bug 报告是件好事。继续吧。
Nirant Kasliwal: 所以我们说了快速和轻量。那么“轻量”是什么意思呢?你会看到很多向量服务器的镜像尺寸非常大。我说镜像,通常是指 Docker 镜像,其大小通常有几 GB。例如,对于 sentence-transformers,如果你使用 Transformers 包和 PyTorch,你会得到一个大约 5 GB 的 Docker 镜像。顺便说一下,内存消耗并没有那么高。但是尺寸非常大,而且模型本身只有 400 MB。所以你的依赖项非常庞大。
Nirant Kasliwal: 每次你在,比如说 AWS Lambda 上这样做,或者说如果你想进行水平扩展,你的冷启动时间可能需要几分钟。如果你的工作负载非常不稳定(spiky),那会非常慢且低效。如果你仔细想想,人们的查询量通常比你的语料库更大。例如,如果你在一个电商外卖应用的客户支持部门工作。你的大部分订单量会在午餐和晚餐时间。这就是一个非常不稳定的负载。同样,即便是时尚行业的电商公司,也经常看到人们每天晚上,例如下班或回家时,查看他们的订单。那是另一个高峰。
Nirant Kasliwal: 所以每当你的负载不稳定时,你都希望能够进行水平扩展,并且希望能够快速地做到。而这种速度来自于轻量化。这就是为什么 Fast Embed 非常轻量。所以你在这里会看到,我们强调 Fast Embed 只有半 GB,而其他的是 5 GB。在极端情况下,这可能导致你的 Docker 镜像大小甚至是内存消耗相差十倍。召回率——这些向量是好是坏?对吧?所以我们说我们正在让它们变快,但我们为此牺牲了多少性能?我们使用我们的默认向量(最初是 VG small en,现在是 1.5)进行了余弦相似度测试,它们非常稳健。我们没有牺牲太多性能。大家跟上我的思路了吗?我需要听到一些反馈。
Demetrios: 我完全跟上你的思路了。聊天区有一个问题,如果现在是提问的好时机的话。
Nirant Kasliwal: 是的,请尽管问。
Demetrios: 好的,这个问题有点靠前,大概是几张幻灯片之前。所以我先提醒你一下。fast embed 有没有计划支持音频或图像来源?
Nirant Kasliwal: 如果有这方面的需求,我们确实有支持多模态向量的计划。我们很乐意这样做。如果其中有特定的模型,比如说你想要 Clip 或 Seglip,或者某个特定的音频模型,请在 Discord 或我们的 GitHub 上提出来,这样我们就可以相应地进行规划。所以,是的,这就是思路。我们需要具体的建议,这样我们才能持续添加。我们不希望模型太多,因为那样会给我们的最终用户造成困惑,这就是为什么我们采取有主见的立场,这也是一个很好的过渡。为什么我们优先考虑这一点呢?我们希望这个包易于使用,所以我们总是会努力为你做出最佳的默认选择。这很像 Linux 的方式,我们做一件事情,并且努力把这件事情做好。
Nirant Kasliwal: 例如,如果你查看 Qdrant 客户端,它会像你期望的那样传递所有内容。所以 docs 是一个字符串列表,metadata 是一个字典列表,而 IDs 同样是一个 ID 列表,是符合 Qdrant Client 规范的有效 ID。搜索也非常直接。整个搜索查询基本上只需要两个参数。你甚至可以看到一个非常熟悉的集成,比如说 langchain。我想这里的大多数人之前或多或少都了解过这个。这个也非常熟悉和直接。而在底层,我们所做的就是这一行代码。
Nirant Kasliwal: 我们有一个 .embed,它是一个生成器(generator),我们对其调用 list 函数,以便实际获得一个向量列表。你会注意到这里我们有 passage 和 query 键,这意味着我们默认使用的检索模型考虑到了这一点:如果存在 passage 和 query,它们需要关联在一起,并且在模型训练中就捕获了问答上下文。另一个需要注意的是,我们直接沿用了向量模型创建者设定的 token 限制或上下文窗口大小。所以对于这个模型(BGE base),它是 512 个 BGE token。
Demetrios: 关于这一点,上周我们请来了 Cohere 的 Neil,他当时正在谈论 Cohere 的 embed version three,我想他是这么称呼它的,或者说 V3。这与它兼容吗?支持吗?还是不支持?
Nirant Kasliwal: 目前,我们仅支持开源模型,这样我们就可以直接提供这些模型服务。Embed V3 目前仅限云端使用,所以我们目前还不支持。但话说回来,我们并不反对支持它。如果有人有这方面的需求,我们乐意提供支持,这样人们就可以无缝地将其与 Qdrant 一起使用,而 fast embed 会为你完成将其传递给 Qdrant、构建 Schema 等繁重的工作。所以这是完全合理的。正如我所问的,如果我们有用户很想尝试 Cohere 的 Embed V3,我们可以考虑支持。另外,我认为 Nils 提到 Cohere 的 Embed V3 与二进制量化兼容。我认为这是目前唯一官方支持这一点的向量模型。
Nirant Kasliwal: 好的,我们对二进制量化是有概念的,而且模型也经过了相关训练。我认为这叫做“压缩感知”(compression awareness)。Qdrant 支持这一点。所以使用它可能很值得,因为它能节省大约 30 倍的内存成本。所以这非常强大。
Demetrios: 太棒了。
Nirant Kasliwal: 好的,那么幕后原理,我认为这是我最喜欢的部分。它也很简短。我们实际上只做了两件事。为什么我们速度快?我们目前使用 ONNX runtime,我们的配置是使其在 CPU 上运行,而且我们仍然非常快。这得益于多进程处理以及 ONNX runtime 本身。将来某个时候,我们也想支持 GPU。我们在不同的 Nvidia 配置上遇到了一些配置问题。随着 GPU 的变化,ONNX runtime 并不能无缝地切换 GPU。
Nirant Kasliwal: 这就是为什么我们不允许将其作为默认提供程序。但你可以手动指定。它并非禁止,只是不是默认选项。我们希望确保你的默认选项始终可用,并且在顺利路径中始终可用。我们为你量化模型。所以当我们量化时,这意味着我们做了一系列技巧,这得益于对 Hugging Face Optimum 的大力赞扬。我们在量化过程中进行了一系列优化,例如压缩一些激活函数,例如 Gelu。我们还做了一些图优化,而且我们并没有进行大量的位丢弃,比如说将 32 位量化到 16 位,或将 64 位量化到 32 位,只有在需要时才进行这种量化。
Nirant Kasliwal: 这些性能提升大部分来自图优化本身。因此 Optimum 本身也提供不同的模式。如果有人对此感兴趣,我很乐意分享相关文档和详细信息。是的,大概就是这些。这就是我们做的两件事,它们带来了大部分的速度提升。我认为这又回到了你一开始提出的问题。是的,我们确实想支持多模态。我们正在研究如何对 Clip 进行 ONNX 导出,使其与 Clip 本身一样稳健。
Nirant Kasliwal: 到目前为止,我们还没有发现这样的方法。我花了一些时间研究这个问题,以及一些使用体验的改进。目前,我们大多数的模型下载都是通过 Qdrant 托管的 Google Cloud Storage 进行的。我们希望支持 Hugging Face Hub,这样我们就可以更快地发布新模型。所以我们很快就会这样做。接下来,正如我之前提到的,我们始终将性能视为首要考虑因素。所以我们正在研究如何允许你更改或调整固化的向量(Frozen Embeddings),比如说 OpenAI 的向量或者其他任何模型,以适应你的特定领域。因此,也许会在 Fast Embed 中提供一个独立的工具包,它是可选的,不属于默认路径,因为这并不是你会一直使用的东西。
Nirant Kasliwal: 我们希望确保你的训练和使用体验部分是分开的。所以我们会这样做。是的,就是这样。又快又好。
Demetrios: 太棒了。就像 FastEmbed 一样。
Nirant Kasliwal: 是的。
Demetrios: 有人提到你需要擅长双关语,那可能是最好的东西,你最值得炫耀的东西。还有一个问题通过聊天区传来了,我想问你。是不是当我们使用 Qdrant client 添加数据时,Fast Embedding 就已经包含了?我们不需要额外操作?
Nirant Kasliwal: 你说“额外操作”是什么意思?是指你不需要指定一个 Fast Embed 模型吗?
Demetrios: 是的,我想更像是你不需要以任何方式将它添加到 Qdrant 中,或者说它是完全独立的。
Nirant Kasliwal: 所以这是在客户端进行的。你拥有所有数据,即使你压缩并发送给我们,所有的向量创建都是在你自己的计算资源上进行的。这个向量创建不会发生在 Qdrant 云上,它发生在你的自有计算资源上。这与你应该拥有尽可能多的控制权这一理念是一致的。这也是为什么,至少目前来说,Fast Embed 不是一个专门的服务器。我们不希望你为 Qdrant 和 Fast Embed 运行两个不同的 Docker 镜像。或者说在同一个 Docker 镜像或服务器中为 Qdrant 和 Fast Embed 设置两个不同的端口。所以,是的,那样会比我们期望的更加混乱。
Demetrios: 是的,我认为如果我理解得没错,我对那个问题的理解有点不同,它就像是 Qdrant 自带的功能一样。
Nirant Kasliwal: 是的,我认为那样理解也很好。我们为你设置了所有默认值,我们为你选择了最佳实践,并且基于 MTEB 基准测试,这应该在绝大多数情况下都有效,但我们无法保证它适用于所有场景。比如,我们的默认模型是针对英文挑选的,并且主要在开放领域、开放网络数据上进行测试。因此,举例来说,如果你在做一些特定领域的事情,比如医疗或法律,它可能效果不太好。这就是你可能仍然需要创建自己的向量的地方。这是这里的边缘情况。
Demetrios: 你在使用它时,还有哪些其他可以调整的“旋钮”(参数)?
Nirant Kasliwal: 结合 Qdrant 使用还是不结合 Qdrant 使用?
Demetrios: 结合 Qdrant 使用时。
Nirant Kasliwal: 所以我想说的一点是,第一点是肯定要尝试我们支持的不同模型。我们支持相当范围的模型,包括一些多语言模型。第二点是,当你在使用 Qdrant 时,我们会负责处理。例如,假设你不得不手动指定 passage 或 query。当你这样做时,比如 add 和 query。我们所做的,是在为你创建向量时,自动添加 passage 和 query 键。所以这个问题我们已经处理了。因此,无论你的向量模型有哪些最佳实践,请确保你在结合 Qdrant 使用时,或者单独使用时,都要应用这些实践。
Nirant Kasliwal: 这就是一个可调整的“旋钮”。第二点,我认为这是一个非常普遍的建议,我们会建议你从一些评估开始,比如说,先用五句话试试,看看它们是否真的彼此接近。在向量检索中,有一点非常重要,那就是当我们使用向量进行检索或向量相似度搜索时,重要的是相对顺序。所以,举例来说,我们不能说 0.9 永远都是好的。它可能意味着在你所在的领域,最佳匹配的分数是 0.6。所以在匹配度方面,没有绝对的截止阈值。所以有时人们会认为我们应该设置一个最低阈值,这样就不会有噪音。所以我建议你根据你的查询和领域来校准这个阈值。
Nirant Kasliwal: 而且你不需要很多查询。即使你只是手写五到十个问题,基于你对这个领域的理解,你也会比随机选择一个阈值做得好得多。
Demetrios: 很高兴知道这些。好的,谢谢你的解答。聊天区 Shreya 提了一个问题,她问延迟与 Elasticsearch 相比如何?
Nirant Kasliwal: Elasticsearch?我相信那是一个 Qdrant 基准测试的问题,我不确定 Elasticsearch 的 HNSW 索引表现如何,因为我认为那才是公平的比较。我也认为 Elasticsearch 的 HNSW 索引在能够与 Payload 一起存储多少向量方面存在一些限制。所以这不是一个“苹果比苹果”的比较。这几乎就像比较一页纸和整本书一样,因为据我记忆,通常比例是这样。我对此的了解可能已经过时几个月了,但我认为那个问题背后的意图是,Qdrant 对于它所做的事情(即向量相似度搜索)来说是否足够快?它绝对是快的。在这方面,它非常快。它是用 Rust 编写的,Twitter 在处理大量相似推文时就使用了它,规模非常大。他们运行了一个 Qdrant 实例。
Nirant Kasliwal: 所以我认为,如果像 Twitter 这样规模的公司,每天大概会发布 200 万到 500 万条推文,如果他们能够对这些推文进行向量化并使用 Qdrant 来提供相似度搜索服务,我想大多数人应该都能接受那种延迟和吞吐量要求。
Demetrios: 这也体现在名字里了。我的意思是,你给它起名 Fast Embed 是有原因的,对吧?
Nirant Kasliwal: 是的。
Demetrios: 聊天区还有另一个问题,是关于模型选择和向量大小的。考虑到有多种模型和向量大小可供选择,你如何确定最合适的模型和向量大小?你之前已经部分讲到了如何调整“旋钮”,其中之一就是选择不同的模型。但是你如何选择哪个模型更好呢?
Nirant Kasliwal: 有一种学术的视角,有一种工程师的视角,还有一种“黑客”的视角。我将按顺序给你这三种答案。所以,学术的或说黄金标准的方法大概是这样的:你会去查看已知的基准测试,例如 Kilt (K-I-L-T) 或多语言文本向量基准测试 (multilingual text embedding benchmark),也称为 MTEB 或 BEIR,它们是这三个基准测试之一。然后你会查看它们的检索部分,看看其中哪个在你的领域或问题区域方面得分最高。基本上就是这样。例如,如果你在药理学领域工作,客户支持检索任务与你的相关性几乎为零,除非你专门在一个药理学订阅应用中。所以你会从那里开始。
Nirant Kasliwal: 这通常需要两到二十小时,具体取决于你对这些数据集的熟悉程度。但它不会花你一个月的时间来做这件事。所以,大致估算一下,一旦你找到了合适的基准,你就可以尝试选取在该子领域数据集上表现最好的模型,看看它在你的领域内效果如何,然后以此为基础进行部署。这时,你就要切换到工程师思维了。现在,工程师思维告诉你,构建某物的最佳方法是根据你预见的潜在工作负载或挑战,做出有依据的猜测。对吧。就像土木工程师建造一座桥梁时会考虑预计有多少车辆通过,他们显然不会建造一座能承载整船货物或一架飞机重量的桥梁,那是完全不同的。所以你以此为起点,然后说,好吧,这是我预期的请求数量,这是我的预算,而你的预算通常会涉及到延迟预算、计算资源和内存预算。”
Nirant Kasliwal: 例如,我提到二进制量化和乘积量化的原因之一是,使用像二进制量化这样的技术,你可以获得 98% 的召回率,但能节省 30 到 40 倍的内存成本,因为它丢弃了所有冗余的位,只保留向量本身的 0 或 1 位。Qdrant 已经为你测试过了。所以我们确定它对 OpenAI 和 Cohere 的向量都有效。所以你可能想利用它来进行大规模扩展,同时作为工程师控制好你的预算。现在,要做到这一点,你需要对三个数字有所了解,对吧?你的延迟要求是什么?你的成本要求是什么?以及你的性能要求是什么?至于性能,这是工程师最不熟悉的部分,我会给你“黑客”的答案,就是这个。
Demetrios: 这正是我一直在等的。伙计,对此太激动了,就是这个。请告诉我们“黑客”的答案。
Nirant Kasliwal: “黑客”的答案是这样的:我要分享两个技巧。第一个是写十个问题,找出最佳答案,看看哪个模型能正确回答这十个问题中的尽可能多。第二个是,大多数大于或等于 768 维的向量模型,可以通过在其上添加一个小的线性头部来优化和改进。例如,我可以获取 OpenAI 的向量(它是 1536 维),将我的文本通过它进行向量化,然后针对我自己的领域,通过添加两到三层线性函数来调整 OpenAI 的向量,基本上就是 Y=MX+C 或 AX+B Y=C 这样的函数。所以这非常简单,你可以在 NumPy 上完成,不需要用到 Torch,因为它非常小。头部或适配器(adapter)的大小通常在几 KB 到一 MB 之间。我想我在生产环境中使用过的最大的大概是 400 到 500 KB。就这么点。但这会使你的召回率提高好几倍。
Nirant Kasliwal: 所以这是一个技巧,这是第二个技巧。第三个额外的“黑客”技巧是,如果你正在使用一个大型语言模型(LLM),有时你可以这样做:拿一个问题,用一个 Prompt 重写它,然后分别从原始问题和重写后的问题生成向量,并从两者中提取候选结果。然后借助 Qdrant 的异步功能 (Qdrant Async),你可以异步地同时发出这两个查询,这样你就不会被阻塞,然后利用用户给出的原始问题和通过 LLM 重写的问题所产生的两个结果,看看选择两个结果都包含的,或者找出其他组合方法。另外,大多数 Kagglers 应该熟悉集成的概念(ensembling)。这是一种在查询推理时进行集成的绝妙方法。
Demetrios: 好的,伙计,老实说,这个答案比我预期的内容要多得多。
Nirant Kasliwal: 在检索的细节上讲得太深入了。抱歉。
Demetrios: 不过我喜欢。我很欣赏。说到这里,几周前我们请来了 Qdrant 的 CTO Andre V。他谈到了二进制量化。但是说到量化向量模型,你在文档中提到了量化向量模型可以实现快速的 CPU 生成。你能否再详细解释一下什么是量化向量模型,以及它们如何提升 CPU 性能?
Nirant Kasliwal: 所以这是一种简略的说法,意思是它们优化了 CPU 性能。我认为更准确的说法是,我们更好地利用了 CPU。但是我们来谈谈我们在这里进行的优化或量化,对吧?我们的大部分工作是基于 Optimum,而 Optimum 的配置方式是将其称为不同的“级别”。所以你可以基本上从,比如说,级别零开始,这时没有任何优化,到,比如说,级别 99,这里进行了一堆额外的优化。这些是你可以在不同标志之间切换的。这里有一些我记得的例子。例如,有一个归一化层(norm layer),你可以将其与之前的操作融合。还有不同的注意力层(attention layers),你可以将其与之前的层融合,因为你不再会更新它们了,对吧?所以我们在训练时所做的就是更新它们。
Nirant Kasliwal: 你知道你不会更新它们,因为你正在将它们用于推理。所以比如说,当有人问一个问题时,你希望它能尽可能快、尽可能便宜地被转换成一个向量。所以你可以丢弃所有那些你很可能不会使用的额外信息。所以有很多类似这样的事情,显然你也可以使用混合精度(mixed precision),大多数人通过像 Llama CPP 这样的项目听说过,你可以使用 FP16 混合精度或者很多类似的技术。比如说,如果你只使用 GPU。像 FP16 这样的技术在 GPU 上效果更好。关于 CPU 的说法源自我们使用的 ONNX runtime 如何让你优化你正在使用的 CPU 指令集。举个例子,对于 Intel CPU,你可以说,好的,我将使用 VNNI 指令集或者相关的优化。
Nirant Kasliwal: 所以当我们进行量化时,我们目前考虑的是 CPU。因此,我们未来某个时候想做的是提供一个对 GPU 友好的量化模型,我们可以进行设备检查,然后说,好的,我们看到有 GPU 可用,就先为你下载对 GPU 友好的模型。太棒了。这个问题回答了吗?
Demetrios: 对我来说,是的,但我们看看聊天区怎么说。
Nirant Kasliwal: 好的,就这样做。
Demetrios: 看看大家怎么说吧。伙计,这太棒了。我非常感谢你来这里详细讲解了我们需要了解的一切,不仅是关于 fast embed,还有我认为是关于向量的方方面面。好的,回头见。非常感谢,Nirant。也谢谢大家的到来。如果你想发表演讲,请告诉我们。联系我们吧,我们非常欢迎你在我们的向量空间讲座上分享。