가중랭커
가중랭커는 여러 검색 경로의 결과를 지능적으로 결합하고 각각에 서로 다른 중요도 가중치를 부여하여 우선순위를 지정합니다. 숙련된 요리사가 완벽한 요리를 만들기 위해 여러 재료의 균형을 맞추는 것과 마찬가지로, 가중치 랭커는 서로 다른 검색 결과의 균형을 맞춰 가장 관련성이 높은 결과를 조합합니다. 이 접근 방식은 여러 벡터 필드 또는 양식에 걸쳐 검색할 때 특정 필드가 다른 필드보다 최종 순위에 더 크게 기여해야 하는 경우에 이상적입니다.
가중치 랭커를 사용하는 경우
가중치 랭커는 여러 벡터 검색 경로의 결과를 결합해야 하는 하이브리드 검색 시나리오를 위해 특별히 설계되었습니다. 특히 다음과 같은 경우에 효과적입니다:
사용 사례 |
예시 |
웨이트 랭커가 잘 작동하는 이유 |
|---|---|---|
이커머스 검색 |
이미지 유사도와 텍스트 설명을 결합한 제품 검색 |
리테일러가 패션 상품의 경우 시각적 유사성을 우선시하는 동시에 기술 제품의 경우 텍스트 설명을 강조할 수 있습니다. |
미디어 콘텐츠 검색 |
시각적 기능과 오디오 대본을 모두 사용한 비디오 검색 |
쿼리 의도에 따라 시각적 콘텐츠와 음성 대화의 중요성 간의 균형을 맞출 수 있습니다. |
문서 검색 |
다양한 섹션에 대한 여러 임베딩이 포함된 엔터프라이즈 문서 검색 |
전체 텍스트 임베딩을 고려하면서 제목 및 초록 임베딩에 더 높은 가중치를 부여합니다. |
하이브리드 검색 애플리케이션에서 여러 검색 경로를 결합하면서 상대적 중요도를 제어해야 하는 경우, 가중치 랭커가 이상적인 선택입니다.
가중치 랭커의 메커니즘
웨이트 랭커 전략의 주요 워크플로는 다음과 같습니다:
검색 점수 수집: 벡터 검색의 각 경로에서 결과와 점수를 수집합니다(score_1, score_2).
점수 정규화: 각 검색은 서로 다른 유사성 메트릭을 사용할 수 있으므로 점수 분포가 달라질 수 있습니다. 예를 들어, 유사도 유형으로 내적 곱(IP)을 사용하면 [-∞,+∞] 범위의 점수가 나올 수 있는 반면, 유클리드 거리(L2)를 사용하면 [0,+∞] 범위의 점수가 나올 수 있습니다. 검색 방식에 따라 점수 범위가 다르고 직접 비교할 수 없으므로 각 검색 경로의 점수를 정규화해야 합니다. 일반적으로
arctan함수를 적용하여 점수를 [0, 1] 사이의 범위로 변환합니다(score_1_normalized, score_2_normalized). 점수가 1에 가까울수록 유사성이 높음을 나타냅니다.가중치를 할당합니다: 서로 다른 벡터 필드에 할당된 중요도에 따라 가중치(wi)가 정규화된 점수(score_1_normalized, score_2_normalized)에 할당됩니다. 각 경로의 가중치는 [0,1] 범위여야 합니다. 결과 가중치 점수는 score_1_weighted 및 score_2_weighted입니다.
점수 병합: 가중치 점수(score_1_weighted, score_2_weighted)를 가장 높은 점수부터 가장 낮은 점수까지 순위를 매겨 최종 점수 세트(score_final)를 생성합니다.
가중 랭커
가중 랭커의 예
이 예는 이미지와 텍스트가 포함된 멀티모달 하이브리드 검색(topK=5)을 보여 주며, 가중치랭커 전략이 두 개의 ANN 검색 결과를 어떻게 재순위화하는지를 보여줍니다.
이미지에 대한 ANN 검색 결과(topK=5): 다음과 같습니다.
ID
점수(이미지)
101
0.92
203
0.88
150
0.85
198
0.83
175
0.8
텍스트에 대한 ANN 검색 결과(topK=5):: 다음과 같습니다.
ID
점수(텍스트)
198
0.91
101
0.87
110
0.85
175
0.82
250
0.78
가중치랭커를 사용하여 이미지 및 텍스트 검색 결과에 가중치를 할당합니다. 이미지 ANN 검색의 가중치는 0.6이고 텍스트 검색의 가중치는 0.4라고 가정합니다.
ID
점수(이미지)
점수(텍스트)
가중치 점수
101
0.92
0.87
0.6×0.92+0.4×0.87=0.90
203
0.88
N/A
0.6×0.88+0.4×0=0.528
150
0.85
N/A
0.6×0.85+0.4×0=0.51
198
0.83
0.91
0.6×0.83+0.4×0.91=0.86
175
0.80
0.82
0.6×0.80+0.4×0.82=0.81
110
이미지에 없음
0.85
0.6×0+0.4×0.85=0.34
250
이미지에 없음
0.78
0.6×0+0.4×0.78=0.312
재랭크 후 최종 결과(상위 K=5): 다음과 같습니다.
Rank
ID
최종 점수
1
101
0.90
2
198
0.86
3
175
0.81
4
203
0.528
5
150
0.51
가중 랭커 사용
가중랭커 전략을 사용할 때는 가중치 값을 입력해야 합니다. 입력할 가중치 값의 개수는 하이브리드 검색의 기본 ANN 검색 요청 수와 일치해야 합니다. 입력 가중치 값은 [0,1] 범위에 속해야 하며, 1에 가까운 값일수록 중요도가 높음을 나타냅니다.
가중 랭킹 생성하기
예를 들어, 하이브리드 검색에 텍스트 검색과 이미지 검색이라는 두 가지 기본 ANN 검색 요청이 있다고 가정해 보겠습니다. 텍스트 검색이 더 중요하다고 판단되면 더 큰 가중치를 할당해야 합니다.
Milvus 2.6.x 이상에서는 Function API를 통해 직접 리랭크 전략을 구성할 수 있습니다. 이전 릴리스(v2.6.0 이전)를 사용하는 경우 재랭크 설정 설명서를 참조하여 설정 지침을 확인하세요.
from pymilvus import Function, FunctionType
rerank = Function(
name="weight",
input_field_names=[], # Must be an empty list
function_type=FunctionType.RERANK,
params={
"reranker": "weighted",
"weights": [0.1, 0.9],
"norm_score": True # Optional
}
)
import io.milvus.common.clientenum.FunctionType;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq.Function rerank = CreateCollectionReq.Function.builder()
.name("weight")
.functionType(FunctionType.RERANK)
.param("reranker", "weighted")
.param("weights", "[0.1, 0.9]")
.param("norm_score", "true")
.build();
import { FunctionType } from '@zilliz/milvus2-sdk-node';
const rerank = {
name: "weight",
input_field_names: [],
function_type: FunctionType.RERANK,
params: {
reranker: "weighted",
weights: [0.1, 0.9],
norm_score: true
}
};
// Go
# Restful
파라미터 |
필수? |
설명 |
값/예시 |
|---|---|---|---|
|
예 |
이 함수의 고유 식별자 |
|
|
예 |
함수를 적용할 벡터 필드 목록(가중치 랭커의 경우 비워둬야 합니다). |
[] |
|
Yes |
호출할 함수의 유형( |
|
|
예 |
사용할 재랭킹 방법을 지정합니다. 가중 랭킹을 사용하려면 |
|
|
예 |
각 검색 경로에 해당하는 가중치의 배열, 값 ∈ [0,1]. 자세한 내용은 가중 랭커의 메커니즘을 참조하세요. |
|
|
No |
가중치를 적용하기 전에 원시 점수를 정규화할지 여부(아크탄 사용). 자세한 내용은 가중 랭커의 메커니즘을 참조하세요. |
|
하이브리드 검색에 적용
가중치 랭커는 여러 벡터 필드를 결합하는 하이브리드 검색 작업을 위해 특별히 설계되었습니다. 하이브리드 검색을 수행할 때는 각 검색 경로에 대한 가중치를 지정해야 합니다:
from pymilvus import MilvusClient, AnnSearchRequest
# Connect to Milvus server
milvus_client = MilvusClient(uri="http://localhost:19530")
# Assume you have a collection setup
# Define text vector search request
text_search = AnnSearchRequest(
data=["modern dining table"],
anns_field="text_vector",
param={},
limit=10
)
# Define image vector search request
image_search = AnnSearchRequest(
data=[image_embedding], # Image embedding vector
anns_field="image_vector",
param={},
limit=10
)
# Apply Weighted Ranker to product hybrid search
# Text search has 0.8 weight, image search has 0.3 weight
hybrid_results = milvus_client.hybrid_search(
collection_name,
[text_search, image_search], # Multiple search requests
ranker=rerank, # Apply the weighted ranker
limit=10,
output_fields=["product_name", "price", "category"]
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.AnnSearchReq;
import io.milvus.v2.service.vector.request.HybridSearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.request.data.FloatVec;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.build());
List<AnnSearchReq> searchRequests = new ArrayList<>();
searchRequests.add(AnnSearchReq.builder()
.vectorFieldName("text_vector")
.vectors(Collections.singletonList(new EmbeddedText("\"modern dining table\"")))
.limit(10)
.build());
searchRequests.add(AnnSearchReq.builder()
.vectorFieldName("image_vector")
.vectors(Collections.singletonList(new FloatVec(imageEmbedding)))
.limit(10)
.build());
HybridSearchReq hybridSearchReq = HybridSearchReq.builder()
.collectionName(COLLECTION_NAME)
.searchRequests(searchRequests)
.ranker(ranker)
.limit(10)
.outputFields(Arrays.asList("product_name", "price", "category"))
.build();
SearchResp searchResp = client.hybridSearch(hybridSearchReq);
import { MilvusClient, FunctionType } from "@zilliz/milvus2-sdk-node";
const milvusClient = new MilvusClient({ address: "http://localhost:19530" });
const text_search = {
data: ["modern dining table"],
anns_field: "text_vector",
param: {},
limit: 10,
};
const image_search = {
data: [image_embedding],
anns_field: "image_vector",
param: {},
limit: 10,
};
const rerank = {
name: "weight",
input_field_names: [],
function_type: FunctionType.RERANK,
params: {
reranker: "weighted",
weights: [0.1, 0.9],
norm_score: true,
},
};
const search = await milvusClient.search({
collection_name: collection_name,
limit: 10,
data: [text_search, image_search],
rerank: rerank,
output_fields = ["product_name", "price", "category"],
});
// go
# restful
하이브리드 검색에 대한 자세한 내용은 다중 벡터 하이브리드 검색을 참조하세요.