メインコンテンツまでスキップ

Large TopK の使用方法

Zilliz Cloud のコレクションでは、検索またはクエリの結果として最大 16,384 件のエンティティを取得できます。topK の上限を超えてさらに多くのエンティティを取得するには、複雑で時間のかかるイテレーターを使用する代わりに、クエリモードを設定して、Zilliz Cloud が 1 回の検索またはクエリの結果に数百万件のエンティティを含められるようにします。

Notes

この機能は、Milvus v2.6.x と互換性のある Zilliz Cloud クラスターで利用できます。この機能を試す場合は、お問い合わせください。

概要​

デフォルトでは、Zilliz Cloud のコレクションは、検索またはクエリ操作で最大 16,384 の topK をサポートします。バッチ類似検索やデータマイニングなどのシナリオで、1 回のリクエストでより多くのエンティティを取得する必要がある場合は、コレクションの query_mode プロパティを large_topk に設定して、Large TopK モードを有効にできます。これにより、topK の上限が 1,000,000(100 万)件のエンティティに引き上げられます。

Large TopK を有効にすると、基盤となるインデックス戦略がデフォルトの Auto インデックス から、RaBitQ のディープ圧縮を備えた IVF(Inverted File インデックス) に変更されます。この戦略は、小規模な K のクエリ性能と引き換えに、高い再現率での大規模範囲検索に最適化されています。

Large TopK を使用する場合​

Large TopK は、1 回の検索で非常に多くの類似エンティティを取得する必要があるシナリオ向けに設計されています。例えば、次のような場合です。

  • バッチ類似検索: 指定したクエリベクトルに対して、最も類似する上位 100,000 件または 1,000,000 件の項目を検索します。

  • データマイニングと分析: 後続の処理、フィルタリング、またはモデルトレーニング用に大規模な候補セットを抽出します。

  • リグレッションテストの準備: 大規模な結果セットを取得し、シミュレーションチーム用のテストコーパスを構築します。

topK が小さい(例: 上位 10 件または上位 100 件)対話型のレイテンシー重視のオンラインクエリには、デフォルトのクエリモードをお勧めします。

前提条件とトレードオフ​

Large TopK を有効にする前に、次のトレードオフに注意してください。

  • 小規模な K の性能低下: large_topk に切り替えると、小規模な K のクエリ(K < 16,384)は、デフォルトモードと比較してレイテンシーが増加し、再現率が低下します。

  • クエリレイテンシー: Large TopK クエリは、標準のクエリよりもレイテンシーが大幅に高くなります。topK が 100,000 の場合は数秒、topK が 1,000,000 の場合は数分かかることがあります。

  • リソース使用量: 1 回の大規模な TopK クエリは、結果の並べ替えに数ギガバイトのメモリを消費する場合があります。Perf クラスターでは、同じクラスターで実行されている他のクエリに影響する可能性があります。

  • オフラインの使用: バッチワークロードには、On-demand Compute データベースの使用を検討してください。データベースはオンデマンドの CU を使用し、オンラインサービスに影響しません。

  • インデックスの再構築が必要: コレクションにすでにベクトルインデックスがある場合は、Large TopK を有効にする前に、既存のインデックスをリリースして削除する必要があります。再構築中は検索を利用できません。

Large TopK を有効にする​

コレクションで Large TopK が必要になることがわかっている場合は、後から切り替えるコストを避けるため、作成時に指定します。

python
from pymilvus import MilvusClient, DataType

client = MilvusClient(uri="your_uri", token="your_token")

schema = client.create_schema(auto_id=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("scenario_id", DataType.VARCHAR, max_length=64)
schema.add_field("title", DataType.VARCHAR, max_length=128)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=4)

index_params = client.prepare_index_params()
index_params.add_index(field_name="vector", index_name="vector_idx", index_type="AUTOINDEX", metric_type="COSINE")

client.create_collection(
collection_name="scenarios_corpus",
schema=schema,
index_params=index_params,
properties={"query_mode": "large_topk"}
)

既存のコレクション​

ベクトルインデックスのない既存のコレクションでは、Large TopK を直接有効にできます。

python
from pymilvus import MilvusClient

client = MilvusClient(uri="your_uri", token="your_token")

# 1. Enable Large TopK
client.alter_collection_properties(
collection_name="scenarios_corpus",
properties={"query_mode": "large_topk"}
)

# 2. Create the vector index and load the collection
index_params = client.prepare_index_params()
index_params.add_index(field_name="vector", index_name="vector_idx", index_type="AUTOINDEX", metric_type="COSINE")
client.create_index(collection_name="scenarios_corpus", index_params=index_params)
client.load_collection(collection_name="scenarios_corpus")

ベクトルインデックスのある既存のコレクションでは、最初にインデックスを削除し、次にモードを有効にして、最後にインデックスを再作成する必要があります。

python
from pymilvus import MilvusClient

client = MilvusClient(uri="your_uri", token="your_token")

