SCANN

Milvus 中的SCANN 索引由 Google 的ScaNN函式庫支援,專為解決向量相似性搜尋的擴充挑戰而設計,在速度與精確度之間取得平衡,即使在傳統上會對大多數搜尋演算法構成挑戰的大型資料集上也是如此。

概述

ScaNN 旨在解決向量搜尋的最大挑戰之一:即使資料集越來越大、越來越複雜,仍能在高維空間中有效率地找到最相關的向量。其架構將向量搜尋過程分為不同的階段:

Scann 掃描

  1. 分割:將資料集分割成群組。這種方法只會集中在相關的資料子集,而不會掃描整個資料集,因此可以縮小搜尋空間,節省時間和處理資源。ScaNN 通常使用聚類演算法 (例如k-means) 來識別叢集,這可讓它更有效率地執行相似性搜尋。

  2. 量化:ScaNN 在分割後會應用一種稱為異向向量量化的量化程序。傳統的量化著重於最小化原始向量與壓縮向量之間的整體距離,這對於最大內乘積搜尋 (Maximum Inner Product Search, MIPS) 等任務並不理想,因為在這些任務中,相似性是由向量的內乘積而非直接距離決定的。各向異性量化會優先保留向量之間的平行分量,或對計算精確內乘最重要的部分。此方法可讓 ScaNN 謹慎地將壓縮向量與查詢對齊,以維持高 MIPS 精確度,從而實現更快速、更精確的類似性搜尋。

  3. 重新排序:重新排序階段是最後一步,ScaNN 在此階段會微調分割與量化階段的搜尋結果。重新排序會將精確的內積計算應用於頂部的候選向量,確保最終結果高度精確。重新排序在高速推薦引擎或圖片搜尋應用中至關重要,在這些應用中,最初的篩選和聚類可作為粗略的層次,而最後的階段則可確保只向使用者傳回最相關的結果。

SCANN 的效能由兩個關鍵參數控制,讓您可以微調速度與精確度之間的平衡:

  • with_raw_data:控制原始向量資料是否與量化表示同時儲存。啟用此參數可提高重新排序時的精確度,但會增加儲存需求。

  • reorder_k:決定在最後重新排序階段精煉多少候選人。較高的值會提高精確度,但會增加搜尋延遲。

如需針對您的特定使用個案最佳化這些參數的詳細指引,請參閱索引參數

建立索引

要在 Milvus 的向量場上建立SCANN 索引,請使用add_index() 方法,指定index_type,metric_type, 以及索引的其他參數。

from pymilvus import MilvusClient

# Prepare index building params
index_params = MilvusClient.prepare_index_params()

index_params.add_index(
    field_name="your_vector_field_name", # Name of the vector field to be indexed
    index_type="SCANN", # Type of the index to create
    index_name="vector_index", # Name of the index to create
    metric_type="L2", # Metric type used to measure similarity
    params={
        "with_raw_data": True, # Whether to hold raw data
    } # Index building params
)

在此設定中

  • index_type:要建立的索引類型。在本範例中,設定值為SCANN

  • metric_type:用來計算向量間距離的方法。支援的值包括COSINE,L2, 和IP 。如需詳細資訊,請參閱公制類型

  • params:建立索引的附加設定選項。

    • with_raw_data:是否將原始向量資料與量化表示同時儲存。

    要瞭解SCANN 索引可用的更多建立參數,請參閱索引建立參數

索引參數設定完成後,您可以直接使用create_index() 方法或在create_collection 方法中傳入索引參數,以建立索引。如需詳細資訊,請參閱建立集合

在索引上搜尋

索引建立且實體插入後,您就可以在索引上執行相似性搜尋。

search_params = {
    "params": {
        "reorder_k": 10, # Number of candidates to refine
        "nprobe": 8 # Number of clusters to search
    }
}

res = MilvusClient.search(
    collection_name="your_collection_name", # Collection name
    anns_field="vector_field", # Vector field name
    data=[[0.1, 0.2, 0.3, 0.4, 0.5]],  # Query vector
    limit=10,  # TopK results to return
    search_params=search_params
)

在此配置中

  • params:在索引上搜尋的其他設定選項。

    • reorder_k:在重新排序階段要精煉的候選數。
    • nprobe:要搜尋的叢集數。

    要瞭解SCANN 索引可用的更多搜尋參數,請參閱特定於索引的搜尋參數。

索引參數

本節概述用於建立索引和在索引上執行搜尋的參數。

索引建立參數

下表列出了建立索引時可在params 中設定的參數。

參數

說明

值範圍

調整建議

nlist

群集單位數量

[1, 65536]

較高的nlist會增加剪枝效率,通常會加速粗搜尋,但分區可能會變得太小,這可能會降低召回率;較低的nlist會掃描較大的叢集,提高召回率,但會減慢搜尋速度。

with_raw_data

是否將原始向量資料與量化表示同時儲存。啟用時,可在重新排序階段使用原始向量而非量化近似值來進行更精確的相似度計算。

類型:布林

範圍: true,false

預設值true

設定為true ,以獲得更高的搜尋準確度,且儲存空間並非主要考量。原始向量資料可在重新排序時進行更精確的相似度計算。

設定為false減少儲存開銷和記憶體使用量,尤其是大型資料集。不過,這可能會導致搜尋準確度稍微降低,因為重新排序階段會使用量化向量。

建議使用:對於精確度要求極高的生產應用程式,請使用true

特定於索引的搜尋參數

下表列出在索引上搜尋時,可在search_params.params 中設定的參數。

參數

說明

值範圍

調整建議

reorder_k

控制在重新排序階段精煉的候選向量數量。此參數決定使用更精確的相似度計算,重新評估初始分割和量化階段的頂尖候選向量數量。

類型:整數

範圍:[1、int_max]

預設值:無

較大的reorder_k 通常會帶來較高的搜尋準確度,因為在最後的精煉階段會考慮更多的候選人。不過,這也會因為額外的計算而增加搜尋時間

當達到高召回率是關鍵,而搜尋速度較不重要時,請考慮增加reorder_k 。一個好的起點是 2-5 倍您所期望的limit (返回的 TopK 結果)。

考慮降低reorder_k 以優先加快搜尋速度,尤其是在可以接受精確度稍微降低的情況下。

在大多數情況下,我們建議您設定此範圍內的值:[limit,limit* 5].

nprobe

搜尋候選人的叢集數。

類型:整數

範圍:[1、nlist]

預設值8

較高的值允許搜尋更多的叢集,藉由擴大搜尋範圍來改善召回率,但代價是增加查詢延遲。

請依nlist 的比例設定nprobe ,以平衡速度與精確度。

在大多數情況下,我們建議您設定此範圍內的值:[1, nlist]。

免費嘗試托管的 Milvus

Zilliz Cloud 無縫接入,由 Milvus 提供動力,速度提升 10 倍。

開始使用
反饋

這個頁面有幫助嗎?