Riordinamento con modelli di embedding
Un codice Python per il rirango di RAG
Reranking è un secondo passo nella Generazione Assistita dal Recupero (RAG) sistemi, proprio tra il Recupero e la Generazione.
Quello sopra è come Flux-1 dev immagina Cubi elettrici nello spazio digitale
.
Recupero con reranking
Se archiviamo i documenti sotto forma di embedding nel database vettoriale fin dall’inizio - il recupero ci fornirà immediatamente l’elenco dei documenti simili.
Reranking autonomo
Ma se scarichiamo i documenti da Internet prima, la risposta del sistema di ricerca potrebbe essere influenzata dalle preferenze/algoritmi del provider di ricerca, dal contenuto sponsorizzato, dall’ottimizzazione SEO, ecc. quindi è necessario un reranking post-ricerca.
Quello che stavo facendo:
- ottenere gli embedding per la query di ricerca
- ottenere gli embedding per ogni documento. comunque, il documento non era previsto per superare i 8k token
- calcolare la similarità tra la query e gli embedding di ogni documento
- ordinare i documenti in base a questa similarità.
Nessun database vettoriale qui, andiamo avanti.
Codice di esempio
Utilizzando Langchain per connettersi a Ollama e alla funzione cosine_similarity di Langchain. Puoi filtrare in base alla misura di similarità, ma tieni presente che per diversi domini e modelli LLM di embedding il limite sarà diverso.
Sarò felice se questo frammento di codice ti sarà utile in qualche modo. Licenza Copy/Paste/UseAnyWayYouWant. Grazie.
from langchain_core.documents import Document
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.utils.math import cosine_similarity
import numpy as np
def cosine_distance(a: np.ndarray, b: np.ndarray) -> np.ndarray:
return 1.0 - cosine_similarity(a, b)
def compute_score(vectors: np.ndarray) -> float:
score = cosine_distance(vectors[0].reshape(1, -1), vectors[1].reshape(1, -1)).item()
return score
def list_to_array(lst):
return np.array(lst, dtype=float)
def compute_scorel(lists) -> float:
v1 = list_to_array(lists[0])
v2 = list_to_array(lists[1])
return compute_score([v1, v2])
def filter_docs(emb_model_name, docs, query, num_docs):
content_arr = [doc.page_content for doc in docs]
ollama_emb = OllamaEmbeddings(
model=emb_model_name
)
docs_embs = ollama_emb.embed_documents(content_arr)
query_embs = ollama_emb.embed_query(query)
sims = []
for i, emb in enumerate(docs_embs):
idx = docs[i].id
s = compute_scorel([query_embs, docs_embs[i]])
simstr = str(round(s, 4))
docs[i].metadata["sim"] = simstr
sim = {
"idx": idx,
"i": i,
"sim": s,
}
sims.append(sim)
sims.sort(key=sortFn)
sorted_docs = [docs[x["i"]] for x in sims]
filtered_docs = sorted_docs[:num_docs]
return filtered_docs
Migliori modelli di embedding
Per i miei compiti, il miglior modello di embedding attualmente è bge-large:335m-en-v1.5-fp16
Al secondo posto ci sono nomic-embed-text:137m-v1.5-fp16
e jina/jina-embeddings-v2-base-en:latest
.
Ma fai i tuoi propri test per il tuo dominio e le tue query.
Link utili
- Modelli di embedding e reranking di Qwen3 su Ollama: prestazioni all’avanguardia
- https://en.wikipedia.org/wiki/Retrieval-augmented_generation
- Foglio di riferimento per Python
- Come Ollama gestisce le richieste parallele
- Scrittura di prompt efficaci per gli LLM
- Test degli LLM: gemma2, qwen2 e Mistral Nemo
- Installazione e configurazione di Ollama
- Confronto tra LLM: Mistral Small, Gemma 2, Qwen 2.5, Mistral Nemo, LLama3 e Phi
- Foglio di riferimento per Conda
- Foglio di riferimento per Ollama
- Lambda stratificate con AWS SAM e Python
- Test: Come Ollama utilizza le prestazioni del processore Intel e i core efficienti