Want to Become a Sponsor? Contact Us Now!🎉

vector-database
Pgvector:如何轻松将PostgreSQL转变为矢量数据库

Pgvector:如何轻松将PostgreSQL转变为矢量数据库

Published on

如果你正在使用PostgreSQL而且还没有听说过pgvector,那你就错过了一个具有改变游戏规则的扩展。pgvector被设计为为你的PostgreSQL数据库提供超强动力,它是一款专为高效存储矢量数据和相似搜索而设计的终极工具。它不仅仅是一个插件; 它是一个完整的解决方案,与PostgreSQL无缝集成,将其功能提升到新的高度。

但你为什么要关心呢?因为在当今数据驱动的世界中,有效地存储和查询大量矢量数据对于机器学习、推荐系统和许多其他应用非常重要。pgvector不仅使这成为可能,而且以难以匹敌的效率和速度进行操作。

pgvector对于PostgreSQL用户的重要性

什么是pgvector?

pgvector是一款PostgreSQL扩展,专门用于存储矢量并在这些矢量中执行相似搜索。与传统的PostgreSQL数据类型不同,pgvector针对高维数据进行了优化,非常适合机器学习模型、图像识别和自然语言处理任务。

ℹ️

pgvector的核心特性:

  • 高效的矢量存储:pgvector在不丢失数据完整性的情况下压缩高维矢量。这是一件大事,因为高维数据可能会成为存储的噩梦。

  • 多种距离度量:无论你使用欧几里德距离、余弦相似度还是曼哈顿距离,pgvector都能应对。它支持多种距离度量,让你能够灵活选择最适合你特定用例的度量方式。

  • 无缝集成:pgvector最好的地方之一就是它如何轻松地与PostgreSQL集成。你不需要在不同的数据库之间切换; pgvector作为本地扩展工作,允许你在PostgreSQL内部执行复杂的查询。

让我们来看一下具体数据。使用pgvector,你可以以约1800次查询每秒(QPS)的速度运行100万个OpenAI嵌入,并达到91%的准确率。如果你追求更高的准确率,你可以以惊人的98%准确率达到670次QPS。这些指标不仅令人印象深刻,而且是革命性的。

pgvector的性能不仅仅停留在高QPS和准确率上。它还具有极高的可扩展性。无论你是在配备32 GB内存的8核ARM上运行,还是在配备256 GB内存的64核ARM上运行,pgvector都能很好地扩展,确保你从硬件资源中获得最大的利益。

pgvector有多快?(pgvector基准测试)

分解pgvector的速度和准确率

如果你在寻找矢量搜索中的速度和准确率,pgvector能满足你的需求。最新版本的pgvector 0.4.0经过了严格的测试来评估其性能。让我们进入细节:

基准测试方法

  • 测试运行器:使用Python脚本进行数据上传、索引创建和查询执行。
  • 运行时间:每个测试运行了30-40分钟,涵盖了各种工作负载水平以测量性能。
  • 预热的RAM:在每个测试之前,执行了10,000到50,000次“预热”查询,以优化RAM的使用情况。

用于测试的硬件

  • 2XL:8核ARM,32 GB内存
  • 4XL:16核ARM,64 GB内存
  • 8XL:32核ARM,128 GB内存
  • 12XL:48核ARM,192 GB内存
  • 16XL:64核ARM,256 GB内存

数据集

测试使用了dbpedia-entities-openai-1M (opens in a new tab)数据集,其中包含100万个1536维的嵌入。此数据集使用OpenAI创建,并基于维基百科文章。

性能结果

  • 探测设置为10:pgvector在@10准确率为0.91,每秒查询数(QPS)为380。
  • 探测设置为40:pgvector不仅变得更快,而且在与Qdrant相比保持了几乎相同的准确率,@10的准确率为0.98,QPS为140。

数据库的扩展

pgvector的性能可以可预测地随数据库的大小扩展。例如,4XL实例在探测设置为40时达到了0.98的@10准确率和270的QPS。8XL实例获得了0.98的@10准确率和470的QPS,超过了Qdrant的结果。

