Want to Become a Sponsor? Contact Us Now!🎉

vector-database
Pgvector: Como Transformar o PostgreSQL em um Banco de Dados Vetorial Facilmente

Pgvector: Como Transformar o PostgreSQL em um Banco de Dados Vetorial Facilmente

Published on

Se você está usando o PostgreSQL e ainda não ouviu falar do pgvector, está perdendo uma extensão que está mudando o jogo. Projetado para turbinar seu banco de dados PostgreSQL, pgvector é a ferramenta definitiva para o armazenamento e busca eficiente de vetores. Não é apenas um complemento; é uma solução completa que se integra perfeitamente ao PostgreSQL, melhorando suas capacidades a novos patamares.

Mas por que você deveria se importar? Porque no mundo de hoje, orientado por dados, a capacidade de armazenar e consultar conjuntos grandes de vetores de forma eficiente é crucial para aprendizado de máquina, sistemas de recomendação e muitas outras aplicações. O pgvector não apenas torna isso possível, mas o faz com um nível de eficiência e velocidade difícil de igualar.

Por que pgvector é essencial para usuários do PostgreSQL

O que é pgvector?

pgvector é uma extensão do PostgreSQL especializada em armazenar vetores e realizar buscas de similaridade dentro desses vetores. Ao contrário dos tipos de dados tradicionais do PostgreSQL, o pgvector é otimizado para dados em alta dimensão, tornando-o ideal para modelos de aprendizado de máquina, reconhecimento de imagens e processamento de linguagem natural.

ℹ️

Recursos Principais do pgvector:

  • Armazenamento Eficiente de Vetores: pgvector comprime vetores de alta dimensão sem perder a integridade dos dados. Isso é muito importante, pois dados de alta dimensão podem ser um pesadelo em termos de armazenamento.

  • Várias Métricas de Distância: Seja trabalhando com distâncias Euclidianas, Cosseno ou Manhattan, o pgvector tem tudo o que você precisa. Ele suporta uma variedade de métricas de distância, oferecendo a flexibilidade de escolher a melhor para o seu caso de uso específico.

  • Integração Perfeita: Uma das melhores coisas sobre o pgvector é como ele se integra perfeitamente ao PostgreSQL. Você não precisa alternar entre diferentes bancos de dados; o pgvector funciona como uma extensão nativa, permitindo que você faça consultas complexas diretamente no PostgreSQL.

Vamos aos números. Com o pgvector, você pode executar 1 milhão de embeddings do OpenAI a aproximadamente 1800 consultas por segundo (QPS) com uma taxa de precisão de 91%. Se você busca maior precisão, pode atingir 670 QPS com uma taxa de precisão impressionante de 98%. Essas métricas não são apenas impressionantes; são revolucionárias.

O desempenho do pgvector não se limita apenas a alta QPS e precisão. Ele também é incrivelmente escalável. Esteja você executando-o em um ARM de 8 núcleos com 32 GB de RAM ou em um ARM de 64 núcleos com 256 GB, o pgvector se adapta perfeitamente, garantindo que você aproveite ao máximo seus recursos de hardware.

Quão Rápido é realmente o pgvector? (Benchmarks do pgvector)

Analisando a Velocidade e Precisão do pgvector

Se você procura velocidade e precisão em buscas de vetores, o pgvector tem o que você precisa. A versão mais recente, pgvector 0.4.0, passou por testes rigorosos para medir seu desempenho. Vamos aos detalhes:

Metodologia dos Benchmark

  • Test Runner: Um script Python foi utilizado para upload de dados, criação de índice e execução de consulta.
  • Tempo de Execução: Cada teste foi executado por 30 a 40 minutos, cobrindo vários níveis de carga de trabalho para medir o desempenho.
  • Aquecimento da RAM: Antes de cada teste, foram executadas de 10.000 a 50.000 consultas de "aquecimento" para otimizar a utilização de RAM.

Hardware Utilizado nos Testes

  • 2XL: ARM de 8 núcleos, 32 GB de RAM
  • 4XL: ARM de 16 núcleos, 64 GB de RAM
  • 8XL: ARM de 32 núcleos, 128 GB de RAM
  • 12XL: ARM de 48 núcleos, 192 GB de RAM
  • 16XL: ARM de 64 núcleos, 256 GB de RAM

Conjunto de Dados

Os testes utilizaram o conjunto de dados dbpedia-entities-openai-1M (opens in a new tab), que inclui 1 milhão de embeddings com 1536 dimensões. Esse conjunto de dados é criado usando o OpenAI e é baseado em artigos da Wikipedia.

