En un artículo previo, utilizamos Ollama con LangChain y SingleStore. LangChain proporcionó una solución eficiente y compacta para integrar Ollama con SingleStore. Sin embargo, ¿qué pasaría si elimináramos LangChain? En este artículo, demostraremos un ejemplo de uso de Ollama con SingleStore sin dependencia de LangChain. Veremos que aunque podemos obtener los mismos resultados descritos en el artículo previo, el número de código aumenta, requiriéndonos que manejemos más de la instalación que normalmente maneja LangChain.
El archivo de notebook utilizado en este artículo está disponible en GitHub.
Introducción
Desde el artículo previo, seguiremos los mismos pasos para configurar nuestro entorno de prueba como se describe en estas secciones:
- Introducción
- Utilice una Máquina Virtual o
venv
.
- Utilice una Máquina Virtual o
- Cree una cuenta de SingleStoreDB Cloud
- Utilice Ollama Demo Group como el Nombre del Grupo de Espacio de Trabajo y ollama-demo como el Nombre del Espacio de Trabajo. Note la contraseña y el nombre del host. Permite temporalmente el acceso desde cualquier lugar configurando la cortafuegos bajo Ollama Demo Group > Firewall.
- Crear una Base de Datos
CREATE DATABASE IF NOT EXISTS ollama_demo;
- Instalar Jupyter
pip install notebook
- Instalar Ollama
curl -fsSL https://ollama.com/install.sh | sh
- Variable de Entorno
export SINGLESTOREDB_URL="admin:<password>@<host>:3306/ollama_demo"
Reemplaza<password>
y<host>
con los valores para tu entorno.
- Iniciar Jupyter
jupyter notebook
Completar la Nota de Código
Primero, algunas paquetes:
!pip install ollama numpy pandas sqlalchemy-singlestoredb --quiet --no-warn-script-location
Después, importaremos algunas bibliotecas:
import ollama
import os
import numpy as np
import pandas as pd
from sqlalchemy import create_engine, text
Creamos embebiduras utilizando all-minilm
(45 MB en el momento de la escritura):
ollama.pull("all-minilm")
Ejemplo de salida:
{'status': 'success'}
Para nuestro LLM utilizaremos llama2
(3.8 GB en el momento de la escritura):
ollama.pull("llama2")
Ejemplo de salida:
{'status': 'success'}
A continuación, utilizaremos el texto de ejemplo del sitio web de Ollama :
documents = [
"Llamas are members of the camelid family meaning they're pretty closely related to vicuñas and camels",
"Llamas were first domesticated and used as pack animals 4,000 to 5,000 years ago in the Peruvian highlands",
"Llamas can grow as much as 6 feet tall though the average llama between 5 feet 6 inches and 5 feet 9 inches tall",
"Llamas weigh between 280 and 450 pounds and can carry 25 to 30 percent of their body weight",
"Llamas are vegetarians and have very efficient digestive systems",
"Llamas live to be about 20 years old, though some only live for 15 years and others live to be 30 years old"
]
df_data = []
for doc in documents:
response = ollama.embeddings(
model = "all-minilm",
prompt = doc
)
embedding = response["embedding"]
embedding_array = np.array(embedding).astype(np.float32)
df_data.append({"content": doc, "vector": embedding_array})
df = pd.DataFrame(df_data)
dimensions = len(df.at[0, "vector"])
Configuraremos las embeddings a all-minilm
y recorremos cada documento para construir el contenido para un DataFrame de Pandas. Además, convertiremos las embeddings a un formato de 32 bits, ya que este es el predeterminado de SingleStore para el tipo de dato VECTOR
. Por último, determinaremos el número de dimensiones de embedding para el primer documento en el DataFrame de Pandas.
A continuación, crearemos una conexión a nuestra instancia de SingleStore:
connection_url = "singlestoredb://" + os.environ.get("SINGLESTOREDB_URL")
db_connection = create_engine(connection_url)
Ahora crearemos una tabla con la columna vector
utilizando las dimensiones que determinamos previamente:
query = text("""
CREATE TABLE IF NOT EXISTS pandas_docs (
id BIGINT AUTO_INCREMENT NOT NULL,
content LONGTEXT,
vector VECTOR(:dimensions) NOT NULL,
PRIMARY KEY(id)
);
""")
with db_connection.connect() as conn:
conn.execute(query, {"dimensions": dimensions})
Ahora escribiremos el DataFrame de Pandas en la tabla:
df.to_sql(
"pandas_docs",
con = db_connection,
if_exists = "append",
index = False,
chunksize = 1000
)
Ejemplo de salida:
6
Ahora crearemos un índice para coincidir con el que creamos en el artículo anterior:
query = text("""
ALTER TABLE pandas_docs ADD VECTOR INDEX (vector)
INDEX_OPTIONS '{
"metric_type": "EUCLIDEAN_DISTANCE"
}';
""")
with db_connection.connect() as conn:
conn.execute(query)
Ahora plantearemos una pregunta, como sigue:
prompt = "What animals are llamas related to?"
response = ollama.embeddings(
prompt = prompt,
model = "all-minilm"
)
embedding = response["embedding"]
embedding_array = np.array(embedding).astype(np.float32)
query = text("""
SELECT content
FROM pandas_docs
ORDER BY vector <-> :embedding_array ASC
LIMIT 1;
""")
with db_connection.connect() as conn:
results = conn.execute(query, {"embedding_array": embedding_array})
row = results.fetchone()
data = row[0]
print(data)
Convertiremos la pregunta en embeddings, asegurándonos que las embeddings se conviertan en un formato de 32 bits y luego ejecutaremos la consulta SQL que utiliza la notación infija <->
para la Distancia Euclidiana.
Ejemplo de salida:
Llamas are members of the camelid family meaning they're pretty closely related to vicuñas and camels
A continuación, utilizaremos el LLM, como sigue:
output = ollama.generate(
model = "llama2",
prompt = f"Using this data: {data}. Respond to this prompt: {prompt}"
)
print(output["response"])
Ejemplo de salida:
Llamas are members of the camelid family, which means they are closely related to other animals such as:
1. Vicuñas: Vicuñas are small, wild camelids that are native to South America. They are known for their soft, woolly coats and are considered an endangered species due to habitat loss and poaching.
2. Camels: Camels are large, even-toed ungulates that are native to Africa and the Middle East. They are known for their distinctive humps on their backs, which store water and food for long periods of time.
Both llamas and vicuñas are classified as members of the family Camelidae, while camels are classified as belonging to the family Dromedaryae. Despite their differences in size and habitat, all three species share many similarities in terms of their physical characteristics and behavior.
Resumen
En este artículo, hemos replicado los pasos que seguimos en el artículo anterior y obtenido resultados similares. Sin embargo, tuvimos que escribir una serie de sentencias SQL y manejar varios pasos que LangChain hubiera manejado por nosotros. Además, puede haber más tiempo y costo involucrados en el mantenimiento de la base de código a largo plazo en comparación con la solución LangChain.
Usar LangChain en lugar de escribir código personalizado para el acceso a bases de datos ofrece varias ventajas, como eficiencia, escalabilidad y confiabilidad.
LangChain ofrece una biblioteca de módulos preconstruidos para la interacción con bases de datos, reduciendo el tiempo y el esfuerzo de desarrollo. Los desarrolladores pueden usar estos módulos para implementar rápidamente varias operaciones de base de datos sin empezar desde cero.
LangChain abstrae muchas de las complejidades involucradas en la gestión de bases de datos, permitiendo a los desarrolladores enfocarse en tareas de alto nivel en lugar de en detalles de implementación de bajo nivel. Esto mejora la productividad y la velocidad de lanzamiento de aplicaciones basadas en bases de datos.
LangChain tiene una gran y activa comunidad de desarrolladores que se está expandiendo, está disponible en GitHub y proporciona documentación extensa y ejemplos.
En resumen, LangChain ofrece a los desarrolladores una poderosa, eficiente y confiable plataforma para construir aplicaciones basadas en bases de datos, lo que les permite enfocarse en problemas de negocio utilizando abstracciones de alto nivel en lugar de reinventar la rueda con código personalizado. Comparando el ejemplo de este artículo con el ejemplo que usamos en el artículo anterior, pueden verse los beneficios.
Source:
https://dzone.com/articles/ollama-plus-singlestore-minus-langchain