# 1. Release and drop the existing index
client.release_collection(collection_name="scenarios_corpus")
client.drop_index(collection_name="scenarios_corpus", index_name="vector_idx")

# 2. Enable Large TopK
client.alter_collection_properties(
collection_name="scenarios_corpus",
properties={"query_mode": "large_topk"}
)

# 3. Recreate the index and load the collection
index_params = client.prepare_index_params()
index_params.add_index(field_name="vector", index_name="vector_idx", index_type="AUTOINDEX", metric_type="COSINE")
client.create_index(collection_name="scenarios_corpus", index_params=index_params)
client.load_collection(collection_name="scenarios_corpus")

現在のクエリモードを確認する​

python
from pymilvus import MilvusClient

client = MilvusClient(uri="your_uri", token="your_token")
info = client.describe_collection(collection_name="scenarios_corpus")
query_mode = info["properties"].get("query_mode") # None means default mode

Large TopK を無効にする​

デフォルトのクエリモードに戻すには、query_mode プロパティを削除します。この場合も、最初に既存のインデックスをリリースして削除する必要があることに注意してください。

python
from pymilvus import MilvusClient

client = MilvusClient(uri="your_uri", token="your_token")

# 1. Release and drop the existing index
client.release_collection(collection_name="scenarios_corpus")
client.drop_index(collection_name="scenarios_corpus", index_name="vector_idx")

# 2. Drop query_mode to return to the default mode
client.drop_collection_properties(
collection_name="scenarios_corpus",
property_keys=["query_mode"]
)

# 3. Recreate the index and load the collection
index_params = client.prepare_index_params()
index_params.add_index(field_name="vector", index_name="vector_idx", index_type="AUTOINDEX", metric_type="COSINE")
client.create_index(collection_name="scenarios_corpus", index_params=index_params)
client.load_collection(collection_name="scenarios_corpus")

Large TopK を有効にしたら、標準の search メソッドで大きな limit 値を使用します。

オンライン検索(Serving クラスター)​

python
from pymilvus import MilvusClient

client = MilvusClient(uri="your_uri", token="your_token")
query_vector = [0.1, 0.2, 0.3, 0.4]

results = client.search(
collection_name="scenarios_serving",
data=[query_vector],
limit=500000
)

オフライン検索(On-demand Compute)​

python
from pymilvus import MilvusClient

client = MilvusClient(uri="your_uri", token="your_token")
query_vector = [0.1, 0.2, 0.3, 0.4]

results = client.search(
collection_name="scenarios_corpus",
data=[query_vector],
limit=500000
)

検索結果をエクスポートする​

Large TopK の結果専用のエクスポート API はありません。既存の機能を組み合わせて、結果を Managed Volume に書き込むことができます。

python
import pyarrow as pa
import pyarrow.parquet as pq

# Configure a Zilliz Cloud Managed Volume client as volume_file_manager.
writer = None
try:
for i, qvec in enumerate(query_vectors):
results = client.search(
collection_name="scenarios_corpus",
data=[qvec],
limit=100000,
output_fields=["scenario_id", "title"]
)

rows = [
{
"query_id": i,
"rank": j,
"scenario_id": hit["entity"].get("scenario_id"),
"title": hit["entity"].get("title")
}
for j, hit in enumerate(results[0])
]
table = pa.Table.from_pylist(rows)

if writer is None:
writer = pq.ParquetWriter("/tmp/results.parquet", table.schema)
writer.write_table(table)
finally:
if writer is not None:
writer.close()

volume_file_manager.upload_file_to_volume(
source_file_path="/tmp/results.parquet",
target_volume_path="results/batch.parquet"
)

パフォーマンスの見積もり​

次の表は、Large TopK クエリのパフォーマンス特性をまとめたものです。

メトリクスデフォルトモードLarge TopK モード
TopK の上限16,3841,000,000
小規模な K のレイテンシーミリ秒高くなる(低下)
大規模な K のレイテンシー非サポート数秒から数分
クエリあたりのメモリ低最大数 GB
同時実行性高制限あり(キューイング)
最適な用途オンラインでの対話バッチ、データマイニング

Zilliz Cloud は、リソースの枯渇を防ぐため、Large TopK クエリに同時実行制御を適用します。同時実行数の上限を超えたリクエストはキューに入り、リソースが利用可能になったときに処理されます。

制限事項​

  • クエリモードを切り替えるには、ベクトルインデックスを再構築する必要があります。再構築中は、コレクションの検索を利用できません。

  • Large TopK はコレクションレベルの設定です。コレクション上のすべてのインデックスが影響を受けます。

  • 3 つのクラスタータイプ(Performance-optimized、Capacity-optimized、Tiered Storage)はすべて Large TopK をサポートします。

FAQ​

Q: 頻繁に切り替えることはできますか?

技術的には可能ですが、お勧めしません。切り替えるたびにインデックスのリリース、削除、再作成が必要になり、その間は検索を利用できません。オンデマンドクラスターでは、再構築のたびに インデックス Build CU の料金も発生します。