멀티벡터 후처리
멀티벡터 후처리 (fastembed-fastembed-postprocessing)
멀티벡터 임베딩을 만들고 나면, 이걸 그대로 검색에 쓰기에는 검색 속도가 느려지는 경우가 많아요. 이럴 때 FastEmbed의 postprocessing(후처리) 모듈이 빛을 발해요. FastEmbed의 후처리 모듈은 임베딩을 생성한 뒤 이를 변환하고 최적화하는 기법들을 제공해요. 이런 후처리 방법은 검색 성능을 높이거나 저장 공간 요구량을 줄이거나, 특정 사용 사례에 맞게 임베딩을 적응시키는 데 쓸 수 있어요. 현재 후처리 모듈에는 멀티벡터 임베딩을 가속화하는 MUVERA(Multi-Vector Retrieval Algorithm)가 포함되어 있고, 추가적인 후처리 기법들은 향후 릴리스에서 계획되어 있어요.
출처: Qdrant 공식문서
MUVERA
MUVERA는 가변 길이의 벡터 시퀀스를 고정 차원의 단일 벡터 표현으로 변환해요. 이렇게 만든 근사 표현(approximation)은 HNSW 같은 전통적인 벡터 검색 방법으로 빠른 초기 검색을 수행하는 데 사용할 수 있어요.
이 하이브리드 접근 방식은 단일 벡터 검색의 속도와 멀티벡터 검색의 정확도를 모두 잡아요. 컬렉션의 모든 문서를 비싼 멀티벡터 유사도 계산으로 비교하는 대신, MUVERA를 쓰면 다음이 가능해져요:
- 빠르게 검색 (Retrieve quickly): MUVERA 임베딩으로 전통적인 벡터 검색 + 오버샘플링(Oversampling)으로 상위 후보를 찾는다.
- 정밀하게 재순위화 (Rerank precisely): 이렇게 줄어든 작은 후보 집합에만 MaxSim을 이용한 멀티벡터 유사도를 적용한다.
MUVERA가 어떻게 동작하는지에 대한 자세한 기술적 설명은 MUVERA: Making Multivectors More Performant 아티클을 참고해요.
FastEmbed에서 MUVERA 사용하기 (Using MUVERA in FastEmbed)
이 튜토리얼에서는 장난감(toy) 데이터셋으로 MUVERA를 이용한 빠른 검색과 ColBERT 재순위화를 보여줘요. 멀티벡터 임베딩이 처음이라면, 먼저 FastEmbed로 ColBERT 멀티벡터 만드는 법을 읽어보길 권해요.
Setup
MUVERA 후처리를 사용하려면 FastEmbed 0.7.2 이상을 설치해요.
pip install "fastembed>=0.7.2"
late interaction 임베딩과 MUVERA 후처리에 필요한 모듈을 가져와요.
from fastembed import LateInteractionTextEmbedding
from fastembed.postprocess import Muvera
모델 로드 및 MUVERA 프로세서 생성 (Load Model and Create MUVERA Processor)
model_name = "colbert-ir/colbertv2.0"
model = LateInteractionTextEmbedding(model_name=model_name)
# Create MUVERA processor with recommended parameters
muvera = Muvera.from_multivector_model(
model=model,
k_sim=6,
dim_proj=32,
r_reps=20
)
MUVERA 파라미터는 결과 임베딩의 크기와 품질을 결정해요. 이 권장 값들은 속도와 정확도의 균형을 잡아줘요. k_sim 파라미터는 클러스터 수(2^6 = 64)를 결정하고, dim_proj는 투영(projection) 차원을 설정해요.
ColBERT로 데이터 임베딩 (Embed Data with ColBERT)
MUVERA를 시연하기 위해 영화 설명 장난감 데이터셋을 사용할게요.
"Spinal Tap, one of England's loudest bands, is chronicled by film director Marty DiBergi on what proves to be a fateful tour.",
"Oskar, an overlooked and bullied boy, finds love and revenge through Eli, a beautiful but peculiar girl."
]
Qdrant에 업로드 (Upload to Qdrant)
qdrant-client를 설치해요.
pip install "qdrant-client>=1.14.2"
이 예제에서는 로컬 Docker 컨테이너에서 실행 중인 Qdrant를 사용할 거예요. 또는 Qdrant Cloud의 무료 클러스터를 써도 돼요.
from qdrant_client import QdrantClient, models
client = QdrantClient("http://localhost:6333")
MUVERA 임베딩과 원본 멀티벡터 표현을 모두 저장할 컬렉션을 named vectors를 이용해 만들어요.
client.create_collection(
collection_name="movies-muvera",
vectors_config={
"muvera": models.VectorParams(
size=muvera.embedding_size, # Depends on the MUVERA configuration
distance=models.Distance.COSINE
),
"colbert": models.VectorParams(
size=model.embedding_size, # Model-specific
distance=models.Distance.COSINE,
multivector_config=models.MultiVectorConfig(
comparator=models.MultiVectorComparator.MAX_SIM
)
)
}
)
두 표현을 모두 컬렉션에 업로드해요.
client.upload_points(
collection_name="movies-muvera",
points=[
models.PointStruct(
id=idx,
payload={"description": description},
vector={
"muvera": muvera_emb,
"colbert": colbert_emb
}
)
for idx, (description, muvera_emb, colbert_emb) in enumerate(
zip(descriptions, muvera_embeddings, descriptions_embeddings)
)
]
)
하이브리드 검색: MUVERA 검색 + ColBERT 재순위화 (Hybrid Search)
이제 하이브리드 접근 방식으로 검색을 수행해 볼게요. Qdrant는 prefetch 파라미터를 통한 multi-stage 쿼리를 지원해서, MUVERA의 빠른 검색과 ColBERT의 정확한 리스코어링을 하나의 쿼리로 결합할 수 있어요.
먼저 두 형식 모두로 쿼리 임베딩을 만들어요.
query = "A movie for kids with fantasy elements and wonders"
query_multivec = list(model.query_embed(query))[0]
query_muvera = muvera.process_query(query_multivec)
이제 Qdrant의 네이티브 multi-stage 검색으로 2단계 쿼리를 수행해요.
prefetch 파라미터는 MUVERA를 이용해 후보를 검색하고, 그다음 메인 query가 ColBERT의 멀티벡터 표현으로 그 후보들을 리스코어링해요. 멀티벡터 유사도의 MaxSim 계산은 Qdrant가 자동으로 처리해요.
참고: Qdrant의 multi-stage 쿼리 API가 2단계 검색을 네이티브로 처리하므로, 수동으로 재순위화 코드를 작성할 필요가 없어요! multi-stage 쿼리에 대해 더 알아보세요.
결과를 출력해요.
Result 3: "When a machine that allows therapists to enter their patients' dreams is stolen, all hell breaks loose. Only a young female therapist, Paprika, can stop it."
Score: 10.04
이 하이브리드 접근 방식은 컬렉션 전체에 대한 완전한 멀티벡터 검색과 거의 같은 정확도를 유지하면서도 훨씬 빠르다는 걸 확인할 수 있어요. 비싼 멀티벡터 유사도 계산은 20개 후보에만 적용되거든요.
결론 (Conclusion)
MUVERA 후처리는 멀티벡터 임베딩의 검색 가능한 근사 표현을 만들어 대규모 멀티벡터 검색을 실용적으로 가능하게 해줘요. 권장하는 접근 방식은 MUVERA와 Qdrant의 네이티브 multi-stage 쿼리 기능을 조합하는 거예요.
- 빠른 검색 (Fast retrieval):
prefetch와 함께 MUVERA 임베딩을 사용해 후보 문서를 검색한다. - 정밀한 재순위화 (Precise reranking): Qdrant가 ColBERT 멀티벡터로 후보를 자동으로 리스코어링한다.
이 하이브리드 패턴은 비싼 멀티벡터 계산을 MUVERA가 검색한 후보 집합에만 국한함으로써 큰 컬렉션에서도 효율적으로 확장되면서, 순수 멀티벡터 검색과 거의 동일한 검색 품질을 유지해요.
MUVERA는 특히 문서 컬렉션이 커서 멀티벡터 검색이 첫 단계 검색으로는 너무 느린 프로덕션 시스템에서 유용해요. FastEmbed의 MUVERA 후처리와 Qdrant의 multi-stage 쿼리를 조합하면 매끄럽고 성능 좋은 솔루션을 얻을 수 있어요. pip install --upgrade fastembed로 FastEmbed 0.7.2 이상으로 업그레이드해서 지금 바로 MUVERA 후처리를 시작해 보세요.
더 알아보기 (Learn more)
- FastEmbed로 ColBERT 멀티벡터 만들기 — 멀티벡터 임베딩의 기초
- MUVERA: Making Multivectors More Performant — MUVERA의 기술적 원리
- 하이브리드 쿼리 (Hybrid queries) — multi-stage 쿼리 활용법