HNSW
HNSW索引是一種基於圖的索引演算法,可以提高搜尋高維浮動向量時的效能。它具有優異的搜尋準確性和低延遲,但需要較高的記憶體開銷來維持其階層圖結構。
概述
Hierarchical Navigable Small World (HNSW) 演算法會建立多層圖形,有點像是有不同縮放程度的地圖。底層包含所有資料點,上層則由從底層取樣的資料點子集組成。
在這個層級架構中,每層都包含代表資料點的節點,這些節點由表示其接近程度的邊連接。上層提供長距離跳躍以快速接近目標,而下層則可進行細粒度搜尋以獲得最精確的結果。
以下是它的運作方式:
- 入口點:搜尋始於頂層的固定入口點,也就是圖形中的預定節點。
- 貪婪搜尋:演算法貪婪地移動到目前層的最近鄰居,直到無法再接近查詢向量為止。上層發揮導航作用,扮演粗略過濾器的角色,為下層的精細搜尋找出潛在入口點。
- 層級下降:一旦當前層達到局部最小值,演算法就會跳到下層,使用預先建立的連線,並重複貪婪搜尋。
- 最終 精煉:此過程會持續到達最底層為止,在最底層會有最後的精煉步驟找出最近的鄰居。
HNSW
HNSW 的效能取決於幾個控制圖形結構和搜尋行為的關鍵參數。這些參數包括
M
:每個節點在階層結構的每一層圖中所能擁有的最大邊緣或連線數。M
越高,圖形就越密集,並且會增加回復率和精確度,因為搜尋有更多路徑可以探索,這也會消耗更多的記憶體,並且會因為額外的連線而減慢插入時間。如上圖所示,M = 5表示 HNSW 圖中的每個節點最多與其他 5 個節點直接連接。這創造了一個中度密集的圖結構,其中節點有多條路徑可以到達其他節點。efConstruction
:索引建構時所考慮的候選數。較高的efConstruction
通常會產生品質較佳的圖形,但需要較多時間來建立。ef
:搜尋過程中評估的鄰居數量。增加ef
可提高找到最近鄰居的可能性,但會減慢搜尋過程。
有關如何調整這些設定以符合您需求的詳細資訊,請參閱索引參數。
建立索引
要在 Milvus 的向量場上建立HNSW
索引,請使用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="HNSW", # 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={
"M": 64, # Maximum number of neighbors each node can connect to in the graph
"efConstruction": 100 # Number of candidate neighbors considered for connection during index construction
} # Index building params
)
在此設定中
index_type
:要建立的索引類型。在本範例中,設定值為HNSW
。metric_type
:用來計算向量間距離的方法。支援的值包括COSINE
,L2
, 和IP
。如需詳細資訊,請參閱公制類型。params
:建立索引的附加設定選項。M
:每個節點可以連線的最大鄰居數量。efConstruction
:索引建構期間考慮連接的候選鄰居數量。
若要瞭解
HNSW
索引可用的更多建置參數,請參閱索引建置參數。
索引參數設定完成後,您可以直接使用create_index()
方法或在create_collection
方法中傳入索引參數來建立索引。如需詳細資訊,請參閱建立集合。
在索引上搜尋
索引建立且實體插入後,您就可以在索引上執行相似性搜尋。
search_params = {
"params": {
"ef": 10, # Number of neighbors to consider during the search
}
}
res = MilvusClient.search(
collection_name="your_collection_name", # Collection 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
:在索引上搜尋的其他設定選項。ef
:搜尋時要考慮的鄰居數。
若要瞭解
HNSW
索引可用的更多搜尋參數,請參閱特定於索引的搜尋參數。
索引參數
本節概述用於建立索引和在索引上執行搜尋的參數。
索引建立參數
下表列出了建立索引時可在params
中設定的參數。
參數 | 說明 | 值範圍 | 調整建議 |
---|---|---|---|
M | 每個節點在圖表中可擁有的最大連線(或邊緣)數量,包括傳出和傳入的邊緣。 此參數直接影響索引建構和搜尋。 | 類型:整數 範圍:[2, 2048] 預設值: 30 (每個節點最多可有 30 條出邊和 30 條入邊) | 較大的M 通常會帶來較高的精確度,但會增加記憶體開銷,並減慢索引建立和搜尋的速度。對於高維度的資料集或高召回率非常重要時,請考慮增加 M 。如果記憶體佔用量和搜尋速度是主要考量,則考慮降低 M 。在大多數情況下,我們建議您在此範圍內設定一個值:[5, 100]. |
efConstruction | 索引建構期間考慮連接的候選鄰居數量。 每個新元素都會評估更多的候選鄰居,但實際建立的最大連線數仍受限於 M 。 | 類型:整數 範圍:[1,int_max] 預設值: 360 | 較高的efConstruction 通常會產生更精確的索引,因為會探索更多的潛在連線。不過,這也會導致建立索引的時間變長,並增加建構過程中的記憶體使用量。考慮增加 efConstruction 以提高精確度,尤其是在索引時間不太重要的情況下。在資源有限的情況下,可考慮降低 efConstruction ,以加快索引建置速度。在大多數情況下,我們建議您設定此範圍內的值:[50, 500]. |
特定於索引的搜尋參數
下表列出在索引上搜尋時,可在search_params.params
中設定的參數。
參數 | 說明 | 值範圍 | 調整建議 |
---|---|---|---|
ef | 控制最近鄰檢索時的搜尋範圍。它決定要造訪多少節點,並將其評估為潛在最近鄰居。此參數僅影響搜尋過程,且僅適用於圖的底層。 | 類型:整數 範圍:[1、int_max] 預設值:limit(要回傳的 TopK 最近鄰居) | 較大的ef 通常會導致較高的搜尋準確度,因為會考慮更多的潛在鄰居。不過,這也會增加搜尋時間。當達到高召回率是關鍵,而搜尋速度較不重要時,請考慮增加 ef 。考慮降低 ef 以優先加快搜尋速度,尤其是在可以接受稍微降低精確度的情況下。在大多數情況下,我們建議您設定此範圍內的值:[K, 10K]。 |