Resultados de Desempenho

  • Com Probes definido para 10: o pgvector obteve um accuracy@10 de 0,91 e um QPS (consultas por segundo) de 380.
  • Com Probes definido para 40: o pgvector não apenas ficou mais rápido, como também manteve praticamente a mesma precisão do Qdrant, com uma accuracy@10 de 0,98 e um QPS de 140.

Escalando o Banco de Dados

O desempenho do pgvector escala de forma previsível com o tamanho do banco de dados. Por exemplo, uma instância 4XL obteve uma accuracy@10 de 0,98 e um QPS de 270 com probes definidos para 40. Uma instância 8XL obteve uma accuracy@10 de 0,98 e um QPS de 470, superando os resultados do Qdrant.

Resultados de Benchmark do pgvector

Em um servidor 64-core, 256 GB, o pgvector atingiu cerca de 1800 QPS com uma precisão de 0,91. Isso é para a versão 0.4.0, e vale ressaltar que espera-se que versões mais recentes apresentem um desempenho ainda melhor.

Por que o pgvector é Melhor do que Bancos de Dados Vetoriais Comerciais

Após analisar os impressionantes benchmarks do pgvector, você pode estar se perguntando como ele se compara a outras soluções comerciais de bancos de dados vetoriais, como o Milvus. Bem, vamos analisar:

Facilidade de Integração

  • Milvus: Opera como um serviço separado, adicionando complexidade à sua pilha de tecnologia.
  • pgvector: Se integra perfeitamente ao PostgreSQL, simplificando sua pilha de tecnologia.

Sincronização de Dados

  • Milvus: Não oferece integração nativa, levando a problemas de sincronização de dados.
  • pgvector: Oferece integração nativa, eliminando problemas de sincronização.

Métricas de Desempenho

  • Milvus: Luta para igualar o desempenho do pgvector.
  • pgvector: Lida com 1 milhão de embeddings do OpenAI a 1800 QPS com uma taxa de precisão de 91%.
MétricaMilvuspgvector
Complexidade de IntegraçãoAltaBaixa
Sincronização de DadosProblemáticaPerfeita
Velocidade de Consulta (QPS)Menor1800
PrecisãoMenor91%

Em resumo, se você está procurando por uma solução simplificada, eficiente e de alto desempenho para armazenamento e busca de vetores, pgvector é a escolha clara.

Dicas para otimizar o desempenho do pgvector

  • Ajuste sua Configuração do Postgres: Certifique-se de que esteja alinhada com sua RAM e núcleos da CPU.
  • Pré-aqueça seu Banco de Dados: Use a técnica de aquecimento descrita anteriormente.
  • Escolha a Função de Distância Correta: Se seus vetores estiverem normalizados, prefira o produto interno em relação às distâncias L2 ou cosseno.
  • Ajuste a Constante lists: Aumentar isso pode acelerar suas consultas. Por exemplo, testes com embeddings da OpenAI usaram uma constante de lists de 2000 em vez do valor sugerido de 1000.

Ao analisar essas métricas detalhadas e dicas, fica claro que o pgvector oferece um desempenho robusto para armazenamento de vetores e busca de similaridade, tornando-o uma escolha primordial para usuários do PostgreSQL.

O que você pode fazer com o pgvector?

Como usar o pgvector como um Banco de Dados de Vetores de Código Aberto

O pgvector não é apenas uma extensão; é uma ferramenta transformadora que transforma seu banco de dados PostgreSQL em um poderoso banco de dados de vetores. Isso é particularmente útil para aqueles que desejam realizar operações complexas em dados de alta dimensão sem precisar trocar para um banco de dados especializado. Nesta seção, veremos como configurar e usar o pgvector como um banco de dados de vetores de código aberto.

Instalação e Configuração:

  1. Clone o Repositório: Comece clonando o repositório do pgvector no GitHub para sua máquina local.
git clone https://github.com/your/pgvector/repo.git
  1. Compile e Instale: Navegue até o diretório e compile a extensão.
cd pgvector
make
make install
  1. Configuração do Banco de Dados: Faça login no seu banco de dados PostgreSQL e crie a extensão pgvector.
CREATE EXTENSION pgvector;
  1. Criação da Tabela: Crie uma tabela com uma coluna de vetor para armazenar seus dados de alta dimensão.
CREATE TABLE my_vectors (id SERIAL PRIMARY KEY, vector_field VECTOR(128));

Operações Básicas:

  1. Inserindo Vetores: Insira dados no campo de vetor.
