RRF 排序器
Reciprocal Rank Fusion (RRF) Ranker 是 Milvus 混合搜尋的重新排序策略,可根據多個向量搜尋路徑的排序位置而非原始相似度得分來平衡搜尋結果。就像體育比賽考慮的是球員的排名而不是個人統計,RRF Ranker 根據每個項目在不同搜索路徑中的排名高低來組合搜索結果,從而創建一個公平和平衡的最終排名。
何時使用 RRF Ranker
RRF Ranker 專門設計用於混合搜尋的情況,在這種情況下,您想要平衡來自多個向量搜尋路徑的結果,而不需要指定明確的重要性權重。它對以下情況特別有效
使用案例 |
範例 |
為什麼 RRF Ranker 運作良好 |
|---|---|---|
具有同等重要性的多模式搜尋 |
兩種模式同等重要的圖像-文字搜尋 |
無需任意權重分配即可平衡結果 |
集合向量搜尋 |
結合不同嵌入模型的結果 |
以民主方式合併排名,不偏向任何特定模型的得分分佈 |
跨語言搜尋 |
跨語言搜尋文件 |
不考慮特定語言的嵌入特徵,公平地排列結果 |
專家推薦 |
結合來自多個專家系統的建議 |
當不同系統使用無法比較的評分方法時,可建立共識排名 |
如果您的混合搜尋應用需要以民主方式平衡多種搜尋路徑,而不需要指定明確的權重,RRF Ranker 就是您的理想選擇。
RRF Ranker 的機制
RRFRanker 策略的主要工作流程如下:
收集搜尋排名:收集向量搜尋各個路徑的結果排名 (rank_1、rank_2)。
合併排名:根據公式轉換各路徑的排名 (rank_rrf_1, rank_rrf_2)。
Ranki(d) 是第 i(th)個擷取器產生的文件d的排名位置。
總結排名:根據綜合排名對搜尋結果重新排序,以產生最終結果。
RRF 排序器
RRF 排序器範例
此範例展示了在稀疏密集向量上的混合搜尋 (topK=5),並說明 RRFRanker 策略如何將兩個 ANN 搜尋的結果重新排序。
文本稀疏向量上的 ANN 搜尋結果 (topK=5):
ID
排名 (稀疏)
101
1
203
2
150
3
198
4
175
5
ANN 在密集文字向量上的搜尋結果 (topK=5):...
ID
排名 (密集)
198
1
101
2
110
3
175
4
250
5
使用 RRF 重新排列兩組搜尋結果的排名。假設平滑參數
k設定為 60。ID
得分(稀疏)
得分 (密集)
最終得分
101
1
2
1/(60+1)+1/(60+2) = 0.03252247
198
4
1
1/(60+4)+1/(60+1) = 0.03201844
175
5
4
1/(60+5)+1/(60+4) = 0.03100962
203
2
不適用
1/(60+2) = 0.01612903
150
3
不適用
1/(60+3) = 0.01587302
110
不適用
3
1/(60+3) = 0.01587302
250
不適用
5
1/(60+5) = 0.01538462
重排後的最終結果(topK=5):
排名
ID
最終得分
1
101
0.03252247
2
198
0.03201844
3
175
0.03100962
4
203
0.01612903
5
150
0.01587302
5
110
0.01587302
RRF 排序器的使用
使用 RRF 重排策略時,需要設定參數k 。這是一個平滑參數,可以有效地改變全文搜索與向量搜索的相對權重。此參數的預設值為 60,可在 (0, 16384) 的範圍內調整。該值應為浮點數。建議值在 [10, 100] 之間。雖然k=60 是常見的選擇,但最佳的k 值可能因您的特定應用程式和資料集而異。我們建議根據您的特定用例來測試和調整此參數,以達到最佳效能。
建立 RRF 排序器
用多個向量場設定好您的資料集後,使用適當的平滑參數建立 RRF Ranker:
Milvus 2.6.x 及更高版本可讓您直接透過Function API 設定重排策略。如果您使用的是早期版本(v2.6.0 之前),請參閱Reranking文檔中的設定說明。
from pymilvus import Function, FunctionType
ranker = Function(
name="rrf",
input_field_names=[], # Must be an empty list
function_type=FunctionType.RERANK,
params={
"reranker": "rrf",
"k": 100 # Optional
}
)
import io.milvus.common.clientenum.FunctionType;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq.Function rerank = CreateCollectionReq.Function.builder()
.name("rrf")
.functionType(FunctionType.RERANK)
.param("reranker", "rrf")
.param("k", "100")
.build();
import { FunctionType } from "@zilliz/milvus2-sdk-node";
const ranker = {
name: "weight",
input_field_names: [],
function_type: FunctionType.RERANK,
params: {
reranker: "weighted",
weights: [0.1, 0.9],
norm_score: true,
},
};
// Go
# Restful
參數 |
需要嗎? |
說明 |
值/範例 |
|---|---|---|---|
|
是 |
此功能的唯一識別碼 |
|
|
是 |
要應用函式的向量欄位清單 (RRF Ranker 必須為空) |
[] |
|
是 |
要調用的函數類型;使用 |
|
|
是 |
指定要使用的排名方法。 必須設定為 |
|
|
無 |
平滑參數,用來控制文件排名的影響;較高的 如需詳細資訊,請參閱RRF Ranker 的機制。 |
|
應用於混合搜尋
RRF Ranker 是專為結合多向量場的混合搜尋作業而設計的。以下是如何在混合搜尋中使用它:
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 RRF Ranker to product hybrid search
# The smoothing parameter k controls the balance
hybrid_results = milvus_client.hybrid_search(
collection_name,
[text_search, image_search], # Multiple search requests
ranker=ranker, # Apply the RRF 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 ranker = {
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,
data: [text_search, image_search],
output_fields: ["product_name", "price", "category"],
limit: 10,
rerank: ranker,
});
// go
# restful
有關混合搜尋的更多資訊,請參閱多向量混合搜尋。