pgvector的基准测试结果

在配备64核、256 GB内存的服务器上,pgvector以约1800次QPS和0.91的准确率完成了测试。这是版本0.4.0的结果,值得注意的是新版本预计会展示更好的性能。

pgvector相对商业矢量数据库的优势

深入研究了pgvector的令人印象深刻的基准测试之后,你可能想知道它与Milvus等其他商业矢量数据库解决方案相比如何。那么,让我们来分析一下:

集成的便利性

  • Milvus:作为一个独立服务运行,给你的技术堆栈增加了复杂性。
  • pgvector:与PostgreSQL无缝集成,简化了你的技术堆栈。

数据同步

  • Milvus:缺乏本地集成,导致数据同步问题
  • pgvector:提供本地集成,消除了同步问题。

性能指标

  • Milvus:难以与pgvector的性能相匹配。
  • pgvector:在1800 QPS下处理100万个OpenAI嵌入,并拥有91%的准确率
指标Milvuspgvector
集成复杂性
数据同步有问题的无缝的
查询速度(QPS)较低1800
准确性较低91%

总之,如果您正在寻找一个流畅高效高性能的向量存储和搜索解决方案,pgvector是明显的胜利者

优化pgvector性能的提示

  • 调整您的Postgres配置:确保它与您的RAM和CPU核心对齐。
  • 预热数据库:使用之前描述的预热技术。
  • 选择正确的距离函数:如果您的向量已归一化,请优先选择内积(inner-product)距离而不是L2或余弦距离。
  • 调整列表常数:增加此参数可以加速查询。例如,使用OpenAI嵌入的测试使用了2000的列表常数,而不是建议的1000。

通过查看这些详细指标和提示,很明显pgvector为向量存储和相似性搜索提供了强大的性能,使其成为PostgreSQL用户的首选。

您可以使用pgvector做什么?

如何将pgvector用作开源向量数据库

Pgvector不仅仅是一个扩展程序;它是一个将您的PostgreSQL数据库转变为强大的向量数据库的变革性工具。对于那些想要在高维数据上执行复杂操作而不必切换到专门的数据库的人来说,这特别有用。在本节中,我们将深入介绍如何设置和使用pgvector作为开源向量数据库。

安装和设置:

  1. 克隆存储库:首先克隆pgvector GitHub存储库到本地机器。
git clone https://github.com/your/pgvector/repo.git
  1. 编译和安装:导航到目录并编译扩展。
cd pgvector
make
make install
  1. 数据库配置:登录到您的PostgreSQL数据库并创建pgvector扩展。
CREATE EXTENSION pgvector;
  1. 创建表:创建一个具有向量列的表以存储高维数据。
CREATE TABLE my_vectors (id SERIAL PRIMARY KEY, vector_field VECTOR(128));

基本操作:

  1. 插入向量:将数据插入向量字段中。
INSERT INTO my_vectors (vector_field) VALUES ('{1.1, 2.2, 3.3, ..., 128.128}');
  1. 向量搜索:使用向量字段执行相似性搜索。
SELECT * FROM my_vectors ORDER BY vector_field <-> '{3.3, 2.2, 1.1, ..., 128.128}' LIMIT 10;
  1. 索引:创建索引以加快相似性搜索。
CREATE INDEX idx_vector_field ON my_vectors USING ivfflat(vector_field);

高级功能:

  1. 调整参数:您可以调整索引的参数以在速度和准确性之间平衡。
SET pgvector.index_type = 'hnsw';
SET pgvector.ef_search = 64;
  1. 批处理操作:Pgvector支持批处理操作用于插入和更新向量,这对于机器学习应用特别有用。

  2. 监控和可观察性:使用PostgreSQL内置的监控工具监视向量操作的性能情况。

pgvector的k-NN搜索能力

什么是k-NN搜索?

k-NN(k-Nearest Neighbors)搜索是一种在多维空间中找到与给定点“k”个最接近点的算法。它在机器学习中用于分类和聚类。