INSERT INTO my_vectors (vector_field) VALUES ('{1.1, 2.2, 3.3, ..., 128.128}');
  1. Busca por Vetor: Realize uma busca de similaridade usando o campo de vetor.
SELECT * FROM my_vectors ORDER BY vector_field <-> '{3.3, 2.2, 1.1, ..., 128.128}' LIMIT 10;
  1. Indexação: Crie um índice para acelerar suas buscas de similaridade.
CREATE INDEX idx_vector_field ON my_vectors USING ivfflat(vector_field);

Recursos Avançados:

  1. Ajuste de Parâmetros: Você pode ajustar os parâmetros do seu índice para equilibrar velocidade e precisão.
SET pgvector.index_type = 'hnsw';
SET pgvector.ef_search = 64;
  1. Operações em Lote: O pgvector suporta operações em lote para inserir e atualizar vetores, o que pode ser especialmente útil para aplicações de aprendizado de máquina.

  2. Monitoramento e Observabilidade: Use as ferramentas de monitoramento integradas do PostgreSQL para acompanhar o desempenho de suas operações com vetores.

Capacidades de Pesquisa k-NN do pgvector

O que é Pesquisa k-NN?

A pesquisa k-NN (k-Nearest Neighbors) é um algoritmo usado para encontrar os "k" pontos mais próximos a um determinado ponto em um espaço multidimensional. É amplamente utilizado em aprendizado de máquina para classificação e agrupamento.

Como o pgvector Possibilita o k-NN:

  • Tipo de Dado: O pgvector introduz um novo tipo de dado chamado vector, que pode armazenar dados multidimensionais.
  • Operadores: Ele fornece operadores como <-> para distância euclidiana e <=> para distância de cosseno para calcular a similaridade entre vetores.
  • Indexação: Você pode criar índices nas colunas de vetor para acelerar consultas de k-NN.

Aqui está uma função SQL que realiza uma pesquisa k-NN usando o pgvector:

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;
$$;

Armazenando Embeddings da OpenAI com o pgvector

Por que Armazenar Embeddings da OpenAI? Embeddings da OpenAI são vetores de alta dimensão que capturam o significado semântico de texto. Eles são úteis para tarefas como similaridade de texto, agrupamento e classificação.

Como Armazenar Embeddings da OpenAI com o pgvector

  1. Crie uma Tabela: Crie uma tabela do PostgreSQL com uma coluna do tipo vector.
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(1536)
);
  1. Insira Dados: Insira os embeddings da OpenAI na coluna embedding.
INSERT INTO documents(content, embedding) VALUES ('some text', '{seu vetor de 1536-dim}');
  1. Consulta: Use os operadores do pgvector para consultar os embeddings.
SELECT * FROM documents WHERE embedding <=> '{vetor de consulta}' < 0.5;

PGVector com Langchain: Pesquisa Avançada de Texto

O Langchain e o PGVector podem ser combinados para criar um poderoso sistema de pesquisa e recuperação de texto. Abaixo está um guia sobre como integrar o PGVector com o Langchain para realizar operações avançadas de pesquisa de texto.

Pré-requisitos

  • Verifique se você instalou todos os pacotes necessários e configurou suas variáveis de ambiente conforme mostrado na seção inicial do seu caderno.

Passo 1. Inicialize os Componentes do Langchain Primeiramente, inicialize os componentes do Langchain como OpenAIEmbeddings, TextLoader e CharacterTextSplitter.

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()


**Passo 2. Inicialize PGVector**
Em seguida, inicialize PGVector com a string de conexão para seu banco de dados Postgres.

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

CONNECTION_STRING = "sua_string_de_conexão_aqui"
COLLECTION_NAME = "seu_nome_de_coleção_aqui"

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

Passo 3. Realizar Pesquisa de Similaridade Agora você pode realizar uma pesquisa de similaridade usando o método similarity_search_with_score do PGVector.

query = "Sua consulta de pesquisa aqui"
docs_with_score = db.similarity_search_with_score(query)
 
for doc, score in docs_with_score:
print("Pontuação: ", score)
print(doc.page_content)

Passo 4. Pesquisa de Relevância Marginal Máxima Para uma pesquisa mais avançada, você pode usar a Pesquisa de Relevância Marginal Máxima (MMR) para otimizar tanto a similaridade com a consulta quanto a diversidade entre os documentos selecionados.

docs_with_score = db.max_marginal_relevance_search_with_score(query)
 
for doc, score in docs_with_score:
print("Pontuação: ", score)
print(doc.page_content)

Passo 5. Trabalhando com VectorStore Existente Se você já tiver um VectorStore existente, você pode inicializá-lo diretamente e adicionar documentos a ele.

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

