不論是RAG,還是Agent,幾乎每個LLM 驅動的應用程序都可能會用到向量數據庫。那么,向量數據庫是什么?與傳統數據庫有何不同? 又如何選擇向量數據庫呢? 本文是老碼農關于向量數據庫的學習筆記。
1. 什么是向量數據庫?
首先,我們需要理解什么是向量?
向量是基于不同特征或屬性來描述對象的數據表示。每個向量代表一個單獨的數據點,例如一個詞或一張圖片,由描述其許多特性的值的集合組成。這些變量有時被稱為“特征”或“維度”。例如,一張圖片可以表示為像素值的向量,整個句子也可以表示為單詞嵌入的向量。
一些常用的數據向量如下:
- 圖像向量,通過深度學習模型提取的圖像特征向量,這些特征向量捕捉了圖像的重要信息,如顏色、形狀、紋理等,可以用于圖像識別、檢索等任務;
- 文本向量,通過詞嵌入技術如Word2Vec、BERT等生成的文本特征向量,這些向量包含了文本的語義信息,可以用于文本分類、情感分析等任務;
- 語音向量,通過聲學模型從聲音信號中提取的特征向量,這些向量捕捉了聲音的重要特性,如音調、節奏、音色等,可以用于語音識別、聲紋識別等任務。
向量數據庫是一種將數據存儲為高維向量的數據庫,高維向量是特征或屬性的數學表示。每個向量都有一定數量的維度,根據數據的復雜性和粒度,維度可以從幾十到幾千不等。向量通常是通過對原始數據(如文本、圖像、音頻、視頻等)應用某種變換或嵌入函數來生成的。嵌入函數可以基于各種方法,例如機器學習模型、單詞嵌入、特征提取算法。向量數據庫采用索引策略來簡化向量相似的特定查詢。這在機器學習應用程序中特別有用,因為相似性搜索經常用于發現可比較的數據點或生成建議。
圖片
向量數據庫的主要功能包括:
- 管理:向量數據庫以原始數據形式處理數據,能夠有效地組織和管理數據,便于AI模型應用。
- 存儲:能夠存儲向量數據,包括各種AI模型需要使用到的高維數據。
- 檢索:向量數據庫特別擅長高效地檢索數據,這一個特點能夠確保AI模型在需要的時候快速獲得所需的數據。這也是向量數據庫能夠在一些推薦系統或者檢索系統中得到應用的重要原因。
向量數據庫的主要優點是,它允許基于數據的向量距離或相似性進行快速準確的相似性搜索和檢索。這意味著,可以使用向量數據庫,根據其語義或上下文含義查找最相似或最相關的數據,而不是使用基于精確匹配或預定義標準查詢數據庫的傳統方法。向量數據庫可以搜索非結構化數據,但也可以處理半結構化甚至結構化數據。例如,可以使用向量數據庫執行以下操作,根據視覺內容和風格查找與給定圖像相似的圖像,根據主題和情感查找與給定文檔相似的文檔,以及根據功能和評級查找與給定產品相似的產品。
2. 向量數據庫的工作機理
向量數據庫的構建是為了適應向量嵌入的特定結構,并且它們使用索引算法根據向量與查詢向量的相似性來有效地搜索和檢索向量。
向量數據庫的工作原理可以通過CPU和GPU的工作原理進行類比。CPU和GPU分別是計算機的運算和圖形處理核心,而向量數據庫則是大模型的記憶和存儲核心。在大模型學習階段,向量數據庫接收多模態數據進行向量化表示,讓大模型在訓練時能夠更高效地調用和處理數據。通過多線程機制和矩陣運算,GPU提供了強大的計算能力,讓大模型的訓練變得更加快速和高效。
區別于傳統數據庫,向量數據庫主要有三點不同:數據向量化,向量檢索和相似度計算。數據的向量化采用embedding 技術, 嵌入作為一個橋梁,將非數字數據轉換為機器學習模型可以使用的形式,使它們能夠更有效地識別數據中的模式和關系。一般的,文本是一維向量,圖像是二維矩陣,視頻相當于三維矩陣。這些嵌入實質上是存儲數據的上下文表示的數字列表(即向量)。在存儲層內,數據庫以m個向量堆棧的形式存儲,每個向量使用n個維度表示一個數據點,總大小為m×n。為了查詢性能的原因,這些堆棧通常通過分片進行劃分。
向量檢索是輸入一個向量,從數據庫中查找與輸入向量最相似的topN個向量返回。要在向量數據庫中執行相似性搜索和檢索,需要使用表示所需信息或條件的查詢向量。查詢向量可以從與存儲向量相同類型的數據導出,或者從不同類型的數據導出。使用相似性度量來計算兩個向量在向量空間中的距離。相似性度量可以基于各種度量,如余弦相似性、歐氏距離、向量內積,hamming距離、jaccard指數。
其中,向量檢索算法是向量數據庫的核心之一。向量檢索可以看為是近似最近鄰搜索,通過預先的索引構建來減小數據查詢時的搜索空間,加快檢索速度。目前主要的幾種檢索算法有:
- 基于樹的方法,例如KDTree和Annoy
- 基于圖的方法,例如HNSW
- 基于乘積量化的方法,例如SQ和PQ
- 基于哈希的方法,例如LSH
- 基于倒排索引的方法
向量數據庫中的索引可以按照數據結構和壓縮級別兩個層次進行組織實現。根據數據結構建立索引的分類如下:
圖片
根據數據壓縮方式建立索引, 主要包括平坦壓縮和量化壓縮。平坦壓縮是指以未經修改的形式存儲向量的索引,量化中索引的底層向量被分解成由較少字節組成的塊(通常通過將浮點數轉換為整數)以減少內存消耗和搜索過程中的計算成本。
圖片
相似性搜索和檢索的結果通常是與查詢向量具有最高相似性得分的向量的排序列表。然后,您可以訪問與原始源或索引中的每個向量關聯的相應原始數據。
3. 向量數據庫的分類
根據向量數據庫的的實現方式, 我們可以將向量數據庫大致分為4類:原生的向量數據庫、支持向量的全文檢索數據庫、支持向量的NoSQL數據庫和支持向量的關系型數據庫。
3.1 原生的向量數據庫
原生的向量數據庫是專門為存儲和檢索向量而設計的。包括Chroma, LanceDB, Marqo, Milvus/ Zilliz, Pinecone, Qdrant, Vald, Vespa, Weaviate等, 所管理的數據是基于對象或數據點的向量表示進行組織和索引。這里只介紹其中的三種,具體信息可以參考各自的官網。
Faiss
Faiss是一個用于高效相似性搜索和密集向量聚類的開源庫。Faiss是用C++編寫的,帶有完整的Python/numpy包裝器,一些常用算法都有GPU實現,成為了很多開源向量數據庫的基礎。
圖片
Faiss能構建不同的索引類型,并提供了歐式距離或者點積的相似度計算功能,有些索引類型是簡單的基線,例如精確搜索。大多數可用的索引結構需要考慮搜索時間,搜索質量,每個索引向量使用的內存等。
Faiss支持多種向量搜索技術,提供了能夠在不同大小的向量集中搜索的算法,甚至可以處理那些超過內存容量的向量集。
Faiss的主要優勢之一是速度和可擴展性,即使在具有數十億個向量的數據集中也可以進行快速搜索。此外,還提供了用于評估和調整參數的輔助代碼。
Pinecone
Pinecone是一個基于云的向量數據庫,可以開發實時相似性搜索應用,能夠以毫秒級的延遲存儲和探索高維向量嵌入,適用于推薦系統、圖片和視頻搜索以及自然語言處理等應用。
Pinecone 的主要功能包括自動索引、實時更新、查詢自動調整和用于與當前流程進行簡單交互的 REST API。其架構專為可擴展性和穩健性而構建,可以輕松管理海量數據,同時保持高可用性。
圖片
Pinecone是一個可以托管的向量數據庫平臺,也就是說有商用方案,也有免費使用方案。其主要特點包括:
- 支持全托管服務
- 高度可伸縮
- 實時數據攝取
- 低延遲的搜索
- 與LangChain集成
Pinecone 采用了多種安全措施來保護用戶的數據安全和隱私。多層次的訪問控制機制可以控制用戶的訪問權限和操作權限,同時采用了數據加密、傳輸加密等技術來保護數據的安全性,還提供了數據備份和恢復等功能,可以防止數據丟失和損壞。
Pinecone 在性能方面表現非常出色,它能夠支持高達 1 百萬次的QPS,且具有低延遲和高吞吐量的特點,還具有分布式部署、實時索引構建和高效的向量相似度搜索等優點,可以幫助用戶快速處理大規模的向量數據。
此外,Pinecone 還支持多種編程語言和框架,如 Python、Java、TensorFlow 等,使得用戶可以輕松地將其集成到自己的應用程序中。
Milvus
Milvus是一個開源的分布式向量數據庫,它具備高可用、高性能、易拓展的特點,用于海量向量數據的實時召回。
Milvus 基于 Faiss、Annoy、HNSW 等向量搜索庫構建,可以輕松管理數百萬個實體,可以根據不同的數據特點選擇最合適的索引算法,核心是解決稠密向量相似度檢索的問題。在向量檢索的基礎上,Milvus 支持數據分區分片、數據持久化、增量數據攝取、標量向量混合查詢、time travel 等功能,同時大幅優化了向量檢索的性能,可滿足任何向量檢索場景的應用需求。
圖片
Milvus 還具有分布式部署、高可用性和高擴展性等優點,可以幫助用戶快速處理海量的向量數據。它也提供了多種安全措施來保護用戶的數據安全和隱私,支持 SSL/TLS 加密和訪問控制等技術,可以防止數據被非法訪問和竊取,還提供了數據備份和恢復等功能,可以保護數據的完整性和可用性。
此外,Milvus 還提供了多種客戶端 SDK,如 Python、Java、C++ 等,使得用戶可以方便地使用不同的編程語言來訪問和操作 Milvus。
3.2 支持向量的全文檢索數據庫
這類數據庫包括Elastic/Lucene、OpenSearch和Solr。它們都具有豐富的文本檢索功能,如可定制的標記器,分詞器,停用詞列表和N-grams等,大部分都基于開源庫,且有大型集成的生態系統,包括了向量庫。
例如,Elasticsearch,是一個支持各種類型數據的分布式搜索和分析引擎。Elasticsearch在7.3 版本中,添加了對向量數據索引的支持,支持混合查詢,但是向量檢索采用的仍然是暴力計算,性能損耗較大。在8.0版本引入了knn search其實就是一種近似最近鄰搜索算法,相似度支持歐式距離,點積和余弦相似性,knn search底層其實使用的是HNSW。遺憾的是,這種方式無法進行混合檢索。
3.3 支持向量的NoSQL 數據庫
幾乎所有這些NoSQL數據庫都是最近才通過添加向量搜索擴展而具備向量能力的,所以如果要是使用的話一定要做好測試。Cassandra,Rockset,Azure Cosmos DB和MongoDB等都紛紛宣布了增加向量搜索的計劃。NoSQL數據庫的向量搜索性能可能差別很大,這取決于所支持的向量函數、索引方法和硬件加速。
例如,RedisVector是一個向量數據庫,專注于向量數據的有效處理。它擅長存儲和分析大量向量數據,包括張量、矩陣和數值數組。通過 利用內存數據存儲Redis,RedisVector可提供高性能的查詢響應時間。它提供內置的索引和搜索功能,可以快速搜索和查找相似的載體,RedisVector還支持各種距離測量,用于比較向量和執行復雜的分析操作。通過對向量數據的操作,包括元素級算術和聚合,RedisVector 為處理向量提供了一個多功能環境,適用于處理和分析高維向量數據的機器學習應用,從而能夠創建定制的推薦系統和基于相似性的準確搜索。
對于支持向量的NoSQL 數據庫,探索嘗試未嘗不可,但在生產環境中使用要慎之又慎。
3.4 支持向量的SQL 數據庫
這些大都是關系型數據庫并且支持sql查詢,例如SingleStoreDB, PostgreSQL, Clickhouse和Kinetica的pgvector/Supabase Vector等。它們都宣布包含了向量搜索功能,如點積,余弦相似度,歐幾里得距離和曼哈頓距離,并且使用相似度分數找到n個最近鄰。由于提供了混合查詢,可以將向量與其他數據結合起來以獲得更有意義的結果。另外,大多數SQL數據庫都可以作為服務部署,可以在云上進行完全的管理。
圖片
例如,Postgres 通過 pg_vector 和 pg_embdding 兩個插件來實現向量數據庫,讓PG數據庫支持向量索引檢索的能力。其索引算法使用的是基于Faiss的IVF Flat索引,提供了優異的召回率。
4. 向量數據庫的一些對比
4.1 編程語言支持
Chroma是一個Python/TypeScript包裝器,基于C++編程語言的有OLAP數據庫Clickhouse以及開源向量索引HNSWLib。但如今,快速響應且可擴展的數據庫通常使用現代語言如Golang或Rust編寫。在專為向量數據庫而構建的供應商中,唯一使用Java構建的是Vespa。
4.2 開源與否
Pinecone是完全閉源的,Zilliz也是一個閉源的完全托管的商業解決方案,但它完全建立在Milvus之上,其他向量數據庫至少在代碼庫方面是源代碼可用的,具體的許可證決定了代碼的可許可性以及如何部署。
圖片
4.3 檢索算法
眾多向量數據庫的檢索算法都采用了HNSW,其中,Milvus 的檢索算法支持最為豐富。
圖片
4.4 部署方式
向量數據庫的典型部署方式包括本地部署和托管/云原生,兩者都遵循CS架構。還有一種新的選擇是嵌入式模式,其中數據庫本身與應用程序代碼緊密耦合,以serverless的方式運行。目前,只有Chroma和LanceDB可用作嵌入式數據庫。
圖片
綜上所述,主流向量數據庫的部分指標對比如下:
圖片
此外,在選擇向量數據庫時,還需要特別考量以下因素:
- 可擴展性:能夠高效處理高維度大數據量并能夠根據數據需求的增長進行擴展。
- 性能:速度和效率對數據庫至關重要,需要在數據搜索、搜索性能和執行各種向量操作方面表現出色。
- 靈活性:支持廣泛的數據類型和格式,并且可以輕松適應不同的應用場景。
- 易用性。這些數據庫易于使用和管理,易于安裝和配置,具有直觀的API,并且有良好的文檔和支持。
- 可靠性:需要有可靠和穩定的聲譽。
5. 向量數據庫與其他類型數據庫的對比
傳統數據庫,如關系數據庫,旨在存儲結構化數據。這意味著數據被組織到預定義的表、行和列中,確保數據的完整性和一致性。傳統數據庫往往針對CRUD進行優化,旨在高效地創建、讀取、更新和刪除數據條目,使其適用于從 Web 服務到企業軟件的各種應用程序。但是,一旦定義了數據庫結構,進行更改可能會非常復雜且耗時。這種剛性可確保數據一致性,但靈活性可能不如某些現代數據庫的無模式或動態模式性質。
特性 | 關系型數據庫 | 向量數據庫 |
數據類型 | 數值、字符串、時間等傳統數據類型 | 向量數據不存儲原始數據 |
數據規模 | 小,1億數據量為規模很大 | 大,千億數據是底線 |
數據組織方式 | 基于表格,按照行和列組織 | 基于向量,按照向量維度組織 |
查找方式 | 精確查找:點查/范圍查 | 近似查找:對算力要求較高 |
低時延,高并發 | 否 | 是 |
支撐上層應用 | 較弱 | 對外提供統一的API,更適合大規模AI引用程序的部署和使用 |
應用場景 | 容錯率低,需提供更為精準的搜索結果 | 場景容錯率較高 |
與在行和列中存儲多種標準數據類型(如字符串、數字和其他標量數據類型)不同,向量數據庫引入了向量這種新的數據類型,并圍繞此數據類型構建優化,專門用于實現快速存儲、檢索和最近鄰搜索語義。在傳統數據庫中,使用查找完全匹配項的索引或鍵值對對數據庫中的行進行查詢,并返回這些查詢的相關行。
特別地, 向量數據庫與圖數據庫的對比如下:
圖片
6. 向量數據庫在大模型中的應用
基于大模型的應用經常一些面臨挑戰,例如生成不準確或不相關的信息;缺乏事實一致性或常識;重復或自相矛盾;有偏見的或令人反感等。為了克服這些挑戰,可以使用向量數據庫來存儲與所需領域的不同主題、關鍵詞、事實、觀點和/或來源的信息。然后,在使用一個大模型時,通過AI插件從向量數據庫中傳遞信息,以生成更具信息性和吸引力的內容,符合目標意圖和指定風格。
借助向量數據庫,我們能夠快速加載和存儲事件作為嵌入,并使用向量數據庫作為為AI模型提供動力的大腦,提供上下文信息,長期記憶檢索,語義上的數據關聯等等。向量數據庫的典型使用方式如下:1. 使用embeding 技術創建向量2. 將這些向量存儲到向量數據庫3. 應用索引策略來組織管理向量4. 使用查詢向量執行相似性搜索5. 從向量數據庫中取得相似的向量
實際上,向量數據庫在不同的領域和應用程序中都有著許多用例,涉及自然語言處理(NLP)、計算機視覺(CV)、推薦系統(RS)和其他需要對數據進行語義理解和匹配的領域。在向量數據庫中存儲信息的一個用例是使大型語言模型(LLM)能夠基于AI插件生成更相關、更連貫的文本。
由于向量數據庫將要查詢的數據存儲為嵌入向量,并且語言模型(LLM)也將其內部的知識編碼為嵌入向量,因此在生成式問答應用中是天生一對。向量數據庫充當知識庫的功能,而LLM可以直接在嵌入空間中查詢數據的子集,一般可以使用以下方法進行操作:
- 用戶通過界面用自然語言提出問題。
- 問題的文本被傳遞給嵌入模型,然后返回一個句子嵌入向量。
- 問題向量被傳遞給向量數據庫,通過ANN搜索返回與之最相似的前k個結果。這一步非常關鍵,因為它大大縮小了LLM在下一步中的搜索空間。
- 構建一個LLM提示(基于開發者預定義的模板),將其轉換為嵌入向量,并傳遞給LLM。使用類似LangChain的框架可以方便地執行此步驟,因為可以動態構建提示語,并調用LLM的本地嵌入模塊,而無需為每個工作流編寫大量自定義代碼。
- LLM在前k個結果中搜索信息,并生成問題的答案,答案發送回用戶。
圖片
結合LLM和向量數據庫可以構建許多其他有用的應用程序。然而,了解向量數據庫的一些潛在限制是必要的。在搜索應用中,它們不一定優先考慮關鍵詞短語的精確匹配來確定相關性。存儲和查詢的數據必須適應所使用的嵌入模型的最大序列長度(對于類似BERT的模型,這個長度不超過幾百個詞)。目前,最好的方法是利用像LangChain和LlamaIndex這樣的框架,將數據分塊或壓縮成適合底層模型上下文的固定大小的向量。
同樣,向量數據庫也面臨著許多與其他數據庫技術相同的挑戰, 需要繼續努力提高可擴展性、近似精度、延遲性能和經濟性。許多向量數據庫在核心數據庫能力方面需要提升,例如安全性、彈性、運營支持和工作負載支持的多樣化。隨著AI應用的成熟,未來需要的不僅僅只限于向量搜索功能。
【參考資料】
- https://github.com/milvus-io/milvus
- Milvus: A Purpose-Built Vector Data Management System, SIGMOD'21
- https://github.com/facebookresearch/faiss
- https://www.pinecone.io