FastembedLateInteractionRanker

FastembedLateInteractionRanker

FastEmbed를 통해 ColBERT 모델을 사용해 쿼리와의 유사도에 따라 문서 순위를 매기는 컴포넌트예요.

출처: 문서

본문

  • 파이프라인에서의 일반적인 위치: 쿼리 파이프라인에서 Retriever처럼 문서 리스트를 반환하는 컴포넌트 뒤에 사용해요.
  • 필수 실행 변수: documents(문서 리스트), query(쿼리 문자열)
  • 출력 변수: documents(문서 리스트)

개요 (Overview)

FastembedLateInteractionRanker는 늦은 상호작용 점수(late interaction scoring) 로 문서 순위를 매겨요. 크로스 인코더 랭커(쿼리와 문서를 함께 인코딩)와 달리, ColBERT는 쿼리와 각 문서를 토큰 수준 임베딩으로 각각 독립적으로 인코딩한 뒤 MaxSim 점수를 계산해요. 각 쿼리 토큰에 대해 가장 유사한 문서 토큰을 찾고, 이 최대 유사도들을 합산해 최종 관련성 점수를 만들어요.

이 접근법은 ColBERT에게 정확성과 효율성 사이의 강한 균형을 줘요. bi-encoder보다 표현력이 뛰어나면서도, 추론 시점에서는 cross-encoder보다 빠르죠.

FastembedLateInteractionRanker는 RAG(검색 증강 생성) 파이프라인이나 문서 검색 파이프라인 같은 쿼리 파이프라인에서 가장 유용해요. Retriever 뒤에 사용해 후보 문서 집합을 관련성에 따라 다시 순위를 매기세요. Retriever와 함께 쓸 때는 Retriever의 top_k를 Ranker의 top_k보다 높게 설정하세요. 넓은 후보 집합을 검색한 뒤 ColBERT가 가장 좋은 것들을 고르게 해요.

기본적으로 이 컴포넌트는 colbert-ir/colbertv2.0 모델을 사용해요. 다양한 초기화 설정에 대한 자세한 내용은 API reference 페이지를 참고하세요.

note

ColBERT 점수는 정규화되지 않은 합산(확률이 아님)이에요. 그 크기는 쿼리 길이와 문서 길이에 따라 달라지며, 보통 약 3에서 30 사이예요. 단일 쿼리 안에서 순위를 매기는 데는 의미가 있지만, 서로 다른 쿼리 간에는 비교하면 안 돼요.

호환 모델 (Compatible Models)

호환되는 ColBERT 모델은 FastEmbed 문서에서 찾을 수 있어요.

설치 (Installation)

이 통합을 Haystack에서 사용하려면 패키지를 설치하세요.

pip install fastembed-haystack

파라미터 (Parameters)

모델이 저장될 경로를 캐시 디렉터리로 설정할 수 있어요. 단일 onnxruntime 세션이 사용할 스레드 수를 설정할 수도 있어요.

ranker = FastembedLateInteractionRanker(
    model_name="colbert-ir/colbertv2.0",
    cache_dir="/your_cache_directory",
    threads=2,
)

대규모 문서 집합의 오프라인 인코딩을 위해 데이터 병렬 처리를 활성화할 수 있어요.

ranker = FastembedLateInteractionRanker(
    model_name="colbert-ir/colbertv2.0",
    batch_size=64,
    parallel=2,  # number of parallel processes; 0 = use all cores
)

사용법 (Usage)

단독 사용 (On its own)

FastembedLateInteractionRanker로 두 개의 간단한 문서 순위를 매기는 예시예요.

from haystack import Document
from haystack_integrations.components.rankers.fastembed import (
    FastembedLateInteractionRanker,
)

docs = [Document(content="Paris"), Document(content="Berlin")]

ranker = FastembedLateInteractionRanker(model_name="colbert-ir/colbertv2.0", top_k=1)

result = ranker.run(query="City in Germany", documents=docs)
print(result["documents"][0].content)
# Berlin

파이프라인에서 사용 (In a pipeline)

임베딩 유사도로 문서를 검색하고, FastembedLateInteractionRanker로 다시 순위를 매긴 뒤, LLM으로 답변을 생성하는 전체 RAG 파이프라인 예시예요.

이 예시는 추가 패키지가 필요한 TransformersChatGenerator를 사용해요.

pip install "transformers[torch]"

이 페이지의 예시는 transformers-haystack 패키지의 Transformers 컴포넌트를 사용해요. 예시를 실행하려면 설치하세요.

pip install transformers-haystack
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore

from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder
from haystack_integrations.components.generators.transformers import (
    TransformersChatGenerator,
)
from haystack.components.writers import DocumentWriter
from haystack.dataclasses import ChatMessage
from haystack_integrations.components.rankers.fastembed import (
    FastembedLateInteractionRanker,
)
from haystack_integrations.components.embedders.fastembed import (
    FastembedDocumentEmbedder,
    FastembedTextEmbedder,
)

# Set up and populate the document store
document_store = InMemoryDocumentStore()
docs = [
    Document(content="Paris is the capital of France."),
    Document(content="Berlin is the capital of Germany."),
    Document(content="Madrid is the capital of Spain."),
]

indexing = Pipeline()
indexing.add_component("embedder", FastembedDocumentEmbedder())
indexing.add_component("writer", DocumentWriter(document_store=document_store))
indexing.connect("embedder", "writer")
indexing.run({"embedder": {"documents": docs}})

# Define the chat prompt template
prompt_template = [
    ChatMessage.from_system("You are a helpful assistant."),
    ChatMessage.from_user(
        "Given these documents, answer the question.\n"
        "Documents:\n{% for doc in documents %}{{ doc.content }}{% endfor %}\n"
        "Question: {{query}}\nAnswer:",
    ),
]

# Build the query pipeline with ColBERT reranking
rag = Pipeline()
rag.add_component("text_embedder", FastembedTextEmbedder())
rag.add_component(
    "retriever",
    InMemoryEmbeddingRetriever(document_store=document_store, top_k=3),
)
rag.add_component(
    "ranker",
    FastembedLateInteractionRanker(model_name="colbert-ir/colbertv2.0", top_k=2),
)
rag.add_component(
    "prompt_builder",
    ChatPromptBuilder(
        template=prompt_template,
        required_variables={"query", "documents"},
    ),
)
rag.add_component(
    "llm",
    TransformersChatGenerator(model="HuggingFaceTB/SmolLM2-360M-Instruct"),
)

rag.connect("text_embedder.embedding", "retriever.query_embedding")
rag.connect("retriever.documents", "ranker.documents")
rag.connect("ranker.documents", "prompt_builder.documents")
rag.connect("prompt_builder.prompt", "llm.messages")

query = "What is the capital of Germany?"
result = rag.run(
    {
        "text_embedder": {"text": query},
        "ranker": {"query": query},
        "prompt_builder": {"query": query},
    },
)
print(result["llm"]["replies"][0].text)

더 알아보기 (Learn more)