Passo 6. Sobrepondo um VectorStore Existente Se você precisa atualizar uma coleção existente, você pode sobrepor ela.

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

Passo 7. Usando VectorStore como um Retriever Por fim, você pode usar o vector store como um recuperador para operações mais avançadas.

retriever = store.as_retriever()
print(retriever)

Construindo Pesquisa com IA-Powered usando Amazon SageMaker, Amazon RDS for PostgreSQL e pgvector

Nesta seção, demonstramos como construir uma solução de pesquisa de similaridade de catálogo de produtos usando o Amazon SageMaker e o Amazon RDS for PostgreSQL com a extensão pgvector. Usaremos um modelo pré-treinado do Hugging Face para gerar embeddings de documentos e armazená-los em um banco de dados RDS for PostgreSQL. Em seguida, utilizaremos as capacidades de pesquisa de similaridade do pgvector para encontrar itens no catálogo de produtos que melhor correspondam à consulta de pesquisa de um cliente.

Passos para Implementar a Solução:

  1. Configurar a Instância de Notebook do SageMaker: Crie uma instância de notebook do SageMaker para executar o código Python em um notebook Jupyter.

  2. Preparação de Dados: Traduza as descrições dos itens do alemão para o inglês usando o Amazon Translate.

  3. Hospedagem do Modelo: Implante um modelo pré-treinado do Hugging Face no SageMaker para gerar embeddings de vetor de 384 dimensões para o catálogo de produtos.

  4. Armazenamento de Dados: Conecte-se ao RDS for PostgreSQL e crie uma tabela para armazenar o texto bruto e os embeddings de texto.

  5. Inferência em Tempo Real: Use o SageMaker para codificar o texto da consulta em embeddings.

  6. Pesquisa de Similaridade: Realize uma pesquisa de similaridade usando o pgvector no banco de dados RDS for PostgreSQL.

Pré-requisitos:

  • Uma conta da AWS com permissões IAM apropriadas.
  • Familiaridade com serviços da AWS como SageMaker, RDS e CloudFormation.

Implantação: Use um stack do AWS CloudFormation para implantar a solução, que criará todos os recursos necessários, incluindo componentes de rede, uma instância de notebook do SageMaker e uma instância do RDS for PostgreSQL.

Aqui estão alguns trechos de código-chave para implementar a solução:

  • Ingestão de Dados: Use o Amazon Translate para traduzir as descrições dos itens do alemão para o inglês.
import boto3
translate = boto3.client(service_name='translate', use_ssl=True)
result = translate.translate_text(Text=str(j), SourceLanguageCode="de", TargetLanguageCode="en")
  • Hospedagem do Modelo: Implante um modelo pré-treinado do Hugging Face no SageMaker.
from sagemaker.huggingface.model import HuggingFaceModel
predictor = HuggingFaceModel(env=hub, role=role).deploy(initial_instance_count=1, instance_type="ml.m5.xlarge")
  • Armazenamento de Dados: Crie uma tabela no RDS for PostgreSQL para armazenar os embeddings.
CREATE TABLE IF NOT EXISTS products(
id bigserial primary key,
description text,
descriptions_embeddings vector(384)
);
  • Pesquisa de Similaridade: Realize uma pesquisa de similaridade usando o pgvector.
SELECT id, url, description, descriptions_embeddings
FROM products
ORDER BY descriptions_embeddings <-> ARRAY[...];

Como usar o PgVector em Python

Certamente, você pode estender a funcionalidade do pgvector em Python adicionando métodos personalizados ou integrando-o com outras bibliotecas Python. Abaixo está um exemplo de como você poderia estender o pgvector para incluir um método de cálculo da distância euclidiana entre dois vetores no Django.

Estendendo a Funcionalidade do Django

Primeiro, vamos criar um gerenciador personalizado para o modelo Item que inclui um método para calcular a distância euclidiana.

from django.db import models
from pgvector.django import VectorField, L2Distance
import math
 
class ItemManager(models.Manager):
def euclidean_distance(self, vector):
# Use a função L2Distance do pgvector para obter a distância euclidiana ao quadrado
queryset = self.annotate(distance_squared=L2Distance('embedding', vector))
 
# Calcule a raiz quadrada para obter a distância euclidiana real
for item in queryset:
item.distance = math.sqrt(item.distance_squared)
 
return queryset
 
class Item(models.Model):
embedding = VectorField(dimensions=3)
Aqui está o arquivo markdown traduzido para o Português:
 
objects = ItemManager()
 

