curso
Tutorial de pgvector: Integrar la búsqueda vectorial en PostgreSQL
La búsqueda vectorial se ha hecho cada vez más popular en los últimos años, gracias a todos los avances en el ecosistema de la IA Generativa y los Grandes Modelos Lingüísticos.
La búsqueda vectorial es un método de recuperación de información en el que los documentos y las consultas se representan como vectores en lugar de texto plano. Esta representación numérica se obtiene utilizando una gran red neuronal entrenada que puede convertir datos no estructurados, como texto, imágenes y vídeos, en vectores.
Las bases de datos relacionales tradicionales no están optimizadas para manejar grandes volúmenes de datos vectoriales. De ahí que en los últimos años hayan surgido muchas bases de datos vectoriales exclusivas, tanto de código abierto como propias. Sin embargo, puede que no sea ideal para todas las empresas tener una base de datos dedicada sólo a los vectores, separada de la base de datos principal.
Introduce pgvector, una potente extensión para PostgreSQL que aporta capacidades de búsqueda de similitudes vectoriales a una de las bases de datos relacionales más populares.
En este tutorial, exploraremos las características de pgvector y demostraremos cómo puede ayudarte en tu trabajo.
¿Qué es pgvector?
pgvector es una extensión de código abierto para PostgreSQL que añade soporte para operaciones vectoriales y búsquedas por similitud. Te permite almacenar, indexar y consultar datos vectoriales directamente en tu base de datos PostgreSQL.
Esta integración aporta la potencia de las operaciones vectoriales a tu infraestructura PostgreSQL existente, lo que la convierte en una opción excelente para aplicaciones que impliquen incrustaciones, sistemas de recomendación y búsquedas de similitud.
Entre las características de pgvector se incluyen:
- Almacenamiento eficiente de datos vectoriales densos
- Búsqueda rápida de similitudes utilizando varias métricas de distancia
- Integración con el planificador de consultas y los mecanismos de indexación existentes en PostgreSQL
- Soporte para búsquedas exactas y aproximadas del vecino más cercano
La importancia de las bases de datos vectoriales
Las bases de datos vectoriales son bases de datos especializadas diseñadas para almacenar y consultar datos vectoriales multidimensionales. Esta capacidad es relevante en las aplicaciones modernas de aprendizaje automático, incluidos los sistemas de recomendación, la recuperación de imágenes y los casos de uso del procesamiento del lenguaje natural.
Los vectores necesitan un nuevo tipo de base de datos-fuente de imágenes.
Las bases de datos relacionales tradicionales tienen dificultades con los datos de alta dimensión y para realizar búsquedas de similitud de forma eficiente. Sin embargo, las bases de datos vectoriales están optimizadas específicamente para estas tareas, permitiendo una recuperación rápida y precisa de los datos basada en la proximidad o semejanza de los vectores.
Este enfoque permite realizar búsquedas basadas en la relevancia semántica o contextual, proporcionando resultados más significativos en comparación con las búsquedas de coincidencia exacta de las bases de datos convencionales.
Por ejemplo, una base de datos vectorial puede
- Busca canciones que resuenen con una melodía concreta basándote en la melodía y el ritmo.
- Descubre artículos que se alinean con otro artículo específico en tema y perspectiva.
- Identifica gadgets que reflejen las características y opiniones de un dispositivo concreto.
Entonces, ¿cómo pueden convertirse en números los datos no estructurados, como texto o imágenes? La respuesta son las incrustaciones.
La incrustación es un proceso que transforma los datos no estructurados en vectores numéricos de tamaño fijo, capturando la semántica y las relaciones inherentes a los datos. Esto se consigue mediante grandes redes neuronales que aprenden a representar los datos en un espacio vectorial continuo, donde los elementos similares se colocan más cerca unos de otros.
¿Cómo funciona una base de datos vectorial? Fuente de la imagen.
Tutorial pgvector paso a paso
En este tutorial, veremos cómo configurar pgvector, utilizar sus funciones básicas y crear una aplicación sencilla integrándola con OpenAI.
Cubriremos la instalación, las operaciones básicas, la indexación y la integración con Python y LangChain.
1. Requisitos previos
Para seguir este tutorial, debes tener conocimientos básicos de SQL y PostgreSQL y estar familiarizado con la programación en Python.
Antes de empezar, asegúrate de que tienes lo siguiente:
- PostgreSQL 11 o posterior instalado en tu sistema
- Python 3.7 o posterior (para la sección de integración)
- Una clave API de OpenAI (para la aplicación de búsqueda semántica)
2. Cómo instalar pgvector
1. En primer lugar, asegúrate de que tienes instalados los archivos de desarrollo de PostgreSQL. En Ubuntu o Debian, puedes instalarlos con:
sudo apt-get install postgresql-server-dev-all
Si eres usuario de Windows, puedes descargar el instalador de PostgreSQL desde el sitio web oficial.
2. Clona el repositorio GitHub de pgvector:
git clone https://github.com/pgvector/pgvector.git
3. Construye e instala la extensión pgvector
:
cd pgvector
make
sudo make install
Si eres usuario de Windows, asegúrate de tener instalada la compatibilidad con C++ en Visual Studio Code. La documentación oficial de instalación proporciona un proceso paso a paso.
4. Conéctate a tu base de datos PostgreSQL:
Tienes varias opciones para conectarte e interactuar con la base de datos PostgreSQL: pgAdmin es una de las interfaces más utilizadas. Como alternativa, puedes utilizar pSQL (interfaz de línea de comandos PostgreSQL) o incluso una extensión de VS Code para PostgreSQL.
5. Tras conectarte a tu base de datos PostgreSQL, crea la extensión:
CREATE EXTENSION vector;
Interfaz pgAdmin
3. Uso básico de pgvector
Ahora que tenemos pgvector instalado, vamos a explorar su uso básico.
1. Para configurar nuestra primera base de datos vectorial en PostgreSQL utilizando la extensión pgvector, vamos a crear una tabla para almacenar nuestros datos vectoriales:
CREATE TABLE items (
id SERIAL PRIMARY KEY,
embedding vector(3)
);
Esto crea una tabla llamada items
con una columna id
y una columna embedding
de tipo vector(3)
, que almacenará vectores tridimensionales.
2. Ahora, vamos a insertar algunos datos en nuestra tabla:
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]'), ('[1,1,1]');
3. Ahora podemos realizar operaciones vectoriales. Por ejemplo, para encontrar el vecino más próximo del vector [2,3,4]
:
SELECT * FROM items ORDER BY embedding <-> '[2,3,4]' LIMIT 1;
Esta consulta utiliza el operador <->
, que calcula la distancia euclídea entre vectores.
4. También podemos utilizar otras métricas de distancia, como la distancia coseno:
SELECT * FROM items ORDER BY embedding <=> '[2,3,4]' LIMIT 1;
El operador <=>
calcula la distancia coseno entre vectores.
4. Indexar datos vectoriales con pgvector
La indexación en bases de datos vectoriales, incluido pgvector, es necesaria para mejorar el rendimiento de la búsqueda, sobre todo a medida que se amplía tu conjunto de datos.
No se puede exagerar la importancia de la indexación, ya que ofrece varias ventajas:
- En primer lugar, mejora significativamente la velocidad. Sin un índice, cada búsqueda de similitud requeriría una exploración completa de la tabla, comparando el vector de consulta con cada vector de la base de datos. Este proceso consume cada vez más tiempo a medida que crecen tus datos. Los índices crean una estructura que permite búsquedas mucho más rápidas.
- En segundo lugar, la indexación mejora la escalabilidad, permitiendo que tu base de datos gestione conjuntos de datos más grandes con eficacia. A medida que sigas añadiendo más vectores, las búsquedas correctamente indexadas mantendrán su rendimiento.
- Por último, la indexación contribuye a la eficiencia de los recursos al reducir la carga de CPU y E/S durante las búsquedas. Esto es especialmente importante para los sistemas con mucho trabajo o que funcionan con recursos limitados, ya que garantiza un funcionamiento sin problemas incluso en condiciones exigentes.
Hay dos tipos de índices disponibles para pgvector: ivfflat
y hnsw
. Ambos sirven para fines distintos:
- Índice IVFFlat (Archivo plano invertido):
- Adecuado para búsquedas exactas del vecino más próximo
- Divide el espacio vectorial en clusters, acelerando las búsquedas al identificar primero los clusters relevantes
- Buen equilibrio entre velocidad de búsqueda y precisión
- Índice HNSW (Pequeño Mundo Navegable Jerárquico):
- Diseñado para búsquedas aproximadas del vecino más próximo
- Crea una estructura gráfica para navegar rápidamente entre vectores
- Extremadamente rápido, pero ocasionalmente puede pasar por alto al vecino más cercano absoluto
Cuándo utilizar cada índice:
- Utiliza IVFFlat cuando necesites resultados exactos y puedas tolerar búsquedas algo más lentas
- Utiliza HNSW cuando necesites búsquedas rápidas y puedas aceptar ligeras imprecisiones
1. Vamos a crear un índice ivfflat
:
CREATE INDEX ON items USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
Esto crea un índice utilizando el algoritmo IVFFlat, que es adecuado para las búsquedas exactas del vecino más próximo.
2. Para las búsquedas aproximadas del vecino más próximo, podemos utilizar el índice hnsw
:
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WITH (m = 16, ef_construction = 64);
Tras crear un índice, nuestras consultas lo utilizarán automáticamente cuando proceda.
5. integración de pgvector con otras herramientas
Pgvector admite la integración con algunos frameworks, lo que facilita la interacción con nuestra base de datos vectorial. Repasemos dos útiles: Python y LangChain.
Utilizar pgvector con Python
pgvector puede integrarse fácilmente con Python utilizando la biblioteca psycopg2
. Vamos a configurar un entorno Python y a realizar algunas operaciones básicas.
1. Primero, instala las bibliotecas necesarias:
!pip install psycopg2-binary numpy
2. Ahora, vamos a crear un script en Python para interactuar con nuestra base de datos vectorial:
import psycopg2
import numpy as np
# Connect to the database
conn = psycopg2.connect("dbname=your_database user=your_username")
cur = conn.cursor()
# Insert a vector
embedding = np.array([1.5, 2.5, 3.5])
cur.execute("INSERT INTO items (embedding) VALUES (%s)", (embedding.tolist(),))
# Perform a similarity search
query_vector = np.array([2, 3, 4])
cur.execute("SELECT * FROM items ORDER BY embedding <-> %s LIMIT 1", (query_vector.tolist(),))
result = cur.fetchone()
print(f"Nearest neighbor: {result}")
conn.commit()
cur.close()
conn.close()
Este script demuestra cómo insertar un vector y realizar una búsqueda de similitud utilizando Python.
Utilizar pgvector con LangChain
pgvector también puede integrarse con LangChain, un popular marco para desarrollar aplicaciones con grandes modelos lingüísticos.
He aquí un ejemplo sencillo de cómo utilizar pgvector como almacén de vectores en LangChain:
from langchain_postgres.vectorstores import PGVector
from langchain.embeddings.openai import OpenAIEmbeddings
# Set up the connection string and embedding function
connection_string = "postgresql://user:pass@localhost:5432/db_name"
embedding_function = OpenAIEmbeddings()
# Create a PGVector instance
vector_store = PGVector.from_documents(
documents,
embedding_function,
connection_string=connection_string
)
# Perform a similarity search
query = "Your query here"
results = vector_store.similarity_search(query)
Este ejemplo supone que has configurado las incrustaciones de OpenAI y que tienes una lista de documentos para incrustar.
6. Construir una aplicación de ejemplo con pgvector y OpenAI
Ahora, ¡construyamos un sencillo motor de búsqueda semántica utilizando pgvector e incrustaciones OpenAI!
Esta aplicación permitirá a los usuarios buscar en una colección de documentos de texto mediante consultas de lenguaje natural.
import openai
import psycopg2
import numpy as np
# Set up OpenAI API (replace with your actual API key)
openai.api_key = "your_openai_api_key"
# Connect to the database
conn = psycopg2.connect("dbname=your_database user=your_username")
cur = conn.cursor()
# Create a table for our documents
cur.execute("""
CREATE TABLE IF NOT EXISTS documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536)
)
""")
# Function to get embeddings from OpenAI
def get_embedding(text):
response = openai.embeddings.create(input=text, model="text-embedding-ada-002")
return response['data'][0]['embedding']
# Function to add a document
def add_document(content):
embedding = get_embedding(content)
cur.execute("INSERT INTO documents (content, embedding) VALUES (%s, %s)", (content, embedding))
conn.commit()
# Function to search for similar documents
def search_documents(query, limit=5):
query_embedding = get_embedding(query)
cur.execute("""
SELECT content, embedding <-> %s AS distance
FROM documents
ORDER BY distance
LIMIT %s
""", (query_embedding, limit))
return cur.fetchall()
# Add some sample documents
sample_docs = [
"The quick brown fox jumps over the lazy dog.",
"Python is a high-level programming language.",
"Vector databases are essential for modern AI applications.",
"PostgreSQL is a powerful open-source relational database.",
]
for doc in sample_docs:
add_document(doc)
# Perform a search
search_query = "Tell me about programming languages"
results = search_documents(search_query)
print(f"Search results for: '{search_query}'")
for i, (content, distance) in enumerate(results, 1):
print(f"{i}. {content} (Distance: {distance:.4f})")
# Clean up
cur.close()
conn.close()
Esta sencilla aplicación demuestra cómo utilizar pgvector para crear un buscador semántico.
Incrusta documentos utilizando el modelo de incrustación de texto de OpenAI y los almacena en una base de datos PostgreSQL con pgvector. La función de búsqueda encuentra los documentos más parecidos a una consulta dada utilizando la similitud del coseno.
Análisis comparativo de pgvector
Comparemos pgvector con otras bases de datos vectoriales populares. Esta comparación te ayudará a comprender las diferencias en cuanto a características, opciones de despliegue, escalabilidad, integración y coste entre pgvector y otras soluciones disponibles en el mercado.
pgvector frente a Pinecone
Pinecone es una base de datos vectorial totalmente gestionada, diseñada para ofrecer una gran escalabilidad y facilidad de uso.
Función |
pgvector |
Piña |
Tipo de base de datos |
Extensión para PostgreSQL |
Base de datos vectorial totalmente gestionada |
Despliegue |
Autoalojado |
En la nube |
Escalabilidad |
Limitado por PostgreSQL |
Altamente escalable |
Integración |
Funciona con la pila PostgreSQL existente |
Requiere integración por separado |
Coste |
Gratuito, de código abierto |
Precios de pago por uso |
pgvector es una opción excelente para quienes desean aprovechar su infraestructura PostgreSQL existente sin costes adicionales. Al mismo tiempo, Pinecone proporciona una solución gestionada altamente escalable con precios de pago por uso para facilitar su uso.
pgvector contra Milvus
Milvus es una base de datos vectorial dedicada que ofrece funciones avanzadas y una gran escalabilidad.
Función |
pgvector |
Milvus |
Tipo de base de datos |
Extensión para PostgreSQL |
Base de datos vectorial dedicada |
Despliegue |
Autoalojado |
Autoalojado o en la nube |
Escalabilidad |
Limitado por PostgreSQL |
Altamente escalable |
Integración |
Funciona con la pila PostgreSQL existente |
Requiere integración por separado |
Conjunto de características |
Operaciones vectoriales básicas |
Funciones avanzadas como el esquema dinámico |
Mientras que pgvector proporciona operaciones vectoriales básicas dentro del conocido entorno PostgreSQL, Milvus ofrece una solución más rica en funciones y escalable, específica para manejar datos vectoriales a gran escala.
pgvector frente a Weaviate
Weaviate es una base de datos vectorial con almacenamiento de objetos integrado, que ofrece un modelado de datos flexible y escalabilidad.
Función |
pgvector |
Weaviate |
Tipo de base de datos |
Extensión para PostgreSQL |
Base de datos vectorial con almacenamiento de objetos |
Despliegue |
Autoalojado |
Autoalojado o en la nube |
Escalabilidad |
Limitado por PostgreSQL |
Diseñado para la escalabilidad |
Integración |
Funciona con la pila PostgreSQL existente |
Requiere integración por separado |
Modelo de datos |
Sólo vectores |
Objetos con vectores y propiedades |
La sencillez de pgvector y su integración con PostgreSQL lo convierten en una buena opción para los usuarios existentes que necesiten funcionalidades vectoriales básicas. En cambio, el modelo de datos más sofisticado y la escalabilidad de Weaviate son adecuados para aplicaciones complejas que requieren almacenamiento de objetos junto con vectores.
Conclusión
pgvector aporta potentes funciones de búsqueda de similitudes vectoriales a PostgreSQL, lo que lo convierte en una excelente opción para los desarrolladores que deseen añadir funciones potenciadas por la IA a sus aplicaciones existentes basadas en PostgreSQL.
En este tutorial, hemos explorado su instalación, uso básico, capacidades de indexación e integración con Python y LangChain.
Aunque pgvector puede no ofrecer la misma escalabilidad y características especializadas que las bases de datos vectoriales dedicadas como Pinecone o Milvus, su perfecta integración con PostgreSQL la convierte en una opción atractiva para muchos casos de uso.
Es especialmente adecuado para proyectos que ya utilizan PostgreSQL y necesitan añadir capacidades de búsqueda vectorial sin introducir un nuevo sistema de base de datos.
Te animamos a que pruebes pgvector en tus propios proyectos. Tanto si estás construyendo un sistema de recomendación, un motor de búsqueda semántica o cualquier otra aplicación que requiera búsquedas por similitud, pgvector puede ser una herramienta valiosa en tu conjunto de herramientas de ciencia de datos.
Para seguir aprendiendo, considera la posibilidad de explorar estos cursos gratuitos de DataCamp:
- Crear bases de datos PostgreSQL
- Desarrollar aplicaciones LLM con LangChain
- Introducción a las incrustaciones con la API OpenAI
Estos cursos te ayudarán a profundizar en el conocimiento de las bases de datos y las aplicaciones modernas del LLM.
Preguntas frecuentes
¿Tengo que cambiar toda mi base de datos para utilizar pgvector?
No, es un complemento de tu base de datos PostgreSQL existente.
¿Puedo utilizar pgvector con lenguajes distintos de Python?
Sí, con cualquier lenguaje que tenga un adaptador PostgreSQL.
¿Cómo puedo controlar el rendimiento de las consultas pgvector?
Puedes utilizar las herramientas integradas de PostgreSQL, como EXPLAIN
y ANALYZE
, para controlar el rendimiento de las consultas. Además, las extensiones de registro y supervisión, como pg_stat_statements
, pueden proporcionar información sobre el rendimiento de las consultas y ayudar a identificar los cuellos de botella.
¿Es posible combinar la búsqueda vectorial con las consultas SQL tradicionales?
Sí, pgvector te permite combinar la búsqueda vectorial con las consultas SQL tradicionales. Puedes incluir operaciones de similitud vectorial en tus consultas SQL junto con otras condiciones, lo que permite realizar búsquedas complejas que aprovechan tanto los datos vectoriales como los relacionales.
¿Puede utilizarse pgvector con otros marcos de aprendizaje automático además de OpenAI?
Sí, pgvector puede integrarse con varios marcos y bibliotecas de aprendizaje automático. Puedes generar incrustaciones utilizando modelos de marcos como TensorFlow, PyTorch o Hugging Face, y almacenar y consultar estas incrustaciones utilizando pgvector en PostgreSQL.
¿Cómo gestiono las actualizaciones de versión de pgvector?
Cuando actualices pgvector, asegúrate de que sigues las instrucciones oficiales de actualización proporcionadas en la documentación de pgvector. Haz una copia de seguridad de tus datos antes de realizar cualquier actualización. Tras la actualización, prueba a fondo tu aplicación para garantizar la compatibilidad y el rendimiento.
¿Puede pgvector manejar vectores de alta dimensión de forma eficiente?
Aunque pgvector puede manejar vectores de alta dimensión, el rendimiento puede verse limitado por las capacidades de PostgreSQL. Para datos de muy alta dimensión, considera optimizar tu configuración PostgreSQL o explorar bases de datos vectoriales dedicadas como Milvus o Pinecone.
¡Aprende más sobre aprendizaje automático e IA con estos cursos!
curso
Vector Databases for Embeddings with Pinecone
curso
Introduction to Embeddings with the OpenAI API
blog
Las 5 mejores bases de datos vectoriales
tutorial
Tutorial sobre máquinas de vectores de soporte con Scikit-learn
Avinash Navlani
15 min
tutorial
Uso de PostgreSQL en Python
tutorial
Visión GPT-4: Guía completa para principiantes
tutorial
Guía para principiantes sobre la ingeniería de avisos ChatGPT
tutorial
Cómo utilizar GROUP BY y HAVING en SQL
Eugenia Anello
6 min