728x90

Ensemble Retriever란?

  • 앙상블 검색기는 Retriever의 list를 받아서 각각의 Retriever로 get_relevant_documents 방법으로 검색한 결과를 종합한 뒤 Reciprocal Rank Fusion 알고리즘으로 결과를 rerank한다.
  • Similarity search 만으로 성능이 잘 나오지 않을 때 사용하기 좋은 방법론이다.
  • 가장 흔히 사용하는 방식은 sparse retriever(BM25 같이 키워드 기반)와 dense retriever(embedding similarity)를 함께 사용하는 것이다.
  • Hybrid Search 라고도 알려져있고 sparse retriever는 keyword 기반으로 문서를 찾는데 특화되어 있고 dense retriever는 의미론적 유사도 기반으로 문서를 찾는데 특화되어 있으므로 두 종류를 합쳐서 사용하면 효과가 좋다.관련 문서 링크
  • Reciprocal Rank Fusion에 대한 자세한 설명은 👉여기
  • Ensemble Retriever 관련 Langchain 문서 👉여기
  • BM25 Retriever 관련 Langchain 문서 👉여기

Dependency 설치

pip install --upgrade --quiet  rank_bm25 > /dev/null
pip install rank_bm25
pip install faiss-cpu
from langchain.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings

실습

Retriever 정의

문자열이 저장된 리스트 2개를 선언한다. 이후 bm25_retriever와 faiss_retriever를 정의한다.
metadatas에 source를 정해주고 가져올 문서의 개수는 k로 설정한다.

이후 ensemble_retriever를 구성하고 weights로 어떤 retriever의 결과를 더 반영할 지 정한다.

doc_list_1 = [
    "I like apples",
    "I like oranges",
    "Apples and oranges are fruits",
]

# initialize the bm25 retriever and faiss retriever
bm25_retriever = BM25Retriever.from_texts(
    doc_list_1, metadatas=[{"source": 1}] * len(doc_list_1)
)
bm25_retriever.k = 2

doc_list_2 = [
    "You like apples",
    "You like oranges",
]

embedding = OpenAIEmbeddings()
faiss_vectorstore = FAISS.from_texts(
    doc_list_2, embedding, metadatas=[{"source": 2}] * len(doc_list_2)
)
faiss_retriever = faiss_vectorstore.as_retriever(search_kwargs={"k": 2})

# initialize the ensemble retriever
ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, faiss_retriever], weights=[0.5, 0.5]

이제 결과를 살펴보자

docs = ensemble_retriever.invoke("apples")
docs

결과

[Document(page_content='You like apples', metadata={'source': 2}),
 Document(page_content='I like apples', metadata={'source': 1}),
 Document(page_content='You like oranges', metadata={'source': 2}),
 Document(page_content='Apples and oranges are fruits', metadata={'source': 1})]

Runtime Configuration

개발자는 runtime에 retriever들을 구성할 수 있다. 이를 위해서는 우선 field들을 configurable 할 수 있게 표시해야한다.

 from langchain_core.runnables import ConfigurableField

아래 과정을 통해서 개발자는 runtime에 faiss_retriever가 몇개의 문서를 반환할 지 결정할 수 있다.

 faiss_retriever = faiss_vectorstore.as_retriever(
    search_kwargs={"k": 2}
).configurable_fields(
    search_kwargs=ConfigurableField(
        id="search_kwargs_faiss",
        name="Search Kwargs",
        description="The search kwargs to use",
    )
)
ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, faiss_retriever], weights=[0.5, 0.5]
)
config = {"configurable": {"search_kwargs_faiss": {"k": 1}}}
docs = ensemble_retriever.invoke("apples", config=config)
docs

'인공지능 > RAG' 카테고리의 다른 글

LangChain (10) Gemini로 RAG 구현  (0) 2024.06.04
What is Elastic Search?  (0) 2024.06.03
Langchain - Hybrid Search 구현  (0) 2024.05.31
MongoDB와 Gemma를 사용한 RAG 실습(LangChain X)  (0) 2024.05.28
Langchain - MessagesPlaceholder  (0) 2024.05.24

+ Recent posts