Milvus 向量資料庫的相似性搜尋功能為何?
封面圖片
作為核心向量執行引擎,Knowhere之於Milvus就如同引擎之於跑車。本文將介紹Knowhere是什麼,與Faiss有什麼不同,以及Knowhere的程式碼是如何結構化的。
跳到
Knowhere的概念
狹義來說,Knowhere 是一個操作介面,用來存取系統上層的服務,以及系統下層的向量相似性搜尋函式庫,例如Faiss、Hnswlib、Annoy。此外,Knowhere 還負責異質運算。更明顯的是,Knowhere 可以控制使用何種硬體(例如 CPU 或 GPU)來執行索引建立與搜尋的請求。這就是 Knowhere 名字的由來 - 知道在哪裡執行作業。在未來的版本中,還將支援包括 DPU 和 TPU 在內的更多類型的硬體。
在更廣泛的意義上,Knowhere 也整合了其他第三方索引函式庫,例如 Faiss。因此,整體而言,Knowhere 被公認為 Milvus 向量資料庫的核心向量計算引擎。
從 Knowhere 的概念可以看出,它只處理資料運算任務,而像分片、負載平衡、災難恢復等任務都不在 Knowhere 的工作範圍內。
從 Milvus 2.0.1 開始,Knowhere(廣義上的Knowhere)將獨立於 Milvus 專案之外。
Milvus架構中的Knowhere
Knowhere 架構
Milvus 中的計算主要涉及向量和標量操作。Knowhere 只處理 Milvus 中向量的操作。上圖說明了 Milvus 中的 Knowhere 架構。
最底層是系統硬體。第三方索引庫在硬體之上。然後,Knowhere 透過 CGO 與上面的索引節點和查詢節點互動。
本文討論的是廣義上的 Knowhere,也就是架構圖中藍色框內標示的部分。
Knowhere 與 Faiss
Knowhere 不僅進一步擴展了 Faiss 的功能,還優化了性能。具體來說,Knowhere 有以下優點。
1.支援 BitsetView
最初,在 Milvus 中引入 bitset 是為了實現 「軟刪除 」的目的。軟刪除的向量仍然存在於資料庫中,但在向量相似性搜尋或查詢時不會被計算。bitset 中的每個 bit 對應一個索引向量。如果一個向量在 bitset 中被標記為 "1",就表示這個向量是軟刪除的,在向量搜尋時不會涉及。
bitset 參數會加入 Knowhere 中所有外露的 Faiss 索引查詢 API,包括 CPU 和 GPU 索引。
進一步瞭解bitset 如何實現向量搜尋的多功能性。
2.支持更多的相似度指標來索引二進位向量
除了Hamming,Knowhere 還支援Jaccard、Tanimoto、Superstructure、Substructure。Jaccard 和 Tanimoto 可以用來測量兩個樣本集之間的相似度,而 Superstructure 和 Substructure 可以用來測量化學結構的相似度。
3.支援 AVX512 指令集
Faiss 本身支援多種指令集,包括AArch64、SSE4.2、AVX2。Knowhere 進一步擴充支援的指令集,加入AVX512 指令集,相較於 AVX2 指令集,可以提升 20% 到 30% 的索引建立與查詢效能。
4.自動選擇 SIMD 指令
Knowhere 的設計是為了能在各種不同 SIMD 指令 (例如 SIMD SSE、AVX、AVX2 和 AVX512) 的 CPU 處理器 (包括企業內部平台和雲端平台) 上運作良好。因此,我們面臨的挑戰是:給予單一軟體二進位檔 (即 Milvus),如何讓它在任何 CPU 處理器上自動調用適當的 SIMD 指令?Faiss 不支援自動選擇 SIMD 指令,使用者需要在編譯時手動指定 SIMD 標誌 (例如 "-msse4")。然而,Knowhere 是透過重構 Faiss 的程式碼來建立的。依賴 SIMD 加速的常見函數 (例如相似性運算) 會被析出。然後,每個函式都會有四個版本 (即 SSE、AVX、AVX2、AVX512) 來實作,並各自放入獨立的原始碼檔案。然後,這些原始碼檔案再以相對應的 SIMD 標誌單獨編譯。因此,在運行時,Knowhere 可以根據目前的 CPU 標誌自動選擇最適合的 SIMD 指令,然後再使用掛鉤(hooking)連結正確的函式指針。
5.其他效能最佳化
閱讀Milvus: A Purpose-Built Vector Data Management System了解更多關於 Knowhere 的效能優化。
瞭解 Knowhere 程式碼
如第一節所述,Knowhere 只處理向量搜尋操作。因此,Knowhere 只處理實體的向量場(目前,一個集合中的實體只支援一個向量場)。索引建立和向量相似性搜索也是針對段中的向量場。要更好地了解數據模型,請閱讀這裡的博客。
實體欄位
索引
索引是一種獨立於原始向量資料的資料結構。索引需要四個步驟:建立索引、訓練資料、插入資料和建立索引。
對於某些人工智能應用程式而言,資料集訓練是一個獨立於向量搜尋的過程。在這類型的應用程式中,資料集的資料會先經過訓練,然後再插入像 Milvus 之類的向量資料庫中進行相似性搜尋。sift1M 和 sift1B 等開放資料集提供了訓練和測試的資料。然而,在 Knowhere 中,用於訓練和搜尋的資料是混合在一起的。也就是說,Knowhere 會先訓練一個區段中的所有資料,然後再插入所有訓練過的資料,並為它們建立索引。
Knowhere 的代碼結構
DataObj 是 Knowhere 中所有數據結構的基類。Size()
是 DataObj 中唯一的虛方法。Index類別繼承自DataObj,並有一個名為 "size_"的欄位。Index 類也有兩個虛擬方法 -Serialize()
和Load()
。從 Index 派生的 VecIndex 類是所有向量索引的虛擬基類。VecIndex 提供的方法包括Train()
,Query()
,GetStatistics()
, 和ClearStatistics()
。
基類
其他索引類型列於上圖右方。
- Faiss 索引有兩個子類別:FaissBaseIndex 用於浮點向量上的所有索引,而 FaissBaseBinaryIndex 用於二進位向量上的所有索引。
- GPUIndex 是所有 Faiss GPU 索引的基類。
- OffsetBaseIndex 是所有自行開發索引的基類。索引檔案中只會儲存向量 ID。因此,128 維向量的索引檔案大小可以減少 2 個數量級。我們建議在使用這類型的索引進行向量相似性搜尋時,也要考慮到原始向量。
IDMAP
技術上來說,IDMAP並非索引,而是用於暴力搜尋。向量插入向量資料庫時,不需要進行資料訓練和索引建立。搜尋將直接在插入的向量資料上進行。
然而,為了程式碼的一致性,IDMAP 也繼承自 VecIndex 類的所有虛擬介面。IDMAP 的用法與其他索引相同。
IVF
IVF (倒置檔案) 索引是最常使用的索引。IVF 類源自 VecIndex 和 FaissBaseIndex,並進一步延伸至 IVFSQ 和 IVFPQ。GPUIVF 衍生自 GPUIndex 和 IVF。然後 GPUIVF 進一步延伸至 GPUIVFSQ 和 GPUIVFPQ。
IVFSQHybrid 是一個用於自行開發混合索引的類別,在 GPU 上以粗量化的方式執行。而桶中的搜尋則在 CPU 上執行。此類索引可利用 GPU 的運算能力,減少 CPU 與 GPU 之間的記憶體複製次數。IVFSQHybrid 的召回率與 GPUIVFSQ 相同,但效能較佳。
二進位索引的基類結構相對較簡單。BinaryIDMAP 和 BinaryIVF 是從 FaissBaseBinaryIndex 和 VecIndex 衍生出來的。
第三方索引
目前,除了 Faiss 之外,只支援兩種第三方索引:樹狀索引 Annoy 和圖狀索引 HNSW。這兩種常用的第三方索引都是從 VecIndex 衍生出來的。
向Knowhere添加索引
如果你想添加新的索引到Knowhere,你可以先參考現有的索引:
- 要添加基於量化的索引,請參考 IVF_FLAT。
- 要添加基于图形的索引,请参考 HNSW。
- 若要新增樹狀索引,請參考 Annoy。
參考現有索引後,您可以按照以下步驟在 Knowhere 中新增索引。
- 在
IndexEnum
中添加新索引的名稱。資料類型為字串。 - 在文件
ConfAdapter.cpp
中為新索引添加數據驗證檢查。驗證檢查主要是驗證數據訓練和查詢的參數。 - 為新索引建立新檔案。新索引的基類應包括
VecIndex
,以及VecIndex
必要的虛擬介面。 - 在
VecIndexFactory::CreateVecIndex()
中加入新索引的索引建立邏輯。 - 在
unittest
目錄下新增單元測試。
關於 Deep Dive 系列
隨著 Milvus 2.0正式宣布全面上市,我們安排了這個 Milvus Deep Dive 系列部落格,提供對 Milvus 架構和原始碼的深入詮釋。本系列部落格涵蓋的主題包括
- Knowhere的概念
- Milvus架構中的Knowhere
- Knowhere 與 Faiss
- 瞭解 Knowhere 程式碼
- 向Knowhere添加索引
- 關於 Deep Dive 系列
On This Page
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word