pgvector如何支持k-NN:

  • 数据类型:pgvector引入了一个称为vector的新数据类型,用于存储多维数据。
  • 运算符:它提供了像<->用于计算欧几里德距离和<=>用于计算余弦距离的运算符,以计算向量之间的相似性。
  • 索引:您可以在向量列上创建索引以加速k-NN查询。

这是一个使用pgvector执行k-NN搜索的SQL函数:

CREATE OR REPLACE FUNCTION knn_search(query_vector vector, k int)
RETURNS TABLE(id INT, distance FLOAT)
LANGUAGE SQL STABLE AS $$
SELECT id, query_vector <=> vector_column AS distance
FROM your_table
ORDER BY distance ASC
LIMIT k;
$$;

使用pgvector存储OpenAI嵌入

为什么要存储OpenAI嵌入? OpenAI嵌入是捕捉文本的语义含义的高维向量。它们对于文本相似性、聚类和分类等任务非常有用。

如何使用pgvector存储OpenAI嵌入

  1. 创建表:创建一个带有vector类型列的PostgreSQL表。
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(1536)
);
  1. 插入数据:将OpenAI嵌入插入到embedding列中。
INSERT INTO documents(content, embedding) VALUES ('some text', '{your 1536-dim vector}');
  1. 查询:使用pgvector的运算符查询嵌入向量。
SELECT * FROM documents WHERE embedding <=> '{query vector}' < 0.5;

pgvector与Langchain:高级文本搜索

Langchain和PGVector可以结合使用创建强大的文本搜索和检索系统。以下是如何将PGVector与Langchain集成以执行高级文本搜索操作的指南。

前提条件

  • 确保您已安装所有必要的软件包,并按照笔记本的初始部分中所示设置了环境变量。

步骤1:初始化Langchain组件 首先,初始化Langchain组件,如OpenAIEmbeddingsTextLoaderCharacterTextSplitter

from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.document_loaders import TextLoader
 
loader = TextLoader("your_text_file.txt")
documents = loader.load()

text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) docs = text_splitter.split_documents(documents) embeddings = OpenAIEmbeddings()


**第2步. 初始化PGVector**
接下来,使用你的Postgres数据库的连接字符串初始化PGVector。

