VLLMDocumentEmbedder

VLLMDocumentEmbedder

vLLM으로 서빙된 모델로 문서 리스트의 임베딩을 계산해 주는 컴포넌트예요.

파이프라인에서 가장 흔한 위치: 인덱싱 파이프라인의 DocumentWriter 앞 필수 init 변수: model — vLLM이 서빙하는 모델 이름 필수 run 변수: documents — 문서 리스트 출력 변수: documents — 임베딩으로 보강된 문서 리스트 API 레퍼런스: vLLM GitHub 링크: https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/vllm 패키지 이름: vllm-haystack

출처: 문서

본문

개요 (Overview)

vLLM은 LLM을 위한 고처리량·메모리 효율적 추론/서빙 엔진이에요. OpenAI 호환 HTTP 서버를 노출하는데, VLLMDocumentEmbedder가 Embeddings API를 통해 임베딩을 계산하는 데 사용해요.

VLLMDocumentEmbedder는 문서 리스트의 임베딩을 계산하고 얻은 벡터를 각 문서의 embedding 필드에 저장해요. api_base_url 파라미터(기본 http://localhost:8000/v1)에서 접근 가능한 vLLM 서버가 실행 중이어야 해요. 문자열(예: 쿼리)을 임베딩하려면 VLLMTextEmbedder를 사용해요.

이 컴포넌트가 계산한 벡터는 문서 컬렉션에서 임베딩 검색을 수행하는 데 필요해요. 검색 시점에는 쿼리를 나타내는 벡터를 문서들의 벡터와 비교해 가장 유사하거나 관련 있는 문서를 찾아요.

vLLM 서버를 --api-key로 시작했다면, Haystack의 Secret API를 통해 VLLM_API_KEY 환경 변수나 api_key init 파라미터로 API 키를 제공하세요.

호환 모델 (Compatible models)

vLLM은 다양한 임베딩 모델을 지원해요. 지원되는 아키텍처와 모델 목록은 vLLM pooling models 문서를 참고하세요.

vLLM 특유 파라미터 (vLLM-specific parameters)

extra_parameters 딕셔너리로 vLLM 특유 파라미터를 전달할 수 있어요. 이 값들은 OpenAI 호환 임베딩 엔드포인트에 extra_body로 전달돼요. 표준 OpenAI Embeddings API에 없는 파라미터(예: truncate_prompt_tokens, truncation_side)를 넘길 때 사용해요. 자세한 내용은 vLLM Embeddings API 문서를 참고하세요.

embedder = VLLMDocumentEmbedder(
    model="google/embeddinggemma-300m",
    extra_parameters={"truncate_prompt_tokens": 256, "truncation_side": "right"},
)

Matryoshka 임베딩 (Matryoshka embeddings)

모델이 Matryoshka Representation Learning으로 학습됐다면, dimensions 파라미터로 출력 벡터의 차원을 줄일 수 있어요. 자세한 내용은 vLLM Matryoshka 문서를 참고하세요.

배칭과 실패 처리 (Batching and failure handling)

VLLMDocumentEmbedder는 문서를 배치 단위로 인코딩해요. batch_size(기본 32)로 vLLM 서버에 단일 요청으로 보낼 문서 수를 조절하고, progress_bar로 진행 표시기를 켜고 끌 수 있어요.

기본적으로(raise_on_failure=False) 실패한 임베딩 요청은 로그로 기록되고 나머지 문서로 처리가 계속돼요. 대신 예외를 던지려면 raise_on_failure=True로 설정하세요.

지시어 (Instructions)

일부 임베딩 모델은 검색에 더 잘 동작하도록 문서 텍스트 앞에 지시어(instruction)를 붙여야 해요. 예를 들어 intfloat/e5-large-v2를 쓴다면 문서 앞에 다음과 같은 지시어를 붙여야 해요: "passage:".

VLLMDocumentEmbedder에서는 이렇게 동작해요:

instruction = "passage:"
embedder = VLLMDocumentEmbedder(
    model="intfloat/e5-large-v2",
    prefix=instruction,
)

메타데이터 임베딩 (Embedding metadata)

문서는 종종 여러 메타데이터를 함께 가져와요. 메타데이터가 뚜렷하고 의미상 의미가 있다면 문서 텍스트와 함께 임베딩해서 검색 성능을 높일 수 있어요. 관련 필드를 meta_fields_to_embed로 전달하면 돼요. 이 값들은 embedding_separator(기본 줄바꿈)를 사용해 문서 텍스트에 연결돼요:

from haystack import Document
from haystack_integrations.components.embedders.vllm import VLLMDocumentEmbedder

doc = Document(content="some text", meta={"title": "relevant title", "page_number": 18})
embedder = VLLMDocumentEmbedder(
    model="google/embeddinggemma-300m",
    meta_fields_to_embed=["title"],
)
docs_with_embeddings = embedder.run(documents=[doc])["documents"]

사용법 (Usage)

VLLMDocumentEmbedder를 쓰려면 vllm-haystack 패키지를 설치해요:

pip install vllm-haystack

vLLM 서버 시작 (Starting the vLLM server)

이 컴포넌트를 쓰기 전에 임베딩 모델로 vLLM 서버를 시작하세요:

vllm serve google/embeddinggemma-300m

서버 옵션에 대한 자세한 내용은 vLLM CLI 문서를 참고하세요.

단독으로 사용하기 (On its own)

from haystack import Document
from haystack_integrations.components.embedders.vllm import VLLMDocumentEmbedder

doc = Document(content="I love pizza!")
document_embedder = VLLMDocumentEmbedder(model="google/embeddinggemma-300m")
result = document_embedder.run([doc])
print(result["documents"][0].embedding)
# [-0.0215301513671875, 0.01499176025390625, ...]

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

from haystack import Document, Pipeline
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
from haystack.components.writers import DocumentWriter
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack_integrations.components.embedders.vllm import (
    VLLMDocumentEmbedder,
    VLLMTextEmbedder,
)

document_store = InMemoryDocumentStore(embedding_similarity_function="cosine")
documents = [
    Document(content="My name is Wolfgang and I live in Berlin"),
    Document(content="I saw a black horse running"),
    Document(content="Germany has many big cities"),
]
document_embedder = VLLMDocumentEmbedder(model="google/embeddinggemma-300m")
writer = DocumentWriter(document_store=document_store, policy=DuplicatePolicy.OVERWRITE)

indexing_pipeline = Pipeline()
indexing_pipeline.add_component("document_embedder", document_embedder)
indexing_pipeline.add_component("writer", writer)
indexing_pipeline.connect("document_embedder", "writer")
indexing_pipeline.run({"document_embedder": {"documents": documents}})

query_pipeline = Pipeline()
query_pipeline.add_component(
    "text_embedder",
    VLLMTextEmbedder(model="google/embeddinggemma-300m"),
)
query_pipeline.add_component(
    "retriever",
    InMemoryEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")

query = "Who lives in Berlin?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
# Document(id=..., content: 'My name is Wolfgang and I live in Berlin', score: ...)

더 알아보기 (Learn more)