Herordenen met embeddingmodellen
Een Python-code voor het herordenen van RAG
Reranking is een tweede stap in Retrieval Augmented Generation (RAG) systemen, recht tussen het Ophalen en het Genereren.
Het hierboven is hoe Flux-1 dev Elektrische kubussen in digitale ruimte
voorstelt.
Ophalen met reranking
Als we de documenten vanaf het begin opslaan in de vorm van embeddings in de vector DB - dan geeft het ophalen direct een lijst met vergelijkbare documenten.
Afhankelijk reranking
Maar als we de documenten eerst van het internet downloaden, kan het antwoord van het zoeksysteem beïnvloed worden door voorkeuren/algoritmen van zoekproviders, gesponsorde inhoud, SEO-optimalisatie, enzovoort, dus we hebben postzoek reranking nodig.
Wat ik deed:
- embeddings ophalen voor de zoekquery
- embeddings ophalen voor elk document. het document werd sowieso niet verwacht te zijn langer dan 8k tokens
- de gelijkenis tussen query en elk van de documentembeddings berekenen
- documenten sorteren op basis van deze gelijkenis.
Geen vector DB hier, laten we gaan.
Voorbeeldcode
Met behulp van Langchain om verbinding te maken met Ollama en de cosine_similarity functie van langchain. Je kunt filteren op gelijkenismaat, maar houd er rekening mee dat de drempel anders is voor verschillende domeinen en embedding LLMs.
Ik ben blij als deze code op welke manier dan ook voor jou nuttig is. Copy/Paste/UseAnyWayYouWant licentie. Cheers.
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
Beste Embeddingmodellen
Voor mijn taken is momenteel het beste embeddingmodel bge-large:335m-en-v1.5-fp16
Op tweede plaats kwam nomic-embed-text:137m-v1.5-fp16
en jina/jina-embeddings-v2-base-en:latest
.
Maar voer je eigen tests uit voor je eigen domein en queries.
Nuttige links
- Qwen3 Embedding & Reranker Modellen op Ollama: State-of-the-Art Prestaties
- https://en.wikipedia.org/wiki/Retrieval-augmented_generation
- Python Cheatsheet
- Hoe Ollama Parallelle Verzoeken Behandelt
- Effectief schrijven van prompts voor LLMs
- Testen van LLMs: gemma2, qwen2 en Mistral Nemo
- Installeren en Configureren van Ollama
- LLMs vergelijking: Mistral Small, Gemma 2, Qwen 2.5, Mistral Nemo, LLama3 en Phi
- Conda Cheatsheet
- Ollama Cheatsheet
- Laaggeplaatste Lambdas met AWS SAM en Python
- Test: Hoe Ollama Intel CPU Prestaties en Efficiënte Kernen Gebruikt