Pgvector: Comment transformer PostgreSQL en base de données vectorielle sans effort
Published on
Si vous utilisez PostgreSQL et que vous n'avez pas encore entendu parler de pgvector, vous passez à côté d'une extension révolutionnaire. Conçu pour booster votre base de données PostgreSQL, pgvector est l'outil ultime pour un stockage et une recherche de vecteurs efficaces. Ce n'est pas seulement une extension supplémentaire ; c'est une solution complète qui s'intègre parfaitement à PostgreSQL, améliorant ses capacités à des niveaux inédits.
Mais pourquoi devriez-vous vous en soucier ? Parce que dans le monde axé sur les données d'aujourd'hui, la capacité à stocker et interroger efficacement de grands ensembles de vecteurs est cruciale pour l'apprentissage automatique, les systèmes de recommandation et de nombreuses autres applications. pgvector non seulement rend cela possible, mais le fait avec une efficacité et une rapidité difficiles à égaler.
Pourquoi pgvector est essentiel pour les utilisateurs de PostgreSQL
Qu'est-ce que pgvector ?
pgvector est une extension de PostgreSQL spécialisée dans le stockage de vecteurs et l'exécution de recherches de similarité dans ces vecteurs. Contrairement aux types de données traditionnels de PostgreSQL, pgvector est optimisé pour les données de haute dimension, ce qui le rend idéal pour les modèles d'apprentissage automatique, la reconnaissance d'images et les tâches de traitement du langage naturel.
Principales fonctionnalités de pgvector :
-
Stockage vectoriel efficace : pgvector compresse les vecteurs de haute dimension sans perte d'intégrité des données. C'est un gros avantage car les données de haute dimension peuvent être un cauchemar en termes de stockage.
-
Plusieurs mesures de distance : Que vous travailliez avec des distances euclidiennes, cosinus ou de Manhattan, pgvector vous fournit une couverture complète. Il prend en charge une variété de mesures de distance, vous offrant la flexibilité de choisir la meilleure pour votre cas d'utilisation spécifique.
-
Intégration transparente : L'un des grands avantages de pgvector est sa parfaite intégration avec PostgreSQL. Vous n'avez pas à jongler entre différentes bases de données ; pgvector fonctionne comme une extension native, vous permettant d'effectuer des requêtes complexes directement dans PostgreSQL.
Passons aux chiffres. Avec pgvector, vous pouvez exécuter 1 million d'embeddings OpenAI à environ 1800 requêtes par seconde (QPS) avec un taux de précision de 91%. Si vous visez une plus grande précision, vous pouvez atteindre 670 QPS avec un taux de précision stupéfiant de 98%. Ces mesures ne sont pas seulement impressionnantes, elles sont révolutionnaires.
Les performances de pgvector ne s'arrêtent pas seulement à un haut QPS et à une grande précision. Il est également incroyablement évolutif. Que vous l'exécutiez sur un processeur ARM 8 cœurs avec 32 Go de RAM ou sur un processeur ARM 64 cœurs avec 256 Go, pgvector s'adapte parfaitement, vous garantissant de tirer le meilleur parti de vos ressources matérielles.
À quelle vitesse fonctionne réellement pgvector ? (Benchmarks de pgvector)
Analyse de la vitesse et de la précision de pgvector
Si vous recherchez la rapidité et la précision dans les recherches de vecteurs, pgvector a tout prévu. La dernière version, pgvector 0.4.0, a été soumise à des tests rigoureux pour mesurer ses performances. Examinons les détails :
Méthodologie des benchmarks
- Lanceur de tests : Un script Python a été utilisé pour le chargement des données, la création des index et l'exécution des requêtes.
- Durée d'exécution : Chaque test s'est déroulé pendant 30 à 40 minutes, couvrant différents niveaux de charge de travail pour mesurer les performances.
- Préchauffage de la RAM : Avant chaque test, de 10 000 à 50 000 requêtes de "préchauffage" ont été exécutées pour optimiser l'utilisation de la RAM.
Matériel utilisé pour les tests
- 2XL : ARM 8 cœurs, 32 Go de RAM
- 4XL : ARM 16 cœurs, 64 Go de RAM
- 8XL : ARM 32 cœurs, 128 Go de RAM
- 12XL : ARM 48 cœurs, 192 Go de RAM
- 16XL : ARM 64 cœurs, 256 Go de RAM
Jeu de données
Les tests ont utilisé le jeu de données dbpedia-entities-openai-1M (opens in a new tab), qui comprend 1 million d'embeddings avec 1536 dimensions. Ce jeu de données est créé à l'aide d'OpenAI et est basé sur des articles Wikipédia.
Résultats des performances
- Avec une valeur de probes réglée sur 10 : pgvector a obtenu une précision@10 de 0.91 et un QPS (requêtes par seconde) de 380.
- Avec une valeur de probes réglée sur 40 : pgvector est non seulement devenu plus rapide, mais a également maintenu presque la même précision que Qdrant, avec une précision@10 de 0.98 et un QPS de 140.
Évolution de la base de données
Les performances de pgvector évoluent de manière prévisible en fonction de la taille de la base de données. Par exemple, une instance 4XL a obtenu une précision@10 de 0.98 et un QPS de 270 avec des probes réglés sur 40. Une instance 8XL a obtenu une précision@10 de 0.98 et un QPS de 470, dépassant les résultats de Qdrant.
Résultats des benchmarks de pgvector
Sur un serveur ARM 64 cœurs, 256 Go de RAM, pgvector atteint environ 1800 QPS avec une précision de 0.91. Ceci est pour la version 0.4.0, et il convient de noter que les versions plus récentes devraient montrer des performances encore meilleures.
Pourquoi pgvector surpasse les bases de données vectorielles commerciales
Après avoir examiné les impressionnants benchmarks de pgvector, vous vous demandez peut-être comment il se compare à d'autres solutions de bases de données vectorielles commerciales comme Milvus. Eh bien, voyons cela en détail :
Facilité d'intégration
- Milvus : Fonctionne en tant que service distinct, ce qui ajoute de la complexité à votre pile technologique.
- pgvector : S'intègre parfaitement à PostgreSQL, simplifiant votre pile technologique.
Synchronisation des données
- Milvus : Ne prend pas en charge l'intégration native, ce qui entraîne des problèmes de synchronisation des données.
- pgvector : Offre une intégration native, éliminant les problèmes de synchronisation.
Métriques de performance
- Milvus : Peine à rivaliser avec les performances de pgvector.
- pgvector : Gère 1 million d'embeddings OpenAI à 1800 QPS avec un taux de précision de 91%.
Métrique | Milvus | pgvector |
---|---|---|
Complexité d'intégration | Haute | Basse |
Synchronisation des données | Problématique | Transparente |
Vitesse de requête (QPS) | Inférieure | 1800 |
Précision | Inférieure | 91% |
En résumé, si vous recherchez une solution optimisée, efficace et performante pour le stockage et la recherche vectorielle, pgvector est le choix évident.
Conseils pour optimiser les performances de pgvector
- Ajustez votre configuration Postgres: Assurez-vous qu'elle est adaptée à votre RAM et au nombre de cœurs de votre CPU.
- Pré-chauffez votre base de données: Utilisez la technique d'amorçage décrite précédemment.
- Choisissez la bonne fonction de distance : Si vos vecteurs sont normalisés, préférez le produit interne aux distances L2 ou cosinus.
- Ajustez la constante des listes: L'augmentation de cette valeur peut accélérer vos requêtes. Par exemple, lors des tests avec les embeddings OpenAI, une constante de listes de 2000 a été utilisée au lieu des 1000 suggérés.
En examinant ces mesures détaillées et ces conseils, il est clair que pgvector offre des performances robustes pour le stockage vectoriel et la recherche de similarité, en en faisant un choix de premier ordre pour les utilisateurs de PostgreSQL.
Que pouvez-vous faire avec pgvector ?
Comment utiliser pgvector en tant que base de données vectorielle open-source
Pgvector n'est pas seulement une extension ; c'est un outil transformateur qui transforme votre base de données PostgreSQL en une base de données vectorielle puissante. Cela est particulièrement utile pour ceux qui souhaitent effectuer des opérations complexes sur des données de haute dimension sans avoir à passer à une base de données spécialisée. Dans cette section, nous explorerons comment configurer et utiliser pgvector en tant que base de données vectorielle open-source.
Installation et configuration :
- Clonez le référentiel: Commencez par cloner le référentiel pgvector GitHub sur votre machine locale.
git clone https://github.com/votre/référentiel/pgvector.git
- Compilez et installez: Accédez au répertoire et compilez l'extension.
cd pgvector
make
make install
- Configuration de la base de données: Connectez-vous à votre base de données PostgreSQL et créez l'extension pgvector.
CREATE EXTENSION pgvector;
- Création de table: Créez une table avec une colonne vectorielle pour stocker vos données de grande dimension.
CREATE TABLE my_vectors (id SERIAL PRIMARY KEY, vector_field VECTOR(128));
Opérations de base :
- Insertion de vecteurs: Insérez des données dans le champ vectoriel.
INSERT INTO my_vectors (vector_field) VALUES ('{1.1, 2.2, 3.3, ..., 128.128}');
- Recherche vectorielle: Effectuez une recherche de similarité en utilisant le champ vectoriel.
SELECT * FROM my_vectors ORDER BY vector_field <-> '{3.3, 2.2, 1.1, ..., 128.128}' LIMIT 10;
- Indexation: Créez un index pour accélérer vos recherches de similarité.
CREATE INDEX idx_vector_field ON my_vectors USING ivfflat(vector_field);
Fonctionnalités avancées :
- Paramètres d'optimisation: Vous pouvez ajuster les paramètres de votre index pour équilibrer la vitesse et la précision.
SET pgvector.index_type = 'hnsw';
SET pgvector.ef_search = 64;
-
Opérations par lots: Pgvector prend en charge les opérations par lots pour l'insertion et la mise à jour des vecteurs, ce qui peut être particulièrement utile pour les applications d'apprentissage automatique.
-
Surveillance et observabilité: Utilisez les outils de surveillance intégrés à PostgreSQL pour suivre les performances de vos opérations vectorielles.
Capacités de recherche k-NN de pgvector
Qu'est-ce que la recherche k-NN ?
La recherche k-NN (k plus proches voisins) est un algorithme utilisé pour trouver les "k" points les plus proches d'un point donné dans un espace multidimensionnel. Elle est largement utilisée en apprentissage automatique pour la classification et le regroupement.
Comment pgvector permet la recherche k-NN :
- Type de données: pgvector introduit un nouveau type de données appelé
vector
, qui peut stocker des données multidimensionnelles. - Opérateurs: Il fournit des opérateurs tels que
<->
pour la distance euclidienne et<=>
pour la distance cosinus afin de calculer la similarité entre les vecteurs. - Indexation: Vous pouvez créer des index sur les colonnes vectorielles pour accélérer les requêtes k-NN.
Voici une fonction SQL qui effectue une recherche k-NN en utilisant 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;
$$;
Stockez les embeddings OpenAI avec pgvector
Pourquoi stocker les embeddings OpenAI ? Les embeddings OpenAI sont des vecteurs de grande dimension qui capturent le sens sémantique d'un texte. Ils sont utiles pour des tâches telles que la similarité de texte, le regroupement et la classification.
Comment stocker les embeddings OpenAI avec pgvector
- Créez une table: Créez une table PostgreSQL avec une colonne de type
vector
.
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(1536)
);
- Insérez des données: Insérez les embeddings OpenAI dans la colonne
embedding
.
INSERT INTO documents(content, embedding) VALUES ('some text', '{your 1536-dim vector}');
- Requête: Utilisez les opérateurs de pgvector pour interroger les embeddings.
SELECT * FROM documents WHERE embedding <=> '{query vector}' < 0.5;
PGVector avec Langchain : Recherche de texte avancée
Langchain et PGVector peuvent être combinés pour créer un système puissant de recherche et de récupération de texte. Voici un guide sur l'intégration de PGVector avec Langchain pour effectuer des opérations de recherche de texte avancées.
Prérequis
- Assurez-vous d'avoir installé tous les packages nécessaires et configuré vos variables d'environnement comme indiqué dans la section initiale de votre fichier notebook.
Étape 1. Initialiser les composants de Langchain
Tout d'abord, initialisez les composants de Langchain tels que OpenAIEmbeddings
, TextLoader
et CharacterTextSplitter
.
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.document_loaders import TextLoader
loader = TextLoader("votre_fichier_texte.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) docs = text_splitter.split_documents(documents) embeddings = OpenAIEmbeddings()
**Étape 2. Initialiser PGVector**
Ensuite, initialisez PGVector avec la chaîne de connexion à votre base de données Postgres.
```python
from langchain.vectorstores.pgvector import PGVector
CONNECTION_STRING = "votre_chaine_de_connexion_ici"
COLLECTION_NAME = "votre_nom_de_collection_ici"
db = PGVector.from_documents(
embedding=embeddings,
documents=docs,
collection_name=COLLECTION_NAME,
connection_string=CONNECTION_STRING,
)
Étape 3. Effectuer une recherche de similarité
Vous pouvez maintenant effectuer une recherche de similarité en utilisant la méthode similarity_search_with_score
de PGVector.
query = "Votre requête de recherche ici"
docs_with_score = db.similarity_search_with_score(query)
for doc, score in docs_with_score:
print("Score: ", score)
print(doc.page_content)
Étape 4. Recherche de relevant marginal maximal Pour une recherche plus avancée, vous pouvez utiliser le Relevé marginal maximal (MMR) pour optimiser à la fois la similarité avec la requête et la diversité parmi les documents sélectionnés.
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)
Étape 5. Travailler avec un VectorStore existant Si vous avez déjà un magasin de vecteurs existant, vous pouvez l'initialiser directement et y ajouter des documents.
store = PGVector(
collection_name=COLLECTION_NAME,
connection_string=CONNECTION_STRING,
embedding_function=embeddings,
)
store.add_documents([Document(page_content="nouveau_contenu_ici")])
Étape 6. Remplacement d'un VectorStore existant Si vous devez mettre à jour une collection existante, vous pouvez la remplacer.
db = PGVector.from_documents(
documents=docs,
embedding=embeddings,
collection_name=COLLECTION_NAME,
connection_string=CONNECTION_STRING,
pre_delete_collection=True,
)
Étape 7. Utilisation de VectorStore comme récupérateur Enfin, vous pouvez utiliser le magasin de vecteurs comme récupérateur pour des opérations plus avancées.
retriever = store.as_retriever()
print(retriever)
Construction d'une recherche alimentée par l'IA avec Amazon SageMaker, Amazon RDS pour PostgreSQL et pgvector
Dans cette section, nous montrons comment construire une solution de recherche de similarité de catalogue de produits en utilisant Amazon SageMaker et Amazon RDS pour PostgreSQL avec l'extension pgvector. Nous utiliserons un modèle Hugging Face pré-entraîné pour générer des embeddings de documents et les stocker dans une base de données RDS pour PostgreSQL. Ensuite, nous utiliserons les capacités de recherche de similarité de pgvector pour trouver les articles du catalogue de produits qui correspondent le mieux à la requête de recherche d'un client.
Étapes pour mettre en place la solution :
-
Configurer une instance de bloc-notes SageMaker : Créez une instance de bloc-notes SageMaker pour exécuter le code Python dans un bloc-notes Jupyter.
-
Préparation des données : Traduisez les descriptions des articles de l'allemand à l'anglais en utilisant Amazon Translate.
-
Hébergement du modèle : Déployez un modèle Hugging Face pré-entraîné dans SageMaker pour générer des embeddings vectoriels de dimension 384 pour le catalogue de produits.
-
Stockage des données : Connectez-vous à RDS pour PostgreSQL et créez une table pour stocker le texte brut et les embeddings textuels.
-
Inférence en temps réel : Utilisez SageMaker pour encoder le texte de la requête en embeddings.
-
Recherche de similarité : Effectuez une recherche de similarité en utilisant pgvector dans la base de données RDS pour PostgreSQL.
Prérequis :
- Un compte AWS avec les autorisations IAM appropriées.
- Connaissance des services AWS tels que SageMaker, RDS et CloudFormation.
Déploiement : Utilisez une pile CloudFormation AWS pour déployer la solution, qui créera toutes les ressources nécessaires, y compris les composants de mise en réseau, une instance de bloc-notes SageMaker et une instance RDS pour PostgreSQL.
Voici quelques extraits de code clés pour mettre en œuvre la solution :
- Ingestion des données : Utilisez Amazon Translate pour traduire les descriptions des articles de l'allemand à l'anglais.
import boto3
translate = boto3.client(service_name='translate', use_ssl=True)
result = translate.translate_text(Text=str(j), SourceLanguageCode="de", TargetLanguageCode="en")
- Hébergement du modèle : Déployez un modèle Hugging Face pré-entraîné dans SageMaker.
from sagemaker.huggingface.model import HuggingFaceModel
predictor = HuggingFaceModel(env=hub, role=role).deploy(initial_instance_count=1, instance_type="ml.m5.xlarge")
- Stockage des données : Créez une table dans RDS pour PostgreSQL pour stocker les embeddings.
CREATE TABLE IF NOT EXISTS products(
id bigserial primary key,
description text,
descriptions_embeddings vector(384)
);
- Recherche de similarité : Effectuez une recherche de similarité en utilisant pgvector.
SELECT id, url, description, descriptions_embeddings
FROM products
ORDER BY descriptions_embeddings <-> ARRAY[...];
Utilisation de PgVector en Python
Certainement, vous pouvez étendre les fonctionnalités de pgvector
en Python en ajoutant des méthodes personnalisées ou en l'intégrant à d'autres bibliothèques Python. Voici un exemple de la façon dont vous pourriez étendre pgvector
pour inclure une méthode permettant de calculer la distance euclidienne entre deux vecteurs dans Django.
Étendre les fonctionnalités de Django
Tout d'abord, créons un gestionnaire personnalisé pour le modèle Item
qui inclut une méthode permettant de calculer la distance euclidienne.
from django.db import models
from pgvector.django import VectorField, L2Distance
import math
class ItemManager(models.Manager):
def euclidean_distance(self, vector):
# Utilisez la fonction L2Distance de pgvector pour obtenir la distance euclidienne au carré
queryset = self.annotate(distance_squared=L2Distance('embedding', vector))
# Prenez la racine carrée pour obtenir la distance euclidienne réelle
for item in queryset:
item.distance = math.sqrt(item.distance_squared)
return queryset
class Item(models.Model):
embedding = VectorField(dimensions=3)
# Création d'un objet ItemManager
objects = ItemManager()
Maintenant, vous pouvez utiliser cet objet manager personnalisé dans vos vues ou dans le shell Django :
```python
# Obtenir les items triés par leur distance euclidienne au vecteur [3, 1, 2]
items = Item.objects.euclidean_distance([3, 1, 2]).order_by('distance')
# Afficher les items et leurs distances
for item in items:
print(f"ID de l'objet : {item.id}, Distance : {item.distance}")
Étendre la fonctionnalité de SQLAlchemy
De la même manière, vous pouvez étendre la fonctionnalité de SQLAlchemy en ajoutant une classe de requête personnalisée.
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)
# Configuration de la base de données
engine = create_engine('postgresql://localhost/mydatabase')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# Obtenir les items et leur distance euclidienne au vecteur [3, 1, 2]
items_with_distance = session.query(Item).euclidean_distance([3, 1, 2]).all()
# Afficher les items et leurs distances
for item, distance in items_with_distance:
print(f"ID de l'objet : {item.id}, Distance : {distance}")
Dans cet exemple, j'ai ajouté un champ id à la classe Item en tant que clé primaire. La classe VectorQuery est utilisée pour étendre les capacités de requête, en ajoutant une méthode pour calculer la distance euclidienne. Enfin, la méthode de classe query est utilisée pour définir cette classe de requête personnalisée pour le modèle Item.
Vous pouvez ensuite utiliser cela dans votre code SQLAlchemy :
# Obtenir les items et leur distance euclidienne au vecteur [3, 1, 2]
items = session.query(Item).euclidean_distance([3, 1, 2]).all()
# Afficher les items et leurs distances
for item, distance in items:
print(f"ID de l'objet : {item.id}, Distance : {distance}")
Conclusion
Pgvector est une véritable révolution si vous utilisez des bases de données PostgreSQL. Ce n'est pas simplement une extension, c'est comme un turbocompresseur pour votre base de données. Cela vous permet de stocker et de rechercher rapidement et précisément de grandes quantités de données. C'est très utile pour des tâches telles que l'apprentissage automatique, où vous devez trier rapidement une énorme quantité de données.
De plus, pgvector s'intègre parfaitement à PostgreSQL, vous n'avez donc pas à jongler avec plusieurs bases de données. Il est également flexible, vous permettant de choisir comment mesurer la "distance" entre les points de données. Vous pouvez même étendre ses fonctionnalités si vous utilisez des frameworks Python tels que Django. En résumé, si vous travaillez avec des données et utilisez PostgreSQL, ne passez pas à côté de pgvector.
FAQ
Quelle est l'utilité de Pgvector ?
Pgvector est une extension pour les bases de données PostgreSQL qui se spécialise dans le stockage et la recherche dans de grands ensembles de vecteurs. Elle est particulièrement utile pour les applications qui nécessitent des recherches de similarité rapides et précises, telles que les modèles d'apprentissage automatique, les systèmes de recommandation et les tâches de traitement du langage naturel.
Quels sont les avantages de Pgvector ?
Pgvector offre plusieurs avantages :
- Rapidité : Elle permet des requêtes rapides, même avec des données de haute dimension.
- Efficacité : Elle compresse les données sans en perdre l'intégrité, ce qui permet d'économiser de l'espace de stockage.
- Flexibilité : Elle prend en charge plusieurs métriques de distance comme l'Euclidienne, la Cosine et la Manhattan, vous permettant de choisir la meilleure pour vos besoins.
- Intégration transparente : Elle s'intègre directement à PostgreSQL, vous n'avez donc pas à gérer plusieurs bases de données.
- Évolutivité : Elle fonctionne bien sur différentes configurations matérielles, garantissant une utilisation optimale des ressources.
PostgreSQL est-il une base de données vectorielle ?
Non, PostgreSQL n'est pas intrinsèquement une base de données vectorielle. Cependant, avec l'extension Pgvector, vous pouvez efficacement transformer PostgreSQL en une puissante base de données vectorielle capable de stocker et d'effectuer des recherches de similarité sur des données de haute dimension.
Comment utiliser Pgvector dans PostgreSQL ?
Pour utiliser Pgvector dans PostgreSQL, vous devez :
- Installer l'extension Pgvector en exécutant
CREATE EXTENSION pgvector;
dans votre base de données PostgreSQL. - Créer une table avec une colonne vectorielle, par exemple :
CREATE TABLE my_vectors (id SERIAL PRIMARY KEY, vector_field VECTOR(128));
. - Insérer des vecteurs dans la table :
INSERT INTO my_vectors (vector_field) VALUES ('{1.1, 2.2, 3.3, ..., 128.128}');
. - Effectuer des recherches de similarité en utilisant des requêtes SQL, par exemple :
SELECT * FROM my_vectors ORDER BY vector_field <-> '{3.3, 2.2, 1.1, ..., 128.128}' LIMIT 10;
.