ハイブリッド検索
Milvus2.4からマルチベクターサポートとハイブリッド検索フレームワークが導入された。異なる列のこれらのベクトルは、異なる埋め込みモデルに由来する、あるいは異なる処理方法を経た、データの多様な側面を表しています。ハイブリッド検索の結果は、RRF(Reciprocal Rank Fusion)やWeighted Scoringなどのリランキング戦略を使って統合されます。再ランク付け戦略の詳細については、再ランク付けを参照してください。
この機能は、写真、音声、指紋などの様々な属性に基づいて、ベクトル・ライブラリ内で最も類似した人物を特定するような、包括的な検索シナリオで特に役立ちます。
このチュートリアルでは、以下の方法を学びます:
異なるベクトルフィールドの類似検索用に複数の
AnnSearchRequest
インスタンスを作成する;複数の
AnnSearchRequest
インスタンスからの検索結果を結合し、再ランク付けするための再ランク付け戦略の設定;ハイブリッド検索を実行する
hybrid_search()
メソッドを使用してハイブリッド検索を実行する。
このページのコードスニペットはPyMilvus ORMモジュールを使ってMilvusとやりとりします。新しいMilvusClient SDKを使ったコードスニペットは近日公開予定です。
準備
ハイブリッド検索を開始する前に、複数のベクトルフィールドを持つコレクションを持っていることを確認してください。現在、Milvusではコレクションあたりデフォルトで4つのベクターフィールドを導入していますが、proxy.maxVectorFieldNumの設定を変更することで最大10まで拡張することができます。
以下は、filmVector
とposterVector
の2つのベクトルフィールドを持つtest_collection
という名前のコレクションを作成し、ランダムエンティティを挿入する例です。
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType
import random
# Connect to Milvus
connections.connect(
host="127.0.0.1", # Replace with your Milvus server IP
port="19530"
)
# Create schema
fields = [
FieldSchema(name="film_id", dtype=DataType.INT64, is_primary=True),
FieldSchema(name="filmVector", dtype=DataType.FLOAT_VECTOR, dim=5), # Vector field for film vectors
FieldSchema(name="posterVector", dtype=DataType.FLOAT_VECTOR, dim=5)] # Vector field for poster vectors
schema = CollectionSchema(fields=fields,enable_dynamic_field=False)
# Create collection
collection = Collection(name="test_collection", schema=schema)
# Create index for each vector field
index_params = {
"metric_type": "L2",
"index_type": "IVF_FLAT",
"params": {"nlist": 128},
}
collection.create_index("filmVector", index_params)
collection.create_index("posterVector", index_params)
# Generate random entities to insert
entities = []
for _ in range(1000):
# generate random values for each field in the schema
film_id = random.randint(1, 1000)
film_vector = [ random.random() for _ in range(5) ]
poster_vector = [ random.random() for _ in range(5) ]
# create a dictionary for each entity
entity = {
"film_id": film_id,
"filmVector": film_vector,
"posterVector": poster_vector
}
# add the entity to the list
entities.append(entity)
collection.insert(entities)
ステップ 1: 複数の AnnSearchRequest インスタンスの作成
ハイブリッド検索では、hybrid_search()
API を使用して、1 回の呼び出しで複数の ANN 検索要求を実行する。各AnnSearchRequest
は、特定のベクトル・フィールドに対する単一の検索要求を表す。
以下の例では、AnnSearchRequest
インスタンスを 2 つ作成し、2 つのベクトルフィールドに対して個別の類似性検索を実行します。
from pymilvus import AnnSearchRequest
# Create ANN search request 1 for filmVector
query_filmVector = [[0.8896863042430693, 0.370613100114602, 0.23779315077113428, 0.38227915951132996, 0.5997064603128835]]
search_param_1 = {
"data": query_filmVector, # Query vector
"anns_field": "filmVector", # Vector field name
"param": {
"metric_type": "L2", # This parameter value must be identical to the one used in the collection schema
"params": {"nprobe": 10}
},
"limit": 2 # Number of search results to return in this AnnSearchRequest
}
request_1 = AnnSearchRequest(**search_param_1)
# Create ANN search request 2 for posterVector
query_posterVector = [[0.02550758562349764, 0.006085637357292062, 0.5325251250159071, 0.7676432650114147, 0.5521074424751443]]
search_param_2 = {
"data": query_posterVector, # Query vector
"anns_field": "posterVector", # Vector field name
"param": {
"metric_type": "L2", # This parameter value must be identical to the one used in the collection schema
"params": {"nprobe": 10}
},
"limit": 2 # Number of search results to return in this AnnSearchRequest
}
request_2 = AnnSearchRequest(**search_param_2)
# Store these two requests as a list in `reqs`
reqs = [request_1, request_2]
パラメータ
AnnSearchRequest
(オブジェクト)ANN 検索要求を表すクラス。各ハイブリッド検索は、一度に 1 から 1,024
ANNSearchRequest
オブジェクトを含むことができます。data
(list)単一の
AnnSearchRequest
で検索するクエリーベクター。現在のところ、このパラメータは単一のクエリ・ベクタのみを含むリスト、例えば[[0.5791814851218929, 0.5792985702614121, 0.8480776460143558, 0.16098005945243, 0.2842979317256803]]
を受け付ける。 将来的には、このパラメータは複数のクエリ・ベクタを受け付けるように拡張される予定である。anns_field
(文字列)単一の
AnnSearchRequest
で使用するベクトルフィールドの名前。param
(dict)単一の
AnnSearchRequest
に対する検索パラメータの辞書。これらの検索パラメータは、単一ベクトル検索のパラメータと同じです。詳細については、検索パラメータ を参照してください。limit
(int)一つの
ANNSearchRequest
に含める検索結果の最大数。このパラメータは、個々の
ANNSearchRequest
内で返す検索結果の数にのみ影響し、hybrid_search
呼び出しに対して返す最終結果を決定するものではない。ハイブリッド検索では、最終結果は、複数のANNSearchRequest
インスタンスからの結果を組み合わせ、再ランク付けすることによって決定される。
ステップ2:再ランク付け戦略の設定
AnnSearchRequest
。インスタンスを作成したら、結果を結合して再ランク付けするための再ランク付け戦略を設定する。現在、WeightedRanker
とRRFRanker
の2つのオプションがある。再ランク付け戦略の詳細については、再ランク付けを参照のこと。
重み付きスコアリングを使用する
WeightedRanker
を使用して、各ベクトルフィールドの検索結果に指定した重みで重要度を割り当てます。あるベクター・フィールドを他のベクター・フィールドより優先させる場合、WeightedRanker(value1, value2, ..., valueN)
を使用することで、検索結果の組み合わせにこれを反映させることができます。from pymilvus import WeightedRanker # Use WeightedRanker to combine results with specified weights # Assign weights of 0.8 to text search and 0.2 to image search rerank = WeightedRanker(0.8, 0.2)
WeightedRanker
を使用する場合は、次の点に注意してください:- 各重み値は 0(最も重要でない)から 1(最も重要)まであり、最終的な集計スコアに影響します。
WeightedRanker
で提供されるウェイト値の総数は、作成したAnnSearchRequest
インスタンスの数と同じでなければなりません。
相互ランク融合(RFF)を使用する
# Alternatively, use RRFRanker for reciprocal rank fusion reranking from pymilvus import RRFRanker rerank = RRFRanker()
ステップ3:ハイブリッド検索を実行する
AnnSearchRequest
インスタンスとリランキング戦略を設定したら、hybrid_search()
メソッドを使用してハイブリッド検索を実行します。
# Before conducting hybrid search, load the collection into memory.
collection.load()
res = collection.hybrid_search(
reqs, # List of AnnSearchRequests created in step 1
rerank, # Reranking strategy specified in step 2
limit=2 # Number of final search results to return
)
print(res)
パラメータ
reqs
(リスト)検索リクエストのリスト。各リクエストは
ANNSearchRequest
オブジェクトである。各リクエストは異なるベクトルフィールドと異なる検索パラメータのセットに対応することができる。rerank
(オブジェクト)ハイブリッド検索に使用するリランキング戦略。取り得る値:
WeightedRanker(value1, value2, ..., valueN)
とRRFRanker()
。リランキング戦略の詳細については、リランキングを参照のこと。
limit
(int)ハイブリッド検索で返す最終結果の最大数。
出力は以下のようになります:
["['id: 844, distance: 0.006047376897186041, entity: {}', 'id: 876, distance: 0.006422005593776703, entity: {}']"]
制限
通常、各コレクションには最大4つのベクトル・フィールドがデフォルトで許容されます。しかし、
proxy.maxVectorFieldNum
の設定を調整して、コレクション内のベクターフィールドの最大数を拡張するオプションがあり、コレクションごとに最大10個のベクターフィールドが制限されます。詳細はプロキシ関連の設定を参照。コレクション内のベクトルフィールドに部分的にインデックスが付けられたり、ロードされたりすると、エラーになります。
現在のところ、ハイブリッド検索では、
AnnSearchRequest
、1つのクエリ・ベクタのみを運ぶことができます。
よくある質問
ハイブリッド検索はどのような場合に推奨されますか?
ハイブリッド検索は、高い精度が要求される複雑な状況、特にエンティティが複数の多様なベクトルで表現できる場合に最適です。これは、文章などの同じデータが異なる埋め込みモデルで処理される場合や、マルチモーダル情報(個人の画像、指紋、声紋など)が様々なベクトル形式に変換される場合に当てはまります。これらのベクトルに重みを割り当てることで、それらの複合的な影響力により、検索結果の再現性を大幅に高め、有効性を向上させることができる。
重み付きランカーはどのように異なるベクトルフィールド間の距離を正規化するのですか?
重み付きランカーは、各フィールドに割り当てられた重みを使用して、ベクトルフィールド間の距離を正規化します。重みに従って各ベクトルフィールドの重要度を計算し、重みの大きいものを優先します。一貫性を確保するために、ANN検索リクエスト全体で同じメトリックタイプを使用することをお勧めします。この方法により、より重要であると判断されたベクトルが、全体的なランキングにより大きな影響を与えるようになります。
Cohere Ranker や BGE Ranker のような代替ランカーを使用することはできますか?
現在のところ、提供されているランカーのみがサポートされています。将来のアップデートに向けて、追加のランカーを含める計画が進行中です。
複数のハイブリッド検索を同時に実行することは可能ですか?
はい、複数のハイブリッド検索操作の同時実行はサポートされています。
複数のAnnSearchRequestオブジェクトで同じベクトルフィールドを使用してハイブリッド検索を実行できますか?
技術的には、ハイブリッド検索に複数のAnnSearchRequestオブジェクトで同じベクターフィールドを使用することは可能です。ハイブリッド検索のために複数のベクターフィールドを持つ必要はありません。