SQLite 是一种轻量级数据库,虽然没有内置的矢量搜索功能,但通过扩展和一些额外的步骤,可以轻松实现矢量搜索。
什么是sqlite-vec?sqlite-vec是一个SQLite数据库的向量搜索扩展,添加了向量搜索功能。
该扩展完备用C措辞编写,无依赖性,具有极好的可移植性,可以在大多数操作系统和环境中运行,且具有MIT/Apache-2.0双重容许证。

sqlite-vec 是一个极小且“足够快”的 SQLite 扩展,许可在 SQLite 中存储和查询浮点、整数和二进制矢量。
它是 sqlite-vss 的继任者,旨在供应跨平台的矢量搜索能力,能够在各种环境下运行,包括 Linux、MacOS、Windows,乃至浏览器(利用 WASM)和树莓派等设备。
什么时候利用sqlite-vec,适用于哪些场景?大多数现实天下的AI运用并不涉及数十亿个向量,而是处理数千或数百个向量。
最近邻(ANN)算法用于索引,但这会降落搜索效率。
sqlite-vec利用快速的暴力搜索,因此适宜小型运用(或数据库)利用。
sqlite-vec有哪些上风?sqlite-vec的几个上风包括:
无其他依赖利用虚拟表在阴影表中存储向量块避免一次性加载所有内容到内存中支持在 vec0 虚拟表中存储和查询浮点、int8 和二进制矢量。利用纯 C 编写,无任何依赖项,能够在任何支持 SQLite 的环境中运行。可通过 rowid IN (...) 子查询预筛选矢量。安装要在您的项目中利用 sqlite-vec,您可以根据您的开拓环境选择相应的安装办法:
措辞
安装命令
更多信息
Python
pip install sqlite-vec
PyPI
Node.js
npm install sqlite-vec
npm
Ruby
gem install sqlite-vec
Gem
Go
go get -u github.com/asg017/sqlite-vec/bindings/go
Go Reference
Rust
cargo add sqlite-vec
Crates.io
Datasette
datasette install datasette-sqlite-vec
Datasette
rqlite
rqlited -extensions-path=sqlite-vec.tar.gz
rqlite
sqlite-utils
sqlite-utils install sqlite-utils-sqlite-vec
sqlite-utils
入门示例以下是如何利用 sqlite-vec 的大略示例:
以下是如何利用 sqlite-vec 的大略示例:
1、加载扩展:
.load ./vec0
2、创建虚拟表:
CREATE VIRTUAL TABLE vec_examples USING vec0( sample_embedding FLOAT[8] -- 创建一个包含8维浮点向量的虚拟表);
3、插入矢量:
您可以通过 JSON 格式或紧凑的二进制格式供应向量。以下是将几个矢量插入表的示例:
INSERT INTO vec_examples(rowid, sample_embedding)VALUES (1, '[-0.200, 0.250, 0.341, -0.211, 0.645, 0.935, -0.316, -0.924]'), (2, '[0.443, -0.501, 0.355, -0.771, 0.707, -0.708, -0.185, 0.362]'), (3, '[0.716, -0.927, 0.134, 0.052, -0.669, 0.793, -0.634, -0.162]'), (4, '[-0.710, 0.330, 0.656, 0.041, -0.990, 0.726, 0.385, -0.958]');
4、实行 KNN 查询:
您可以实行 KNN 查询来查找与给定向量最靠近的向量:
SELECT rowid, distanceFROM vec_examplesWHERE sample_embedding MATCH '[0.890, 0.544, 0.825, 0.961, 0.358, 0.0196, 0.521, 0.175]'ORDER BY distanceLIMIT 2;
这将返回最靠近的两个结果,查询结果类似于:
一个完全示例
假设我们想要创建一个在线书本推举系统。每本书都有一些特色,比如主题、风格和情绪色彩等。我们将用这些特色来为用户推举相似的书本。
import sqlite3import sqlite_vecfrom typing import Listimport structdef serialize_f32(vector: List[float]) -> bytes: """将浮点数列表序列化为紧凑的原始字节格式""" return struct.pack("%sf" % len(vector), vector)# 连接到内存数据库db = sqlite3.connect(":memory:")db.enable_load_extension(True)sqlite_vec.load(db)db.enable_load_extension(False)# 查询SQLite和vec版本sqlite_version, vec_version = db.execute( "select sqlite_version(), vec_version()").fetchone()print(f"sqlite_version={sqlite_version}, vec_version={vec_version}")# 准备书本数据,每本书有一个嵌入向量表示其特色books = [ (1, [0.9, 0.8, 0.1, 0.2]), # 书本 1 特色向量 (2, [0.7, 0.6, 0.2, 0.4]), # 书本 2 特色向量 (3, [0.1, 0.1, 0.9, 0.8]), # 书本 3 特色向量 (4, [0.3, 0.5, 0.7, 0.9]), # 书本 4 特色向量 (5, [0.2, 0.4, 0.6, 0.5]), # 书本 5 特色向量]# 用户喜好的书本特色向量query = [0.1, 0.1, 0.9, 0.8] # 用户输入的书本特色向量# 创建虚拟表用于存储书本信息db.execute("CREATE VIRTUAL TABLE vec_books USING vec0(embedding float[4])")# 插入书本数据with db: for book in books: db.execute( "INSERT INTO vec_books(rowid, embedding) VALUES (?, ?)", [book[0], serialize_f32(book[1])], )# 查询与用户喜好的书本相似的书本rows = db.execute( """ SELECT rowid, distance FROM vec_books WHERE embedding MATCH ? ORDER BY distance LIMIT 3 """, [serialize_f32(query)],).fetchall()# 输出推举的书本print("推举的书本 ID 和与用户输入书本的间隔:")for row in rows: print(row)
代码解读
1、数据准备:
每本书用一个浮点数列表表示其特色向量,向量的不同维度可以代表书本的主题、风格和情绪等。例如:
书本 1:特色向量 [0.9, 0.8, 0.1, 0.2] 可能表示一本浪漫小说。
书本 2:特色向量 [0.7, 0.6, 0.2, 0.4] 可能表示一本悬疑小说。
书本 3:特色向量 [0.1, 0.1, 0.9, 0.8] 可能表示一本科幻小说。
2、查询相似书本:
用户输入的书本特色向量为 [0.1, 0.1, 0.9, 0.8],代表他们喜好的书本。
利用 sqlite_vec 扩展的 MATCH 功能查询与用户输入书本相似的书本,结果按照间隔升序排列,并限定返回 3 条记录。
3、输出推举结果:
末了打印推举的书本的 ID 和与用户输入书本的间隔。
输出:
这个代码实现了一个大略的书本推举系统,通过输入用户喜好书本的特色,查询与之相似的书本,并推举给用户。
这样的实现办法可以用在各种基于特色的推举系统中,比如电影推举、音乐推举等。
知识拓展Q: 什么是向量量化?它为什么主要?向量量化如何事情?
A: 向量量化是一种向量压缩技能。我们通过以下例子来理解:
每个浮点向量占用4字节的空间。如果我们须要存储100万个向量,每个向量有1500维,那么所需的存储空间为:
sqlite-vec支持位向量和浮点向量换句话说,在sqlite-vec中,一个向量可以用1位表示。因此,大小减少了32倍。
Q: 向量量化的后果是什么?
A: 向量量化或任何其他向量压缩技能会导致质量丢失。根据嵌入模型的不同,准确率将降落约5-10%,但查询速率将提高约10倍。
结论sqlite-vec 供应了一种大略、跨平台的办法来实现 SQLite 中的矢量搜索。
通过加载扩展、创建虚拟表、插入矢量并实行 KNN 查询,您可以在自己的运用程序中轻松集成这一强大功能。
这种能力能够显著提升数据检索的灵巧性和准确性,特殊是在处理自然措辞处理和机器学习干系任务时。
https://alexgarcia.xyz/blog/2024/sqlite-vec-stable-release/index.html