百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

LanceDB:2.1k star,适用于AI开发的高性能向量数据库

toyiye 2024-06-30 09:41 24 浏览 0 评论

一 为什么会有LanceDB?

LanceDB 是一个用于人工智能的开源向量数据库,旨在存储、管理、查询和检索大规模多模式数据的嵌入。LanceDB 的核心是用Rust编写的,并构建在Lance之上,Lance 是一种开源列式数据格式,专为高性能 ML 工作负载和快速随机访问而设计。Lance的性能比parquet高2000倍。

数据库和底层数据格式都经过精心设计,易于使用、可扩展且经济高效。

二 LanceDB的使用方法

LanceDB 可以通过多种方式运行:

  • 嵌入现有后端(例如 Django、Flask、Node.js 或 FastAPI 应用程序)
  • 直接从客户端应用程序(例如 Jupyter 笔记本)连接以进行分析工作负载
  • 部署为远程无服务器数据库

2.1 安装

pip install lancedb

2.2 链接到数据库

import lancedb
uri = "data/sample-lancedb"
db = lancedb.connect(uri)

2.3 创建表格

tbl = db.create_table("my_table",
                data=[{"vector": [3.1, 4.1], "item": "foo", "price": 10.0},
                      {"vector": [5.9, 26.5], "item": "bar", "price": 20.0}])

如果表已经存在,LanceDB默认会抛出错误。如果你想覆盖表,你可以传入mode="overwrite" 该create_table方法。

您还可以直接传入 pandas DataFrame:

import pandas as pd
df = pd.DataFrame([{"vector": [3.1, 4.1], "item": "foo", "price": 10.0},
                   {"vector": [5.9, 26.5], "item": "bar", "price": 20.0}])
tbl = db.create_table("table_from_df", data=df)

2.4 创建一个空表

import pyarrow as pa
schema = pa.schema([pa.field("vector", pa.list_(pa.float32(), list_size=2))])
tbl = db.create_table("empty_table", schema=schema)

2.5 打开现有表

tbl = db.open_table("my_table")

如果您忘记了表的名称,您始终可以获得所有表名称的列表:

print(db.table_names())

2.6 向表中添加数据

# Option 1: Add a list of dicts to a table
data = [{"vector": [1.3, 1.4], "item": "fizz", "price": 100.0},
        {"vector": [9.5, 56.2], "item": "buzz", "price": 200.0}]
tbl.add(data)

# Option 2: Add a pandas DataFrame to a table
df = pd.DataFrame(data)
tbl.add(data)

2.7 相似性搜索

tbl.search([100, 100]).limit(2).to_pandas()

2.8 从表中删除数据

tbl.delete('item = "fizz"')

2.9 删除表

db.drop_table("my_table")

三 LanceDB的原理

3.1 向量索引

向量搜索是一种基于向量表示搜索相似项目的技术,称为嵌入。它也称为相似性搜索、最近邻搜索或近似最近邻搜索。

原始数据(例如文本、图像、音频等)通过嵌入模型转换为嵌入,然后存储在像 LanceDB 这样的矢量数据库中。为了大规模执行相似性搜索,在存储的嵌入上创建索引,然后可以使用该索引来执行快速查找。

现代机器学习模型可以经过训练将原始数据转换为嵌入,表示为固定维度的浮点数数组(或向量)。嵌入在实践中有用之处在于,嵌入在向量空间中的位置捕获了数据的一些语义,具体取决于模型的类型及其训练方式。向量空间中彼此靠近的点被认为是相似的(或出现在相似的上下文中),而远离的点被认为是不相似的。

多模式数据(文本、音频、图像等)的大型数据集可以使用适当的模型转换为嵌入。将向量的主成分投影到 2D 空间中会产生表示相似概念的向量组,这些向量聚集在一起,如下所示。

3.2 IVF-PQ索引

ANN(近似最近邻)索引是一种数据结构,它以提高搜索和检索效率的方式表示数据。使用 ANN 索引速度更快,但不如 kNN 或强力搜索准确,因为本质上索引是数据的有损表示。

LanceDB 与其他矢量数据库有根本的不同,因为它构建在Lance之上,Lance 是一种开源列式数据格式,专为高性能 ML 工作负载和快速随机访问而设计。由于Lance的设计,LanceDB的索引理念主要采用基于磁盘的索引理念。

IVF-PQ是倒排文件索引(IVF)和乘积量化(PQ)相结合的复合索引。LanceDB 中的实现提供了几个参数来微调索引的大小、查询吞吐量、延迟和召回,本节稍后将对此进行描述。

乘积量化 (PQ) 的工作原理是将一个大的高维向量划分为大小相等的子向量。每个子向量都分配有一个“再现值”,该值映射到该子向量的最近的点质心。然后将再现值分配给使用唯一 ID 的码本,该码本可用于重建原始向量。

重要的是要记住,量化是一个有损过程,即重建的向量与原始向量不同。这导致索引的大小和搜索结果的准确性之间的权衡。

例如,考虑从由 32 位浮点数组成的 128 维向量开始。将其量化为 4 维的 8 位整数向量(如上图所示),我们可以显着减少内存需求。

原始:128 × 32 = 4096位 量化:4 × 8 = 32位

量化使索引中每个向量的内存需求减少了128 倍,这是相当可观的。

3.3 倒排索引

虽然 PQ 有助于减小索引的大小,但 IVF 主要解决搜索性能问题。倒排文件索引的主要目的是通过缩小搜索空间来促进快速有效的最近邻居搜索。

