Elasticsearch:使用字节大小的向量节省空间 - 8.6

news/2024/11/20 4:52:22/

作者:Jack Conradson, Benjamin Trent

Elasticsearch 在 8.6 中引入了一种新型向量! 该向量具有 8 位整数维度,其中每个维度的范围为 [-128, 127]。 这比具有 32 位浮点维度的当前向量小 4 倍,这可以节省大量空间。

你现在可以通过将带有字节值的 element_type 参数添加到向量映射中来开始索引这些较小的 8 位向量,类似于下面的示例。

{"mappings": {"properties": {"my_vector": {"type": "dense_vector","element_type": "byte","dims": 3,"index": true,"similarity": "dot_product"}}}
}

但是,如果你现有的矢量维度不适合这种较小的类型怎么办? 然后我们可以使用量化过程使它们适合,通常只有很小的精度损失!

让我们量化

让我们从定义量化开始。 量化是获取较大值集并将它们映射到较小值集的过程。 更具体地说,在我们的例子中,这将采用 32 位浮点数的范围并将其映射到向量中每个维度的 8 位整数的范围。 (这不应与降维混淆,后者是不同的主题。这只是缩小现有维度的值范围。)

这导致了另外两个问题。 我们的 32 位浮点向量的实际范围是多少? 我们应该使用什么功能来进行映射? 答案因用例而异。

例如,最简单的量化形式之一是采用归一化 32 位向量的维度并将它们线性映射到 8 位向量的整个维度范围。 使用 Python,这将类似于以下内容:

import numpy as np
import typing as tdef quantize_embeddings(text_and_embeddings: t.List[t.Mapping[str, t.Any]]) -> t.List[t.Mapping[str, t.Any]]:quantized_embeddings = np.array([x['embedding'] for x in 
query_and_embeddings])quantized_embeddings = (quantized_embeddings * 128)quantized_embeddings = quantized_embeddings.clip(-128, 
127).astype(int).tolist()return [dict(item, **{'embedding': embedding}) for (item, 
embedding) in zip(text_and_embeddings, quantized_embeddings)]

不过,这只是一个例子。 还有许多其他有用的量化函数。 对于你的特定用例,重要的是要评估哪种量化方法可以为您提供相对于空间缩减、相关性和召回率之间的权衡的最佳结果。

一些真实世界的数字

8 位向量和量化都很棒,但它们真的能减少实际用例中的空间吗? 答案是肯定的! 并且实质上。 这就是他们在不损害相关性和召回率的情况下继续提供良好结果的全部过程。 Elasticsearch 甚至拥有你使用我们的排名评估 API 自行进行评估所需的所有工具。

现在,让我们看一下使用以下设置从真实示例生成的一些数字:

  1. 所有数据都是使用云中的 Elasticsearch 和两个 gcp.data.highcpu.1 64GB 节点收集的
  2. 数据是从谷歌构建的 NQ 数据集(自然问题)中收集的,用于 BEIR
  3. 嵌入模型是 sentence-transformers/all-MiniLM-L6-v2
  4. 生成 8 位整数向量的量化应用于使用前面的示例 Python 片段从数据中收集的 32 位浮点向量

然后我们让一些神奇的事情发生并根据这个设置收集结果:

category

Median kNN Response Time

Median Exact Response Time

Recall@100

NDCG@10

Total Index Size (1p, 1r)

byte

32ms

1072ms

0.79

0.385.8gb

float

36ms

1530ms

0.79

0.3816.4gb
% Reduction11%30%0%0%64%

