解析雲原生數倉 ByteHouse 如何構建高性能向量檢索

隨着 LLM 技術應用及落地,數據庫需要提高向量分析以及 AI 支持能力,向量數據庫及向量檢索等能力 “異軍突起”,迎來業界持續不斷關注。簡單來說,向量檢索技術以及向量數據庫能爲 LLM 提供外置的記憶單元,通過提供與問題及歷史答案相關聯的內容,協助 LLM 返回更準確的答案。

不僅僅是 LLM,向量檢索也早已在 OLAP 引擎中應用,用來提升非結構化數據的分析和檢索能力。ByteHouse 是火山引擎推出的雲原生數據倉庫,近期推出高性能向量檢索能力,本篇將結合 ByteHouse 團隊對向量數據庫行業和技術的前沿觀察,詳細解讀 OLAP 引擎如何建設高性能的向量檢索能力,並最終通過開源軟件 VectorDBBench 測試工具,在 cohere 1M 標準測試數據集上,recall 98 的情況下,QPS 性能已可以超過專用向量數據庫。

向量檢索現狀分析

向量檢索定義

對於諸如圖片、視頻、音頻等非結構化數據,傳統數據庫方式無法進行處理。目前,通用的技術是把非結構化數據通過一系列 embedding 模型將它變成向量化表示,然後將它們存儲到數據庫或者特定格式裏。在搜索過程中,通過相同的一個模型把查詢項轉化成對應的向量,並進行一個近似度的匹配就可以實現對非結構化數據的查詢。

在技術原理層面,向量檢索主要是做一個 K Nearest Neighbors (K 最近鄰,簡稱 KNN) 計算,目標是在 N 個 D 維的向量的庫中找最相似的 k 個結果。

在數據量較大場景,KNN 計算通常代價比較大,很難在較短時間內返回結果,此外,在很多場景,用戶並不需要絕對精確的相似結果。因此,在真正在使用向量檢索時,通常會使用相似最近鄰搜索,即 ANN 的方式來替代 KNN,從 k 個絕對最近似結果變成 K 個近似最優結果,以犧牲一定準確度的前提,得到更短的響應時間。

LLM 與向量檢索

由於大模型的訓練數據有限,在針對一些最近的消息或者特定領域信息的查詢來說,通常結果不準確。爲了提升檢索的準確性,一種比較常見的處理方式是將想搜索的信息的相關文檔進行文本處理,並通過 embedding 模型將向量寫入到向量數據庫裏後,把問題通過相同的 embedding 模型轉化爲向量進行近似度搜索,得到問題的相似知識作爲 prompt,連同問題一起提交給大模型處理,最終得到更準確的答案。

向量檢索的四種算法(索引)

向量檢索算法基於其存儲結構大致可分爲四種。

目前實際場景中,使用較多的方法主要是後面的兩種,即 Cluster-based 和 Graph-based。

如何構建向量數據庫

首先,一個向量數據庫需要具備向量類型數據和向量索引的存儲與管理相關功能,包括增刪改查等數據維護功能,另外,對於向量檢索性能通常要求比較高。其次,向量檢索通常需要與屬性過濾等操作結合計算。最後,向量檢索通常會與其他屬性結合查詢,比如以圖搜圖等場景,最終需要的,是相似的圖片路徑或文件。

構建向量數據庫時,一種思路是以向量爲中心,從底向上構建一個專用的向量數據庫,這樣的特點是,可以針對向量檢索做特定的優化,能夠保證較高的性能,缺點爲缺乏複雜的數據管理和查詢能力,通常需要結合其他數據庫來使用。

另一種設計思路是基於現有的數據庫和數據引擎增加向量檢索相關擴展功能。優勢是可以做到 all in one 的數據管理和查詢支持,缺點爲受現有架構的限制,很難做到較高的檢索性能。

向量數據庫的當前進展

向量數據庫目前還處於一個快速發展的階段,目前看有兩個趨勢,一個是以專用向量數據庫爲基礎,不斷添加更多複雜的數據類型支持以及更多的數據管理機制,比如存算分離、一致性支持、實時導入等。此外,查詢上也在不斷添加前後置過濾等複雜查詢策略的支持。

第二種構建思路是數據庫加向量檢索擴展,繼續去支持更多的向量檢索算法,並且不斷按照向量檢索的需求,添加特殊的過濾策略、簡化對應的執行計劃。