在 IVF 中,PQ 向量空间被划分为Voronoi 单元,这些单元本质上是由空间中距给定区域种子点阈值距离内的所有点组成的分区。这些种子点用于创建倒排索引,将每个质心与空间中的向量列表相关联,从而允许搜索仅限于索引中向量的子集。

在查询期间,根据查询在向量空间中的位置,它可能靠近多个 Voronoi 单元的边界,这可能会使 top-k 结果不明确并跨越多个单元。为了解决这个问题,IVF-PQ 引入了参数nprobe,该参数控制查询期间要搜索的 Voronoi 单元的数量。越高nprobe,结果越准确,但查询速度越慢。

我们可以结合上面的概念来理解如何在LanceDB中构建和查询IVF-PQ索引。

3.4 构建索引&查询索引

构建索引

构建 IVF-PQ 索引时需要设置三个关键参数:

  • metric:使用L2欧氏距离度量。我们也支持dot并cosine保持距离。
  • num_partitions:索引的 IVF 部分中的分区数。
  • num_sub_vectors:在乘积量化 (PQ) 期间将创建的子向量的数量。

在Python中,可以按如下方式创建索引:

# Create and train the index for a 1536-dimensional vector
# Make sure you have enough data in the table for an effective training step
tbl.create_index(metric="L2", num_partitions=256, num_sub_vectors=96)

通常选择num_partitions针对每个分区特定数量的向量。num_sub_vectors通常根据所需的召回率和向量的维数来选择。

查询索引

# Search using a random 1536-dimensional embedding
tbl.search(np.random.random((1536))) \
    .limit(2) \
    .nprobes(20) \
    .refine_factor(10) \
    .to_pandas()

上面的查询将使用给定的查询向量对表执行搜索tbl,参数如下:

  • limit: 返回结果数
  • nprobes:探针的数量决定了向量空间的分布。虽然较高的数字可以提高搜索准确性,但也会导致性能下降。通常,设置nprobes覆盖数据集的 5-10% 可以有效地以最小的延迟实现高召回率。
  • refine_factor:通过读取额外元素并在内存中重新排列它们来优化结果。数字越大,搜索越准确,但速度也越慢。
  • to_pandas():将结果转换为pandas DataFrame

四 性能 - Lance VS Parquet

Lance 提供与 Parquet 相当的扫描性能,但支持快速随机访问,使其非常适合:搜索引擎、实时特征检索、加快深度学习训练的洗牌性能

在这里,我们将比较 Lance 与 Parquet 的随机访问性能。我们将创建 1 亿条记录,其中每个值都是随机生成的 1000 个字符长的字符串。然后,我们运行 1000 个查询的基准测试,在数据集中随机获取 20-50 行。两个测试都是在同一个 Ubuntu 22.04 系统上完成的:

sudo lshw -short
类描述
================================================ =================
系统 20M9CTO1WW (LENOVO_MT_20M9_BU_Think_FM_ThinkPad P52)
内存 128GiB 系统内存
32GiB SODIMM DDR4 同步 2667 MHz (0.4 ns)
内存 32GiB SODIMM DDR4 同步 2667 MHz (0.4 ns)
内存32GiB SODIMM DDR4 同步 2667 MHz (0.4 ns)
内存 32GiB SODIMM DDR4 同步 2667 MHz (0.4 ns)
内存 384KiB L1 高速
缓存 1536KiB L2 高速
缓存 12MiB L3 高速缓存
处理器 Intel(R) Xeon(R) E-2176M CPU @ 2.70GHz
存储三星 SSD 980 PRO 2TB

还使用 LMDB 对类似的设置进行了基准测试,并将所有内容绘制在同一张图表上以进行比较:

LanceDB一直声称随机访问性能比 Parquet快100 倍,但正如该基准测试所示,它实际上更像是2000倍。Lance 为重要的ML工作流程所需的 OSS 数据生态系统带来了快速随机访问性能。这对于训练深度学习模型的搜索、特征水合和洗牌至关重要。虽然 Lance 的性能对于这些用例来说已经非常有价值,但我们将努力实现通用键查找、更好的 duckdb 集成以及在 Spark/Ray 节点之间分发大型 Lance 数据集的挂钩。

五 LanceDB的应用场景

  • 嵌入式(OSS)和无服务器(云),无需管理服务器
  • 快速生产规模向量相似性、全文和混合搜索以及 SQL 查询接口(通过DataFusion)
  • 原生 Python 和 Javascript/Typescript 支持
  • 存储、查询和管理多模式数据(文本、图像、视频、点云等),而不仅仅是嵌入和元数据
  • 与Arrow生态系统紧密集成,通过 SIMD 和 GPU 加速实现共享内存中真正的零复制访问
  • 自动数据版本控制可管理数据版本,无需额外的基础设施
  • 基于磁盘的索引和存储,无需花费大量资金即可实现大规模可扩展性
  • 直接摄取您最喜欢的数据格式,例如 pandas DataFrames、Pydantic 对象、Polars(即将推出)等

参考资料

[1] github源码:https://github.com/lancedb/lancedb

[2] Lance 中的随机访问基准测试:https://blog.lancedb.com/benchmarking-random-access-in-lance-ed690757a826

[3] LanceDB wiki:https://lancedb.github.io/lancedb

[4] LanceDB quick start:https://lancedb.github.io/lancedb/basic

[5] LanceDB concepts:https://lancedb.github.io/lancedb/concepts/vector_search

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码