經過長時間緊鑼密鼓的開發,AI 原生數據庫 Infinity 已于2023年12月21日正式開源了。AI 原生數據庫,定義為專門服務大模型的數據庫,其具體場景即為 RAG(Retrieval Augmented Generation)。未來企業大模型應用架構的基礎設施層面,將只需要一個 AI 原生數據庫配合一個大模型(當下是 LLM 大語言模型,未來還會有多模態模型),就可以完全滿足企業對于 AI 場景的主要需求,包括 Copilot、搜索、推薦、對話機器人等。來自企業內部的各種數據,比如文檔、普通數據庫(包括 OLTP 和 OLAP 等)、API、日志,還有非結構化數據,都可以集成進一個 AI 原生數據庫;AI 原生數據庫將業務查詢得到的數據交給大模型,再由大模型生成最終結果返回給具體應用。
向量無法單獨解決企業 AI 應用的落地
? ? ? 也許你會有這樣的疑問:AI 原生數據庫究竟是什么?它不過是向量數據庫的新瓶裝舊酒嗎?當然不是!AI 原生數據庫不同于向量數據庫,向量只是大模型配套基礎設施的必要而非充分條件。這是因為向量只能提供語義召回能力,無法提供精確查詢能力,而后者恰恰是企業 AI 應用的核心需求。
? ? ? 舉例來說,根據權限表過濾出具備相應訪問權限的內容,這樣一個簡單卻常見的需求,就無法單獨靠向量實現。當然,當下流行的向量數據庫已經具備了簡單的過濾功能,似乎也可以服務這樣的場景。但這就需要通過 ETL(Extract-Transform-Load)工作,把權限字段寫到向量數據庫的標量字段來提供過濾,這意味著三件事:
1. 需要為簡單的需求引入高成本的 ETL。
2. 原始數據的更新不能及時體現到業務。
3. 引入不必要的數據膨脹。權限過濾僅僅是一個例子。如果完全依賴 ETL 解決來自不同數據源的其他各種查詢,那相當于在向量數據庫內保存一張帶有全部過濾字段的寬表。除了上述的系統維護和數據更新問題之外,這也是一種不必要的數據膨脹。在大多數情況下,企業數字化系統架構內只有離線場景的數據倉庫才有引入寬表的必要。
? ? ? 再比如,基于 RAG 的應用大多數都需要具備精確召回能力。舉例來講,當用戶針對 PDF 文檔內某張表格內的內容進行提問時,僅僅依賴向量是無法提供準確回答的,這就會導致由 LLM 返回的答案包含幻覺。所以,只有依靠搜索引擎才能實現精確召回。
? ? ? 因此,配套 AI 的基礎設施,其實是伴隨了三代的演進:
第一代,以統計模型和數據挖掘為基礎,基礎設施的配套代表就是搜索引擎。因此配套的企業 AI 應用架構,往往是以 Elasticsearch,再加上 MySQL 等數據庫共同支撐業務體系。
第二代,深度學習催生了向量搜索的需求,也催生了向量數據庫這個品類。由于向量數據庫僅僅提供單一的向量搜索能力,在構建企業信息系統時,還需要搭配各類數據庫、數據倉庫等,形成所謂的 AI 中臺。
第三代,AI 進化到大模型之后解鎖了更多場景。因此,它需要的不再是一款單純的向量數據庫,而是能夠同時提供向量搜索、全文搜索和結構化數據檢索,可以支撐大模型對于復雜數據的獲取需求,能夠配合大模型共同支撐起企業門戶業務需求的基礎軟件產品。
傳統數據庫/湖倉加向量插件?
????????比如,傳統的關系型數據庫 PostgreSQL 就提供了 pgvector 插件,可以輕輕松松具備向量能力。但是,AI 原生數據庫并不能通過傳統數據庫增加向量搜索能力來得到。下面,我們就先來看看 PostgreSQL 能否解決 AI 的 RAG 場景下的幾個基本問題,相信讀者很快也可以自行得出答案:
????????如何實現精確召回所需的全文搜索能力?
????????PostgreSQL 是一款 OLTP 數據庫,OLTP 的核心設計目標是確保數據寫入的 ACID,而這跟向量和全文搜索都不相關。盡管 PostgreSQL 有全文搜索的功能,而且已經存在十多年了,為何至今企業仍然采用 Elasticsearch 而不是 PostgreSQL 進行全文搜索呢?這是因為 PostgreSQL 的全文搜索只適合小數據規模的簡易搜索。一款搭配 RAG 的 AI 原生數據庫需要勝任各種數據規模,進行可定制的相關度排序,尤其還需要與向量進行多路召回的融合排序,這些都是PostgreSQL沒有辦法勝任的。
????????如何兼顧伸縮性、成本等因素?
????????PostgreSQL 是個單機數據庫,要提供分布式場景下的各種一致性約束,目前主流是采取 Share-nothing 方式的分庫分表來解決伸縮性問題。而向量搜索和全文搜索,則是完全不同的約束條件和性能優化目標,完全沒有必要采用這些復雜的技術來解決伸縮性問題。因此,讓一款 OLTP 數據庫順道做一些事情,并非不可以,但兼職做,就一定沒有專職做得好,當前的大模型時代需要的是一款專業數據庫,而非傳統數據庫加插件的縫縫補補。
? ? ? ? 另一類工作是在數倉上為添加向量搜索能力。這類工作具備一定的合理性,但設計目標依然是有沖突的。數據倉庫,傳統上來說,是服務離線場景的,例如運行一個復雜的 SQL,跑幾十分鐘,乃至幾個小時之后,給出報表,然后給公司內部看。盡管數據倉庫從技術路線上有實時數倉的概念,但它們從使用場景上來講,并非在線場景,因此并不強調并發??墒窍蛄克阉鳎盏乃阉鳎扑],對話機器人,都是高并發的在線業務場景,因此把強調高并發的向量,跟強調高吞吐卻低并發的數倉結合在一起,這在場景上是割裂的。
? ? ? 因此,正如下面這個圖的藍色框內所示,Infinity 是一款結合 AI 基礎設施和 Data 基礎設施的產品,它面向的是在線場景,滿足未來大模型對企業內部數據基礎設施的一切需求:
Infinity 的系統架構
如上圖所示,Infinity 包含存儲層和計算層兩大模塊:
存儲層:
????????列存(columnar storage):Infinity 的默認存儲是一個列存引擎,主要服務于結構化數據檢索,且它可以保證數據存儲的 ACID。
????????ANN 索引(Approximate Nearest Neighbor Index):即向量索引,用于服務向量搜索。Infinity 目前提供 IVF 和 內存優化的HNSW 兩類索引:前者服務內存受限場景,后者服務高性能場景。Infinity 的 HNSW 索引采用了局部量化技術,可以在內存占用相較標準HNSW算法小的多情況下,提供遠高于其他向量索引的搜索性能。此外,ANN 索引僅僅是針對 Infinity 表的一個向量類型列構建的索引,因此 從設計機理上Infinity 可以包含任意多的向量列,而非普通向量數據庫只能提供單一向量列的能力,因此 Infinity可以很容易支持多向量查詢。
????????倒排索引(Inverted Index):用于服務全文檢索以及結構化數據檢索。倒排索引包含兩部分:一部分是針對文本類型的全文索引,默認提供基于 BM25 的相關度排序功能,也提供短語查詢等常見的精確召回能力;另一部分是針對結構化數據的次級索引,提供高性能過濾能力。
計算層:
????????Parser:為了方便 AI 開發者,Infinity 主要對外提供的是 Pythonic API。此外,Infininty還提供兼容 PostgreSQL 協議的 SQL 方言。因此,Infinity 使用全新實現的 Parser 來提供對這兩種方言的支持。
????????執行器:Infinity 針對不同類型的數據,不同的數據分布,提供了多種多樣的索引。它能夠根據查詢需求動態的決定分配哪些資源哪種存儲提供哪些查詢。例如,對于結構化查詢能力來說,可以選擇列存,也可以選擇倒排索引。如果用戶對延遲敏感,則可以使用多個計算單元,采用并行查詢的執行邏輯;如果用戶對并發敏感,就只采用單個計算單元,采用基于倒排索引的方式來執行,Infinity 的執行器會根據需要動態作出最優選擇。具體來說,Infinity 采用了基于 Push 的流水線執行計劃,但更進一步地改進使之同時能適應大吞吐查詢和大并發查詢的工作負載。除此之外,Infinity 還實現了一些重要的算子,例如 Fusion 融合算子,它負責多路召回——采用向量搜索返回的數據,跟采用全文搜索返回的數據,還有結構化過濾的數據,它們之間如何選擇,如何排序,在 Infinity 內部處理完畢這個算子,既高效又便捷,避免了在多個數據庫之間進行聯邦搜索(Federated Search)造成的低效甚至結果錯誤。
Infinity 提供業界最優的向量搜索性能
?? ? Infinity 采用 C++ 20 標準開發,確保了最優的執行路徑,在各種創新算法的共同加持下,Infinity 在向量搜索性能上超越了所有已知向量數據庫,在八核的機器和百萬 SIFT 向量數據集上,高并發場景下 Infinity? 可以輕松達到 1 萬QPS,單個客戶端場景下查詢響應延遲則是 0.1 毫秒級,且內存占用小。
? ? ? 此外,Infinity 還引入了 C++ Modules 提高開發效率,是最先采用 C++ Modules 的大型開源項目。這使得在普通個人筆記本上編譯 Infinity 二十萬行代碼及其依賴的上百萬行 C++ 代碼的時間減少到數分鐘。極大節約了傳統 C++ 程序員因修改一行頭文件,動輒要重新編譯數百個文件,耗時十幾分鐘的痛點。最后,歡迎大家一起加入 Infinity 開源社區貢獻代碼,為 Infinity 早日 GA 添磚加瓦。