In un articolo precedente, abbiamo utilizzato Ollama insieme a LangChain e SingleStore. LangChain forniva una soluzione efficiente e compatta per l’integrazione di Ollama con SingleStore. Tuttavia, cosa succederebbe se dovessimo rimuovere LangChain? In questo articolo, mostreremo un esempio di come usare Ollama con SingleStore senza dipendere da LangChain. Vedremo che, sebbene possiamo raggiungere gli stessi risultati descritti nell’articolo precedente, il numero di codice aumenta, costringendoci a gestire più del tubo che normalmente LangChain gestisce.
Il file notebook usato in questo articolo è disponibile su GitHub.
Introduzione
Dall’articolo precedente, seguiremo gli stessi passaggi per impostare il nostro ambiente di test come descritti in queste sezioni:
- Introduzione
- Utilizza una Macchina Virtuale o
venv
.
- Utilizza una Macchina Virtuale o
- Crea un account SingleStoreDB Cloud
- Usa Ollama Demo Group come Nome del Gruppo di Workspace e ollama-demo come Nome del Workspace. Prendi nota del password e del nome host. Permetti temporaneamente l’accesso da qualsiasi punto nel configurare il firewall sotto Ollama Demo Group > Firewall.
- Crea un Database
CREATE DATABASE IF NOT EXISTS ollama_demo;
- Installa Jupyter
pip install notebook
- Installa Ollama
curl -fsSL https://ollama.com/install.sh | sh
- Variabile d’ambiente
export SINGLESTOREDB_URL="admin:<password>@<host>:3306/ollama_demo"
Sostituisci<password>
e<host>
con i valori per il tuo ambiente.
- Lancia Jupyter
jupyter notebook
Riempi il Notebook
Prima, alcuni pacchetti:
!pip install ollama numpy pandas sqlalchemy-singlestoredb --quiet --no-warn-script-location
Poi, importeremo alcune librerie:
import ollama
import os
import numpy as np
import pandas as pd
from sqlalchemy import create_engine, text
Creeremo embeddings utilizzando all-minilm
(45 MB al momento della scrittura):
ollama.pull("all-minilm")
Esempio di output:
{'status': 'success'}
Per il nostro LLM utilizzeremo llama2
(3.8 GB al momento dell’iscrizione):
ollama.pull("llama2")
Esempio di output:
{'status': 'success'}
Successivamente, utilizzeremo il testo di esempio dal sito web di 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"])
Imposteremo le emozioni come all-minilm
e iterare attraverso ogni documento per costruire il contenuto per un DataFrame di Pandas. Inoltre, convertiremo le emozioni in un formato a 32 bit, poiché questo è il default di SingleStore per il tipo di dato VECTOR
. Infine, determinaremo le dimensioni dell’emozione per il primo documento nel DataFrame di Pandas.
Successivamente, creerà una connessione alla sua istanza di SingleStore:
connection_url = "singlestoredb://" + os.environ.get("SINGLESTOREDB_URL")
db_connection = create_engine(connection_url)
Ora creerà una tabella con la colonna vector
utilizzando le dimensioni precedentemente determinate:
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})
Ora scriverà il DataFrame di Pandas alla tabella:
df.to_sql(
"pandas_docs",
con = db_connection,
if_exists = "append",
index = False,
chunksize = 1000
)
Esempio di output:
6
Ora creerà un indice per corrispondere a quello creato nell’articolo precedente:
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)
Ora porterà una domanda, come segue:
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)
Converterà il prompt in emozioni, assicurarsi che le emozioni siano convertite in un formato a 32 bit, e poi eseguirà la query SQL che utilizza la notazione inverso <->
per la distanza euclidea.
Esempio di output:
Llamas are members of the camelid family meaning they're pretty closely related to vicuñas and camels
Successivamente, utilizzerà l’LLM, come segue:
output = ollama.generate(
model = "llama2",
prompt = f"Using this data: {data}. Respond to this prompt: {prompt}"
)
print(output["response"])
Esempio di output:
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.
Riepilogo
In questo articolo, abbiamo ripetuto i passaggi seguiti negli articoli precedenti e ottenuto risultati simili. Tuttavia, abbiamo dovuto scrivere una serie di istruzioni SQL e gestire diversi passaggi che LangChain avrebbe ricoperto per noi. Inoltre, potrebbe essere richiesto più tempo e costo per il mantenimento del baseline del codice a lungo termine rispetto alla soluzione LangChain.
L’utilizzo di LangChain invece di scrivere codice personalizzato per l’accesso al database fornisce diversi vantaggi, come l’efficienza, la scalabilità e la affidabilità.
LangChain offre una libreria di moduli predefiniti per l’interazione con il database, riducendo il tempo e il lavoro di sviluppo. I sviluppatori possono usare questi moduli per implementare velocemente varie operazioni sul database senza ricominciare da zero.
LangChain astratta molte delle complessità coinvolte nella gestione del database, permettendo ai sviluppatori di concentrarsi su attività ad alto livello invece di dettagli di implementazione a basso livello. Questo aumenta la produttività e la velocità di immissione del mercato per le applicazioni basate su database.
LangChain ha una comunità di sviluppatori ampia, attiva e in crescita, è disponibile su GitHub e fornisce documentazione estesa e esempi.
In sintesi, LangChain offre ai sviluppatori una piattaforma potente, efficiente e affidabile per la costruzione di applicazioni basate su database, permettendogli di focalizzarsi su problemi aziendali utilizzando astrazioni a alto livello invece di reinventare la ruota con codice personalizzato. Confrontando l’esempio di questo articolo con l’esempio utilizzato negli articoli precedenti, si può notare i benefici.
Source:
https://dzone.com/articles/ollama-plus-singlestore-minus-langchain