```python
from langchain.vectorstores.pgvector import PGVector

CONNECTION_STRING = "your_connection_string_here"
COLLECTION_NAME = "your_collection_name_here"

db = PGVector.from_documents(
embedding=embeddings,
documents=docs,
collection_name=COLLECTION_NAME,
connection_string=CONNECTION_STRING,
)

第3步. 执行相似度搜索 现在,你可以使用PGVector的similarity_search_with_score方法执行相似度搜索。

query = "Your search query here"
docs_with_score = db.similarity_search_with_score(query)
 
for doc, score in docs_with_score:
print("Score: ", score)
print(doc.page_content)

第4步. 最大边际相关性搜索 对于更高级的搜索,你可以使用最大边际相关性(MMR)来同时优化查询与所选文档之间的相似性和多样性。

docs_with_score = db.max_marginal_relevance_search_with_score(query)
 
for doc, score in docs_with_score:
print("Score: ", score)
print(doc.page_content)

第5步. 使用现有的VectorStore 如果你已经有了一个现有的向量存储,你可以直接初始化它并添加文档。

store = PGVector(
collection_name=COLLECTION_NAME,
connection_string=CONNECTION_STRING,
embedding_function=embeddings,
)
 
store.add_documents([Document(page_content="new_content_here")])

第6步. 覆盖现有的VectorStore 如果你需要更新现有的集合,你可以覆盖它。

db = PGVector.from_documents(
documents=docs,
embedding=embeddings,
collection_name=COLLECTION_NAME,
connection_string=CONNECTION_STRING,
pre_delete_collection=True,
)

第7步. 使用VectorStore作为检索器 最后,你可以将向量存储作为检索器来执行更高级的操作。

retriever = store.as_retriever()
print(retriever)

使用Amazon SageMaker、Amazon RDS for PostgreSQL和pgvector构建AI驱动的搜索

在本节中,我们将演示如何使用Amazon SageMaker和Amazon RDS for PostgreSQL与pgvector扩展构建一个产品目录相似性搜索解决方案。我们将使用一个预训练的Hugging Face模型生成文档嵌入,并将它们存储在RDS for PostgreSQL数据库中。然后,我们将利用pgvector的相似性搜索能力来找到与客户的搜索查询最匹配的产品目录中的项目。

实施解决方案的步骤:

  1. 设置SageMaker笔记本实例: 创建一个SageMaker笔记本实例,在Jupyter笔记本中运行Python代码。

  2. 数据准备: 使用Amazon Translate将项目描述从德语翻译成英语。

  3. 模型托管: 将预训练的Hugging Face模型部署到SageMaker,为产品目录生成384维的向量嵌入。

  4. 数据存储: 连接到RDS for PostgreSQL,并创建一个表来存储原始文本和文本嵌入。

  5. 实时推断: 使用SageMaker将查询文本编码成嵌入向量。

  6. 相似性搜索: 在RDS for PostgreSQL数据库中使用pgvector执行相似性搜索。

先决条件:

  • 具有适当IAM权限的AWS账户。
  • 熟悉SageMaker、RDS和CloudFormation等AWS服务。

部署: 使用AWS CloudFormation堆栈来部署解决方案,将创建所有必要的资源,包括网络组件、SageMaker笔记本实例和RDS for PostgreSQL实例。

下面是实施解决方案的一些关键代码片段:

  • 数据摄入: 使用Amazon Translate将项目描述从德语翻译成英语。
import boto3
translate = boto3.client(service_name='translate', use_ssl=True)
result = translate.translate_text(Text=str(j), SourceLanguageCode="de", TargetLanguageCode="en")
  • 模型托管: 将预训练的Hugging Face模型部署到SageMaker。
from sagemaker.huggingface.model import HuggingFaceModel
predictor = HuggingFaceModel(env=hub, role=role).deploy(initial_instance_count=1, instance_type="ml.m5.xlarge")
  • 数据存储: 在RDS for PostgreSQL中创建一个表来存储嵌入向量。
CREATE TABLE IF NOT EXISTS products(
id bigserial primary key,
description text,
descriptions_embeddings vector(384)
);
  • 相似性搜索: 使用pgvector在RDS for PostgreSQL数据库中执行相似性搜索。
SELECT id, url, description, descriptions_embeddings
FROM products
ORDER BY descriptions_embeddings <-> ARRAY[...];

如何在Python中使用PgVector

当然,你可以通过添加自定义方法或将其与其他Python库集成,来扩展Python中的pgvector功能。下面是一个示例,演示了如何扩展pgvector以包括在Django中计算两个向量之间的欧氏距离的方法。

扩展Django功能

首先,让我们为Item模型创建一个自定义管理器,其中包含一个用于计算欧氏距离的方法。

from django.db import models
from pgvector.django import VectorField, L2Distance
import math
 
class ItemManager(models.Manager):
def euclidean_distance(self, vector):
# 使用pgvector的L2Distance函数获取平方欧氏距离
queryset = self.annotate(distance_squared=L2Distance('embedding', vector))
 
# 取平方根得到实际的欧氏距离
for item in queryset:
item.distance = math.sqrt(item.distance_squared)
 
return queryset
 
class Item(models.Model):
embedding = VectorField(dimensions=3)
```python
objects = ItemManager()

现在您可以在Django视图或shell中使用此自定义管理器:

# 按照与向量[3, 1, 2]的欧氏距离对项目进行排序
items = Item.objects.euclidean_distance([3, 1, 2]).order_by('distance')
 
# 打印项目及其距离
for item in items:
print(f"项目ID:{item.id},距离:{item.distance}")

扩展SQLAlchemy功能

同样,您可以通过添加自定义查询类来扩展SQLAlchemy功能。

from sqlalchemy import Column, Integer, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, BaseQuery
from sqlalchemy.sql import func
from pgvector.sqlalchemy import Vector
 