Agora você pode usar esse gerenciador personalizado em suas views ou shell do Django:

# Obter items ordenados pela sua distância Euclidiana para o vetor [3, 1, 2]
items = Item.objects.euclidean_distance([3, 1, 2]).order_by('distance')
 
# Imprimir os items e suas distâncias
for item in items:
print(f"ID do Item: {item.id}, Distância: {item.distance}")

Estendendo a Funcionalidade do SQLAlchemy

Da mesma forma, você pode estender a funcionalidade do SQLAlchemy adicionando uma classe de consulta personalizada.

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)
 
# Configuração do Banco de Dados
engine = create_engine('postgresql://localhost/mydatabase')
Base.metadata.create_all(engine)
 
Session = sessionmaker(bind=engine)
session = Session()
 
# Obter os items e suas distâncias Euclidianas para o vetor [3, 1, 2]
items_with_distance = session.query(Item).euclidean_distance([3, 1, 2]).all()
 
# Imprimir os items e suas distâncias
for item, distance in items_with_distance:
print(f"ID do Item: {item.id}, Distância: {distance}")

Neste exemplo, adicionei um campo id à classe Item como chave primária. A classe VectorQuery é usada para estender as capacidades de consulta, adicionando um método para calcular a distância Euclidiana. Por fim, o método de classe query é usado para definir essa classe de consulta personalizada para o modelo Item.

Você pode então usar isso em seu código SQLAlchemy:

# Obter os items e suas distâncias Euclidianas para o vetor [3, 1, 2]
items = session.query(Item).euclidean_distance([3, 1, 2]).all()
 
# Imprimir os items e suas distâncias
for item, distance in items:
print(f"ID do Item: {item.id}, Distância: {distance}")

Conclusão

Pgvector é uma mudança de jogo se você estiver usando bancos de dados PostgreSQL. Não é apenas um complemento; é como um turbocompressor para o seu banco de dados. Ele permite armazenar e pesquisar conjuntos grandes de dados de forma rápida e precisa. Isso é super útil para coisas como aprendizado de máquina, onde você precisa filtrar toneladas de dados rapidamente.

Além disso, o pgvector se encaixa perfeitamente no PostgreSQL, então você não precisa lidar com vários bancos de dados. Ele também é flexível, permitindo que você escolha como medir a "distância" entre os pontos de dados. Você até pode estender suas funcionalidades se estiver usando frameworks Python como o Django. Em resumo, se você gosta de dados e usa o PostgreSQL, não pode deixar de experimentar o pgvector.

FAQ

Qual é a utilidade do Pgvector?

Pgvector é uma extensão para bancos de dados PostgreSQL que se especializa em armazenar e pesquisar conjuntos grandes de vetores. É particularmente útil para aplicativos que exigem pesquisas de similaridade rápidas e precisas, como modelos de aprendizado de máquina, sistemas de recomendação e tarefas de processamento de linguagem natural.

Quais são as vantagens do Pgvector?

Pgvector oferece várias vantagens:

  1. Velocidade: Permite consultas rápidas, mesmo ao lidar com dados de alta dimensão.
  2. Eficiência: Comprime os dados sem perder sua integridade, economizando espaço de armazenamento.
  3. Flexibilidade: Suporta várias métricas de distância, como Euclidiana, Cosseno e Manhattan, permitindo que você escolha a melhor para suas necessidades.
  4. Integração perfeita: Integra-se diretamente ao PostgreSQL, assim você não precisa gerenciar vários bancos de dados.
  5. Escalabilidade: Funciona bem em várias configurações de hardware, garantindo uso otimizado de recursos.

O PostgreSQL é um banco de dados vetorial?

Não, o PostgreSQL não é intrinsecamente um banco de dados vetorial. No entanto, com a extensão Pgvector, você pode transformá-lo efetivamente em um poderoso banco de dados vetorial capaz de armazenar e realizar pesquisas de similaridade em dados de alta dimensão.

Como usar o Pgvector no PostgreSQL?

Para usar o Pgvector no PostgreSQL, você precisa:

  1. Instalar a extensão Pgvector executando CREATE EXTENSION pgvector; em seu banco de dados PostgreSQL.
  2. Criar uma tabela com uma coluna de vetor, por exemplo: CREATE TABLE my_vectors (id SERIAL PRIMARY KEY, vector_field VECTOR(128));.
  3. Inserir vetores na tabela: INSERT INTO my_vectors (vector_field) VALUES ('{1.1, 2.2, 3.3, ..., 128.128}');.
  4. Realizar pesquisas de similaridade usando consultas SQL, como: 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