以上兩種構建思路都在向一個統一的目標去匯合,即帶有高性能向量檢索,與完備數據管理和查詢支持的數據庫形態。這也是 ByteHouse 在設計向量檢索相關功能時,主要考慮的一個目標。

ByteHouse 的高性能向量檢索方案

ByteHouse 是火山引擎研發的雲原生數據倉庫產品,在開源 ClickHouse 引擎之上做了技術架構重構,實現了雲原生環境的部署和運維管理、存儲計算分離、多租戶管理等功能。在可擴展性、穩定性、可運維性、性能以及資源利用率方面都有巨大的提升。

此外,ByteHouse 還支持了向量檢索、全文檢索、地理空間數據檢索等功能。

ByteHouse 作爲一款高性能向量數據庫的底座的優勢在於,其具備比較完備的 SQL 語法支持,高性能的計算引擎,以及比較完備的數據管理機制和豐富的數據表引擎,能夠支持不同場景。

爲了達到更高的向量檢索性能,ByteHouse 基於向量爲中心的設計思路,構建了一條高效的向量檢索的執行路徑,同時,引入了多種常用的向量檢索算法,以滿足不同場景的向量檢索需求。

設計方案

主要設計思路

基本使用方式

實際使用時,在建表時可以加一個 Index 的定義,包含索引名稱、向量列、以及索引類型信息。

數據導入支持多種方式,比如基於 Kafka 的實時導入,insert file,python SDK 等。

基本查詢是一個定式:select 需要的列信息,增加一個 order by + limit 的指令。查詢支持與標量信息結合的混合查詢,以及針對 distance 的 range 查詢。

遇到的挑戰

在添加高性能向量檢索功能過程中,ByteHouse 主要克服以下三大難點:

讀放大問題

根本原因:ByteHouse 中,當前最小的讀取單元是一個 mark,即便通過 Vector Index 查詢得到結果是有行號信息的,但是在真正讀取的時候仍需要轉成對應的 mark id 傳給下層存儲層讀取。

優化:

  1. 把向量檢索的計算進行了前置處理。

最初的設計中,向量檢索計算時需要每個 data part 首先做 Vector Search 加上其他列信息的讀取,然後再去做後面的 order by + limit 得到最終的結果。這種做法相當於每個 data part 要取 top k,它的讀取的行數是 part 數量乘以 mark_size 乘以 top k。這裏做的優化是將 Vector Search 計算前置,上推到 data part 的讀取之前,首先執行所有 data part 的 Vector Search,獲取全局的 topK 個結果,再分配到各個 data part 去做 read。這樣可以實現 IO 從百萬減到千的級別的降低,實際使用中整體性能實現了兩倍以上的提升。

  1. 存儲層的過濾。

把 row level 的查詢結果往下推到存儲層讀 mark 的位置進行一些過濾,減少了反序列化的開銷。

  1. 在 filter by range 場景進行優化。

基於主鍵查找如按天查找或者按 label 查找等場景,只對首尾 mark 進行了一個讀取和過濾,降低過濾語句的執行開銷。

構建資源消耗大

根本原因:相比於其他比較簡單的索引,如 MinMax 等,向量索引構建時間更長,並且消耗資源更多。

優化:

  1. 在 Build Threads 和 Background Merge Tasks 做了併發限制。

  2. 構建過程中內存使用優化,把一些完全在內存裏面進行的計算做成了 Disk-based,增加了 memory buffer 的機制。此優化主要是對 IVF 類型的索引進行的。

冷讀問題

原因:使用索引需要 Index 結構載入內存,載入到內存後才能進行一些檢索加速。

優化:

加入 Cache Preload 支持。在服務啓動和數據寫入以及後臺數據 merge 的場景可以自動地把新的 index load 到內存。另外,自動的 GC 會把 Cache 中過期數據自動回收。

最終效果

ByteHouse 團隊基於業界最新的 VectorDBBench 測試工具進行測試,在 cohere 1M 標準測試數據集上,recall 98 的情況下,可以達到與專用向量數據庫同等水平的性能。在 recall 95 以上的情況下,QPS 可以達到 2600 以上,p99 時延在 15ms 左右,具備業界領先優勢。

性能評測

不同索引評測

評測對象:IVFPQFS+Refine(SQ8) 和 HNSW。

IVFPQFS+Refine(SQ8) 優點:

痛點:

很難在高精度的場景下替換 HNSW

未來計劃

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/IrrXGT4u4ttUGZKvtGiwdQ