简介

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

快速开始

安装

pip install lancedb

目前0.6.8需要pyarrow-12.0.0及以上,亲测15.0会报错。

创建客户端

import lancedb
import pandas as pd
import pyarrow as pa uri = "data/sample-lancedb"
db = lancedb.connect(uri)
# 异步客户端
#async_db = await lancedb.connect_async(uri)

与Chroma不同,lancedb没有服务端-客户端模式。支持同步和异步客户端,看起来异步客户端更新较快,从官方文档来看没发现使用上的区别。

创建一张表

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

如果表名已经存在,则会报错。如果希望覆盖已经创建的同名表,可以添加mode='overwrite'参数。

tbl = db.create_table("my_table", data=data, mode='overwrite')

如果不希望覆盖已经创建的同名表,而直接打开的话,可以添加exist_ok=True参数。

tbl = db.create_table("my_table", data=data, exist_ok=True)

创建一张空表

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

类似SQL语法,先创建一张空表,插入数据可以放到后面进行。

添加数据

# 直接添加数据
data = [
{"vector": [1.3, 1.4], "item": "fizz", "price": 100.0},
{"vector": [9.5, 56.2], "item": "buzz", "price": 200.0},
]
tbl.add(data) # 添加df数据帧
df = pd.DataFrame(data)
tbl.add(data)

查找数据

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

通过向量来查找相似的向量。默认情况下没有对向量创建索引,因此是全表暴力检索。官方推荐数据量超过50万以上才需要创建索引,否则全表暴力检索的延迟也在可以接受的范围之内。(明明就是没实现,还说的冠冕堂皇。。)

删除数据

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

类似SQL语法中的WHERE声明,需要指定字段和对应的值。

修改数据

table.update(where='item = "fizz"', values={"vector": [10, 10]})

类似SQL语法中的UPDATE声明,需要指定字段和对应的值。

删除表

db.drop_table("my_table")

查看所有表

print(db.table_names())
tbl = db.open_table("my_table")

table_names可以返回该数据库中已经创建的所有表,使用open_table可以打开对应的表。

高级用法

数据类型

多种数据类型

除了直接添加数据和添加df数据帧之外,lancedb还支持用pyarrow创建schema和添加数据。

import pyarrow as pa
schema = pa.schema(
[
pa.field("vector", pa.list_(pa.float16(), 2)),
pa.field("text", pa.string())
]
)

lancedb直接float16数据类型,这就比chromadb有存储优势了。

自定义数据类型

from lancedb.pydantic import Vector, LanceModel

class Content(LanceModel):
movie_id: int
vector: Vector(128)
genres: str
title: str
imdb_id: int @property
def imdb_url(self) -> str:
return f"https://www.imdb.com/title/tt{self.imdb_id}"

LanceModel是pydantic.BaseModel的子类,主要就是实现了Vector数据类型的定义,避免手动创建schema中vector的定义,只需要指定维度即可。

复合数据类型

class Document(BaseModel):
content: str
source: str class NestedSchema(LanceModel):
id: str
vector: Vector(1536)
document: Document tbl = db.create_table("nested_table", schema=NestedSchema, mode="overwrite")

索引

创建IVF_PQ索引

tbl.create_index(num_partitions=256, num_sub_vectors=96)

lancedb支持创建倒排索引的乘积量化。num_partitions是索引中的分区数,默认值是行数的平方根。num_sub_vectors是子向量的数量,默认值是向量的维度除以16。

使用GPU创建

accelerator="cuda"
# accelerator="mps"

支持CUDA的GPU或者Apple的MPS加速

使用索引加速近似查找

tbl.search(np.random.random((1536))) \
.limit(2) \
.nprobes(20) \
.refine_factor(10) \
.to_pandas()

nprobes是探针数量,默认为20,增加探针数量则会提高查找的精度并相应增加计算耗时。refine_factor是一个粗召的数量,用于读取额外元素并重新排列,以此来提高召回。

向量化模型

内置向量模型

import lancedb
from lancedb.pydantic import LanceModel, Vector
from lancedb.embeddings import get_registry model = get_registry().get("sentence-transformers").create(name="BAAI/bge-small-en-v1.5", device="cpu") class Words(LanceModel):
text: str = model.SourceField() # 指定这个字段为需要模型进行向量化的字段
vector: Vector(model.ndims()) = model.VectorField() # 指定这个字段为模型向量化的结果 table = db.create_table("words", schema=Words)
table.add(
[
{"text": "hello world"},
{"text": "goodbye world"}
]
) query = "greetings"
actual = table.search(query).limit(1).to_pydantic(Words)[0]
print(actual.text)

官方支持了多种sentence-transformers的向量化模型。用上述方法调用内置模型需要指定模型的SourceField和VectorField。

自定义向量模型

from lancedb.embeddings import register
from lancedb.util import attempt_import_or_raise @register("sentence-transformers")
class SentenceTransformerEmbeddings(TextEmbeddingFunction):
name: str = "all-MiniLM-L6-v2"
# set more default instance vars like device, etc. def __init__(self, **kwargs):
super().__init__(**kwargs)
self._ndims = None def generate_embeddings(self, texts):
return self._embedding_model().encode(list(texts), ...).tolist() def ndims(self):
if self._ndims is None:
self._ndims = len(self.generate_embeddings("foo")[0])
return self._ndims @cached(cache={})
def _embedding_model(self):
return sentence_transformers.SentenceTransformer(name)
from lancedb.pydantic import LanceModel, Vector

registry = EmbeddingFunctionRegistry.get_instance()
stransformer = registry.get("sentence-transformers").create() class TextModelSchema(LanceModel):
vector: Vector(stransformer.ndims) = stransformer.VectorField()
text: str = stransformer.SourceField() tbl = db.create_table("table", schema=TextModelSchema) tbl.add(pd.DataFrame({"text": ["halo", "world"]}))
result = tbl.search("world").limit(5)

