埋め込みモデルによる再ランキング
RAGのリランキングのPythonコード
Reranking は、Retrieval Augmented Generation (RAG) システム の二つ目のステップであり、Retrieving と Generating の間にある。
上記は、Flux-1 dev が想像する Electric cubes in digital space
の様子です。
Retrieval with reranking
もし最初からドキュメントをベクトル DB に埋め込み形式で保存する場合、Retrieval はすぐに類似したドキュメントのリストを返します。
Standalone reranking
しかし、インターネットからドキュメントをダウンロードしてから検索を行う場合、検索プロバイダーの好みやアルゴリズム、スポンサーコンテンツ、SEO 最適化などによって検索システムの応答が影響を受ける可能性があるため、検索後の再評価(ポスト検索再評価)が必要になります。
私がしていたこと:
- 検索クエリの埋め込みを取得
- 各ドキュメントの埋め込みを取得。ドキュメントが8,000トークンを超えることは予想されていなかった
- クエリと各ドキュメントの埋め込みの類似度を計算
- 類似度によってドキュメントを並べ替える
ベクトル DB はここにはありません。それでは進みましょう。
サンプルコード
Langchain を使って Ollama に接続し、langchain の cosine_similarity 関数を使用しています。 類似度でフィルタリングすることはできますが、ドメインや埋め込み LLM によってしきい値は異なることを覚えておいてください。
このコードが皆様にとって役立つことを願っています。 Copy/Paste/UseAnyWayYouWant ライセンス。 よろしくお願いします。
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
最も優れた埋め込みモデル
私のタスクにおいて現在最も優れた埋め込みモデルは bge-large:335m-en-v1.5-fp16
です。
二位は nomic-embed-text:137m-v1.5-fp16
と jina/jina-embeddings-v2-base-en:latest
です。
しかし、ご自身のドメインとクエリに対してご自身でテストを行ってください。
有用なリンク
- Ollama 上の Qwen3 埋め込みおよび再評価モデル: 画期的な性能
- https://en.wikipedia.org/wiki/Retrieval-augmented_generation
- Python チートシート
- Ollama が並列リクエストをどのように処理するか
- LLM に対して効果的なプロンプトの書き方
- LLM のテスト: gemma2, qwen2 および Mistral Nemo
- Ollama のインストールと設定
- LLM 比較: Mistral Small, Gemma 2, Qwen 2.5, Mistral Nemo, LLama3 および Phi
- Conda チートシート
- Ollama チートシート
- AWS SAM と Python を使用したレイヤード Lambda の実装
- テスト: Ollama がインテル CPU の性能と効率的なコアをどのように利用しているか