Base = declarative_base()
 
class VectorQuery(BaseQuery):
def euclidean_distance(self, vector):
return self.add_columns(
func.sqrt(
func.pow(Vector.l2_distance(self._entities[0].field, vector), 2)
).label('distance')
)
 
class Item(Base):
__tablename__ = 'items'
 
id = Column(Integer, primary_key=True, autoincrement=True)
embedding = Column(Vector(3))
 
@classmethod
def query(cls):
return VectorQuery(cls)
 
# 数据库设置
engine = create_engine('postgresql://localhost/mydatabase')
Base.metadata.create_all(engine)
 
Session = sessionmaker(bind=engine)
session = Session()
 
# 获取项目及其与向量[3, 1, 2]的欧氏距离
items_with_distance = session.query(Item).euclidean_distance([3, 1, 2]).all()
 
# 打印项目及其距离
for item, distance in items_with_distance:
print(f"项目ID:{item.id},距离:{distance}")

在此示例中,我在Item类中添加了一个id字段作为主键。VectorQuery类用于扩展查询功能,添加了一个计算欧氏距离的方法。最后,使用query类方法为Item模型设置了这个自定义查询类。

然后,您可以在SQLAlchemy代码中使用它:

# 获取项目及其与向量[3, 1, 2]的欧氏距离
items = session.query(Item).euclidean_distance([3, 1, 2]).all()
 
# 打印项目及其距离
for item, distance in items:
print(f"项目ID:{item.id},距离:{distance}")

结论

如果您正在使用PostgreSQL数据库,pgvector会改变游戏规则。它不仅仅是一个附加组件;它就像是给数据库装了个涡轮增压器。它让您能够快速而准确地存储和搜索大量数据。对于机器学习等需要快速处理大量数据的任务非常有用。

更重要的是,pgvector可以完美融入PostgreSQL,因此您不必管理多个数据库。它还具有灵活性,可以根据需要选择如何测量数据点之间的“距离”。如果您正在使用Django等Python框架,甚至可以扩展其功能。简而言之,如果您涉及数据且正在使用PostgreSQL,那么您不会错过pgvector。

常见问题

Pgvector有什么用处?

Pgvector是用于PostgreSQL数据库的扩展,专门用于存储和搜索大量向量集。它特别适用于需要快速和准确的相似性搜索的应用,例如机器学习模型、推荐系统和自然语言处理任务。

Pgvector有哪些优点?

Pgvector具有以下几个优点:

  1. 速度快:即使处理高维数据,也能进行快速查询。
  2. 效率高:它可以在不丢失数据完整性的情况下压缩数据,节省存储空间。
  3. 灵活性强:支持多种距离度量,如欧氏距离、余弦距离和曼哈顿距离,可以根据需求选择最佳距离度量方法。
  4. 无缝集成:它直接集成到PostgreSQL中,无需管理多个数据库。
  5. 可扩展性强:在各种硬件配置上表现良好,确保资源的最佳利用。

PostgreSQL是一个向量数据库吗?

不,PostgreSQL本身并不是一个向量数据库。然而,通过使用Pgvector扩展,您可以有效地将PostgreSQL打造成一个功能强大的向量数据库,能够存储和执行高维数据的相似性搜索。

如何在PostgreSQL中使用Pgvector?

要在PostgreSQL中使用Pgvector,您需要执行以下操作:

  1. 在PostgreSQL数据库中运行CREATE EXTENSION pgvector;命令安装Pgvector扩展。
  2. 创建一个具有向量列的表,例如:CREATE TABLE my_vectors (id SERIAL PRIMARY KEY, vector_field VECTOR(128));
  3. 将向量插入表中:INSERT INTO my_vectors (vector_field) VALUES ('{1.1, 2.2, 3.3, ..., 128.128}');
  4. 使用SQL查询执行相似性搜索,例如:SELECT * FROM my_vectors ORDER BY vector_field <-> '{3.3, 2.2, 1.1, ..., 128.128}' LIMIT 10;
Anakin AI - The Ultimate No-Code AI App Builder