官方提供了模板用于自定义模型,但是我觉得直接调用模型进行向量化表示更直接吧,这样感觉有点追求格式化的统一了。

总结

与Chromadb对比,没有服务端模式,全部在客户端完成,虽然官方声称有云原生的版本,但感觉大部分场景下可能都不需要放在云上,感觉这一款产品会更加轻量化。

此外,创建表的时候没有默认的向量化模型,感觉对开发者可能更加灵活一些,相比之下Chromadb默认会从HuggingFace下载模型,对于内网环境不太友好。

向量数据库之Lancedb学习记录的更多相关文章

  1. Quartz 学习记录1

    原因 公司有一些批量定时任务可能需要在夜间执行,用的是quartz和spring batch两个框架.quartz是个定时任务框架,spring batch是个批处理框架. 虽然我自己的小玩意儿平时不 ...

  2. UWP学习记录7-设计和UI之控件和模式4

    UWP学习记录7-设计和UI之控件和模式4 1.翻转视图 使用翻转视图浏览集合中的图像或其他项目(例如相册中的照片或产品详细信息页中的项目),一次显示一个项目. 对于触摸设备,轻扫某个项将在整个集合中 ...

  3. [Django]模型学习记录篇--基础

    模型学习记录篇,仅仅自己学习时做的记录!!! 实现模型变更的三个步骤: 修改你的模型(在models.py文件中). 运行python manage.py makemigrations ,为这些修改创 ...

  4. 在Ubuntu Server下搭建LAMP环境学习记录

    更新于2015/6/16日,因图片地址失效,请在此地址查看:http://note.youdao.com/share/?id=1c249ae6dc6150cbf692adec67b23a33& ...

  5. [ZHUAN]Flask学习记录之Flask-SQLAlchemy

    From: http://www.cnblogs.com/agmcs/p/4445583.html 各种查询方式:http://www.360doc.com/content/12/0608/11/93 ...

  6. 我的hibernate学习记录(二)

    通过上一篇文章我的hibernate学习记录(一)基本上的入门了hibernate,但是,里面还有还多东西是通过迷迷糊糊的记忆,或者说copy直接弄进去的,所以这篇文章就需要对上篇的一些文件.对象进行 ...

  7. 我的Spring学习记录(二)

    本篇就简单的说一下Bean的装配和AOP 本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的 1. 使用setter方法和构造方法装配Bean 1.1 前期准备 使用sett ...

  8. 我的Spring学习记录(四)

    虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...

  9. 我的Spring学习记录(五)

    在我的Spring学习记录(四)中使用了注解的方式对前面三篇做了总结.而这次,使用了用户登录及注册来对于本人前面四篇做一个应用案例,希望通过这个来对于我们的Spring的使用有一定的了解. 1. 程序 ...

  10. mondb 常用命令学习记录

    mondb 常用命令学习记录 一.MongoDB 下载安装 MongoDB官网 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制 ...

随机推荐

  1. URLDNS链分析

    一.概述 URLDNS 是ysoserial中利用链的一个名字,通常用于检测是否存在Java反序列化漏洞.该利用链具有如下特点: 不限制jdk版本,使用Java内置类,对第三方依赖没有要求 目标无回显 ...

  2. 探究WPF中文字模糊的问题:TextOptions的用法

    有网友问WPF中一些文字模糊是什么问题.之前我也没有认真思考过这个问题,只是大概知道和WPF的像素对齐(pixel snapping).抗锯齿(anti-aliasing)有关,通过设置附加属性Tex ...

  3. iview 动态表单验证 FormItem prop rules v-show 动态表单校验

    iview 动态表单验证 FormItem prop rules v-show 重点1 用v-show 控制显示隐藏 重点2 prop 指定字段 重点3 :rules 动态指定规则 <div v ...

  4. 基于python的PC电脑报警系统

    一 基本概念 1.这里实现了电脑的安全报警系统,假如有人不小心动了你的电脑,立即触发报警系统.报警是通过pc机的声卡播放报警信号. 2.该的基础是对python的pyxhook和wave库的合理应用. ...

  5. .NET Aspire Preview 4 发布!

    .NET Aspire是一个有态度的云原生应用开发框架,旨在改善生成.NET云原生应用的体验,并提供一组强大的工具来帮助你生成和运行分布式应用.它允许开发者快速创建属于自己的云原生应用,或改造已有的项 ...

  6. STM32 启动代码分析

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  7. AXI4从机总线分析验证之读取寄存器值

    AXI4从机总线分析验证之读取寄存器值 1.实验目的 利用前面所学的AXI4总线协议的理论分析,验证如何将一个PL的输入信号通过AXI发送到PS端.大致思路就是取一个按键,信号接入自建的AXI4的IP ...

  8. 基于 alientek rv1126 快速启动调试那的写坑

    基于 alientek rv1126 快速启动调试那的写坑 1. sdk 编制准备工作 1.1 编译配置修改 首先拿到 sdk 通过修改一下相关配置 1.1.1修改DDR 配置 cd /home/al ...

  9. NOIP 2007 普及组

    NOIP 2007 普及组(DONE) 注:本文不附原题,可上Luogu有题对照查询. 1.CPU:即中央处理器,由运算器+控制器+寄存器组成,不含主板(但CPU是装在主板上的). 2.二维表即常见的 ...

  10. 03 jQuery属性控制

    03 jQuery属性控制 属性相关的控制主要有以下几个功能 val() => 处理value属性 text() => 处理innerText html() => 处理innerHT ...