Dans un article précédent, nous avons utilisé Ollama avec LangChain et SingleStore. LangChain offrait une solution efficace et compacte pour l’intégration d’Ollama avec SingleStore. Cependant, que se passe-t-il si nous devions supprimer LangChain ? Dans cet article, nous allons démontrer un exemple d’utilisation d’Ollama avec SingleStore sans dépendre de LangChain. Nous verrons que bien que nous puissions obtenir les mêmes résultats que ceux décrits dans l’article précédent, le nombre de lignes de code augmente, nous obligeant à gérer une plus grande partie des tâches que LangChain gère normalement.
Le fichier du carnet utilisé dans cet article est disponible sur GitHub.
Introduction
À partir de l’article précédent, nous suivrons les mêmes étapes pour configurer notre environnement de test tel que décrit dans ces sections :
- Introduction
- Utiliser une Machine Virtuelle ou
venv
.
- Utiliser une Machine Virtuelle ou
- Créer un compte SingleStoreDB Cloud
- Utiliser Ollama Demo Group comme le Nom du Groupe de Workspace et ollama-demo comme le Nom du Workspace. Prenez note du mot de passe et du nom hôte. Autorisez temporairement l’accès depuis n’importe où en configurant le pare-feu sous Ollama Demo Group > Firewall.
- Créer une base de données
CREATE DATABASE IF NOT EXISTS ollama_demo;
- Installer Jupyter
pip install notebook
- Installer Ollama
curl -fsSL https://ollama.com/install.sh | sh
- Variable d’environnement
export SINGLESTOREDB_URL="admin:<mot de passe>@<serveur>:3306/ollama_demo"
Remplacez<mot de passe>
et<serveur>
par les valeurs pour votre environnement.
- Lancer Jupyter
jupyter notebook
Remplir le notebook
Premièrement, quelques paquets :
!pip install ollama numpy pandas sqlalchemy-singlestoredb --quiet --no-warn-script-location
Ensuite, nous importerons quelques bibliothèques :
import ollama
import os
import numpy as np
import pandas as pd
from sqlalchemy import create_engine, text
Nous créerons des empreintes à l’aide de all-minilm
(45 MB à l’heure de l’écriture) :
ollama.pull("all-minilm")
Exemple de sortie :
{'status': 'success'}
Pour notre LLM, nous utiliserons llama2
(3,8 Go au moment de l’écriture) :
ollama.pull("llama2")
Exemple de sortie :
{'status': 'success'}
Ensuite, nous utiliserons le texte exemple du site 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"])
Nous réglerons les embeddings sur all-minilm
et parcourrons chacun des documents pour construire le contenu d’un DataFrame Pandas. De plus, nous convertirons les embeddings en format 32 bits, car c’est la valeur par défaut de SingleStore pour le type de données VECTOR
. Enfin, nous déterminerons le nombre de dimensions d’embedding pour le premier document du DataFrame Pandas.
Ensuite, nous créerons une connexion à notre instance SingleStore :
connection_url = "singlestoredb://" + os.environ.get("SINGLESTOREDB_URL")
db_connection = create_engine(connection_url)
Maintenant, nous créerons une table avec une colonne vector
en utilisant les dimensions que nous avons déterminées auparavant :
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})
Nous écriremons maintenant le DataFrame Pandas dans la table :
df.to_sql(
"pandas_docs",
con = db_connection,
if_exists = "append",
index = False,
chunksize = 1000
)
Exemple de sortie :
6
Nous créerons maintenant un index pour qu’il corresponde à celui que nous avons créé dans l’article précédent :
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)
Nous poserons maintenant une question comme suit :
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)
Nous convertirons l’invite en embeddings, nous verifierons que les embeddings sont convertis en format 32 bits et ensuite, nous exécuterons la requête SQL qui utilise la notation infixe <->
pour la distance euclidienne.
Exemple de sortie :
Llamas are members of the camelid family meaning they're pretty closely related to vicuñas and camels
Ensuite, nous utiliserons le LLM comme suit :
output = ollama.generate(
model = "llama2",
prompt = f"Using this data: {data}. Respond to this prompt: {prompt}"
)
print(output["response"])
Exemple de sortie :
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.
Résumé
Dans cet article, nous avons répliqué les étapes que nous avions suivies dans l’article précédent et avons obtenu des résultats similaires. Cependant, nous avons dû écrire une série de requêtes SQL et gérer plusieurs étapes que LangChain aurait handles pour nous. De plus, il peut y avoir plus de temps et de coûts impliqués dans le maintien de la base de code à long terme par rapport à la solution LangChain.
Utiliser LangChain au lieu d’écrire du code personnalisé pour l’accès à la base de données offre plusieurs avantages, tels que l’efficacité, la scalabilité et la fiabilité.
LangChain propose une bibliothèque de modules préconstruits pour l’interaction avec la base de données, réduisant ainsi le temps et les efforts de développement. Les développeurs peuvent utiliser ces modules pour implémenter rapidement diverses opérations de base de données sans avoir à commencer de zéro.
LangChain abstrait de nombreuses complexités impliquées dans la gestion de la base de données, permettant aux développeurs de se concentrer sur des tâches de haut niveau plutôt que sur des détails d’implémentation de bas niveau. Cela améliore la productivité et le temps-à-mercialisation des applications pilotées par des bases de données.
LangChain dispose d’une grande communauté de développeurs active et en croissance, est disponible sur GitHub et fournit une documentation et des exemples étendus.
En résumé, LangChain offre aux développeurs une plateforme puissante, efficace et fiable pour la construction d’applications pilotées par des bases de données, leur permettant de se concentrer sur les problèmes métier en utilisant des abstractions de plus haut niveau plutôt que de reinventer la roue avec du code personnalisé. En comparant l’exemple de cet article avec celui que nous avons utilisé dans l’article précédent, nous pouvons voir les bénéfices.
Source:
https://dzone.com/articles/ollama-plus-singlestore-minus-langchain