我们的结果看起来棒极了。 让我们逐一分解。

  • Median kNN Response Time:此响应时间是使用近似 kNN 搜索对我们的示例数据集收集的。 这种类型的搜索使用 Lucene 的 HNSW 图作为支持数据结构。 我们看到 byte 与 float 的响应时间增加了 11%。
  • Median Exact Response Time:此响应时间是使用针对我们的示例数据集的准确 kNN 搜索收集的。 这种类型的搜索使用脚本遍历数据集中的每个向量,并将返回可能的最佳结果。 我们看到响应时间大大减少了 30%!
  • Recall@100:这向我们展示了最相关的结果是否包含在前 100 名中。这对于展示我们的量化函数是否运行良好非常重要。 我们可以看到 byte 和 float 的数字是相同的,这意味着即使在量化之后我们的相关性对于 byte 和 float 一样好。
  • @NDCG@10:这向我们展示了前 10 个结果的质量有多好。 这是评估我们的量化函数是否运行良好的另一个重要指标。 再一次,byte 和 float 之间的数字是相同的,所以我们可以放心,即使在量化之后我们的结果仍然一样好。
  • Total Index Size (1p, 1r):这是用于具有单个分区和单个副本的向量索引的总索引大小。 对于此指标,我们禁用了源,我们建议将其用于所有未修改摄取的矢量数据的矢量场,这样它就不会存储两次。 我们看到总索引大小大幅减少了 64%! 由于包括图形连接在内的 HNSW 数据结构的额外开销,这并没有完全达到字节和浮点数之间的 4 倍差异,但它仍然是一个相当大的尺寸缩减。

作为 8.6 的一部分,字节向量已准备就绪,我们鼓励你在 Elastic Cloud 中启动一个集群并尝试一下!


http://www.ppmy.cn/news/75732.html

相关文章

教你精通Java语法之第十四章、枚举

目录 一、背景及定义 二、使用 2.1switch语句 2.2常用方法 三、枚举优点缺点

超市购物车功能

1 问题 平常去超市买的要买的东西过多后,记不清楚怎么办? 2 方法 解决问题的步骤采用如下方式: 首先运用字典储存已有商品跟价格注释引导顾客进行操作; 通过实验、实践等证明提出的方法是有效的,是能够解决开头提出的问题。 代码清…

给初学者的Vue.js项目搭建教程

部分数据来源:ChatGPT 1. 环境准备 在开始创建 Vue.js 项目前,需要保证已经安装了 Node.js(建议版本12)和 NPM(Node.js 自带的包管理工具)。 可以执行以下命令确认是否已经安装: node -v np…

Java 使用 jdbc 连接 mysql

简介 Java JDBC 是 Java Database Connectivity 的缩写,它是一种用于连接和操作数据库的标准 API。Java JDBC 可以让 Java 程序通过 JDBC 驱动程序连接到各种不同类型的数据库,并且执行 SQL 语句来实现数据的读取、插入、更新、删除等操作。在本篇文章中…

ES6中async函数

1.async函数 说明: 通常就是Generator函数的语法糖,async函数自带执行器,也就是说,async函数的执行,与普通函数使用一样。语义化,加上async函数表示时异步操作,await表示需要等待结果。通用性&#xff0…

python+django网上书籍商城小说在线阅读分享下载系统k19is-vue

为了解决用户便捷地在网上购物以及下载文件,本文设计和开发了一个网页小说阅读系统。本系统是基于 B/S架构设计,Dango框架 ,Python技术的前台页面设计与实现,使用Mysql数据库管理来完成系统的相关功能。主要实现了管理员与用户的注…

Flutter3.10版本发布,编程语言的重大更新

Flutter是一款强大的跨端开发框架,可以帮助开发者构建高性能、美观、灵活的应用程序,从而实现跨平台开发和部署。小程序容器技术与跨端框架结合使用,为开发者提供一站式的小程序开发和发布服务,帮助他们更加轻松和高效地构建和部署…

40亿个QQ号,限制1G内存,如何去重?

40亿个QQ号,限制1G内存,如何去重? 40亿个unsigned int,如果直接用内存存储的话,需要: 4*4000000000 /1024/1024/1024 14.9G ,考虑到其中有一些重复的话,那1G的空间也基本上是不够…