八個(gè)優(yōu)秀的開源免費(fèi)向量數(shù)據(jù)庫,讓你的AI擁有記憶
今年AI大模型應(yīng)用呈井噴式發(fā)展,其中,LangChain、Haystack等端到端大語言模型應(yīng)用框架更是將向量數(shù)據(jù)庫推出了新熱點(diǎn)。
向量數(shù)據(jù)庫(vector database,也有人稱矢量數(shù)據(jù)庫),簡(jiǎn)單地說,它們是以向量格式管理、存儲(chǔ)和檢索數(shù)據(jù)的數(shù)據(jù)庫。
為什么向量數(shù)據(jù)庫對(duì)AI如此重要?
因?yàn)樗谔幚砀呔S數(shù)據(jù)方面具有先天優(yōu)勢(shì),從圖像處理到推薦系統(tǒng),向量數(shù)據(jù)庫無疑是幕后的英雄。它的主要功能包括:
- 管理:向量數(shù)據(jù)庫以原始數(shù)據(jù)形式處理數(shù)據(jù),能夠有效地組織和管理數(shù)據(jù),便于AI模型應(yīng)用。
- 存儲(chǔ):能夠存儲(chǔ)向量數(shù)據(jù),包括各種AI模型需要使用到的高維數(shù)據(jù)。
- 檢索:向量數(shù)據(jù)庫特別擅長(zhǎng)高效地檢索數(shù)據(jù),這一個(gè)特點(diǎn)能夠確保AI模型在需要的時(shí)候快速獲得所需的數(shù)據(jù)。這也是向量數(shù)據(jù)庫能夠在一些推薦系統(tǒng)或者檢索系統(tǒng)中得到應(yīng)用的重要原因。
因此,我們說向量數(shù)據(jù)庫讓AI有了記憶,這個(gè)記憶不僅僅是記錄存儲(chǔ)、也包括檢索和管理。就像人類的記憶一樣,我們通過同學(xué)的畢業(yè)照總是能夠認(rèn)得這個(gè)人是誰;我們?cè)诤团笥蚜奶斓臅r(shí)候也常常會(huì)一起回憶過去。
那么向量數(shù)據(jù)庫是如何工作的?
向量數(shù)據(jù)庫的核心是通過使用數(shù)學(xué)模型來管理向量數(shù)據(jù)。
那么什么又是向量?簡(jiǎn)單地說,向量是一個(gè)既有方向又有大小的數(shù)字對(duì)象。在向量數(shù)據(jù)庫中,向量可以用于表示復(fù)雜的數(shù)據(jù),例如:圖像、文本。
每個(gè)數(shù)據(jù)片段都被轉(zhuǎn)換成高維空間中的向量管理起來。當(dāng)我們需要查找相似的數(shù)據(jù)片段時(shí),數(shù)據(jù)庫不需要遍歷篩選選每個(gè)條目。而是通過計(jì)算向量之間的距離來匹配,向量越接近,數(shù)據(jù)就越相似。這種方式非常高效,通過這種方式檢索數(shù)據(jù)可以比傳統(tǒng)關(guān)系型數(shù)據(jù)庫更快地處理大批量數(shù)據(jù)。
下面是個(gè)文本向量存儲(chǔ)的示例圖:
下面是圖片向量化存儲(chǔ)與檢索的示例圖:
大家都知道,通用大模型的運(yùn)行涉及巨大的計(jì)算資源,因此許多大模型都基于MaaS,私有化成本很高。與之相矛盾的是在具體行業(yè)大模型應(yīng)用中往往對(duì)數(shù)據(jù)安全要求高,并且需要與相關(guān)業(yè)務(wù)或領(lǐng)域知識(shí)深入融合,才能做到安全、專業(yè)。LangChain等大模型應(yīng)用框架為行業(yè)大模型應(yīng)用提供了一個(gè)經(jīng)典解決方案,而開源的向量數(shù)據(jù)庫又為L(zhǎng)angChain等大模型應(yīng)用解決方案提供了基礎(chǔ)支撐,其實(shí)向量數(shù)據(jù)庫在許多應(yīng)用場(chǎng)景(如:企業(yè)知識(shí)庫、推薦系統(tǒng)、檔案管理等)也非常有用。因此,向量數(shù)據(jù)庫也成為大模型應(yīng)用發(fā)展的一個(gè)熱門技術(shù)。
八個(gè)優(yōu)秀的開源向量數(shù)據(jù)庫項(xiàng)目
開源社區(qū)對(duì)向量數(shù)據(jù)庫的發(fā)展功不可沒,許多開源向量數(shù)據(jù)庫項(xiàng)目在性能、靈活性和魯棒性方面表現(xiàn)都非常優(yōu)秀,下面列舉8個(gè)目前最佳的開源向量數(shù)據(jù)庫項(xiàng)目,這些開業(yè)項(xiàng)目應(yīng)該能夠?yàn)槟愕腁I解決方案提供最佳技術(shù)選型。
1.Milvus
https://github.com/milvus-io/milvus
Milvus是由Zilliz提供的一個(gè)高度可定制的開源向量數(shù)據(jù)庫,旨在為嵌入式相似性搜索等AI應(yīng)用提供支持。目前Milvus已經(jīng)發(fā)布了 2.0 ,Milvus 2.0是一個(gè)云原生向量數(shù)據(jù)庫,設(shè)計(jì)上采用存儲(chǔ)、計(jì)算分離。Milvus2.0中的所有組件都支持無狀態(tài),這樣做就使得整個(gè)的應(yīng)用更加靈活而有彈性。
Milvus建立在Faiss、Annoy、HNSW等主流向量搜索庫之上,旨在對(duì)包含數(shù)百萬、數(shù)十億甚至數(shù)萬億個(gè)向量的密集向量數(shù)據(jù)集進(jìn)行相似性搜索。
Milvus還支持?jǐn)?shù)據(jù)分片、數(shù)據(jù)持久化、流數(shù)據(jù)攝取、向量和標(biāo)量數(shù)據(jù)之間的混合搜索以及許多其他高級(jí)功能。建議使用Kubernetes部署Milvus,以獲得最佳可用性和彈性。
Milvus采用共享存儲(chǔ)架構(gòu),存儲(chǔ)、計(jì)算分離,具備計(jì)算節(jié)點(diǎn)的水平可擴(kuò)展性。遵循數(shù)據(jù)平面和控制平面分解原則,Milvus包括四層:接入層、協(xié)調(diào)服務(wù)、工作節(jié)點(diǎn)和存儲(chǔ)。在擴(kuò)展或?yàn)?zāi)難恢復(fù)方面,這些層可以做到相互獨(dú)立。
下面是Milvus的架構(gòu)圖。
Milvus的主要特性包括:
- 支持萬億向量數(shù)據(jù)集上的毫秒級(jí)搜索:在萬億向量數(shù)據(jù)集上測(cè)試平均延遲(毫秒級(jí))。
- 簡(jiǎn)化的非結(jié)構(gòu)化數(shù)據(jù)管理:豐富API、跨客戶端一致的用戶體驗(yàn)。
- 始終保持高可靠性:Milvus的內(nèi)置復(fù)制和故障轉(zhuǎn)移/回切功能可確保數(shù)據(jù)和應(yīng)用程序在發(fā)生中斷時(shí)保持業(yè)務(wù)連續(xù)性。
- 高度可擴(kuò)展和彈性性能:組件級(jí)的可伸縮性使其可以按需伸縮。Milvus可以根據(jù)負(fù)載類型在組件級(jí)別自動(dòng)縮放,使資源調(diào)度更加高效。
- 混合搜索能力:除了向量,Milvus還支持“布爾類型”、“整數(shù)”、“浮點(diǎn)數(shù)”等數(shù)據(jù)類型。
- 統(tǒng)一Lambda結(jié)構(gòu):Milvus將流和批處理結(jié)合起來進(jìn)行數(shù)據(jù)存儲(chǔ),以平衡及時(shí)性和效率。它的統(tǒng)一界面使向量相似性搜索變得輕而易舉。強(qiáng)大的社區(qū)支持和行業(yè)的認(rèn)可:擁有超過1000個(gè)企業(yè)用戶,GitHub超23K Star,以及活躍的開源社區(qū)。
更多內(nèi)容可以參考官網(wǎng):https://milvus.io
Demo:https://milvus.io/milvus-demos/
文檔: https://milvus.io/docs
2.Faiss
https://github.com/facebookresearch/faiss
Faiss由Facebook的AI Research團(tuán)隊(duì)開發(fā)的向量數(shù)據(jù)庫,在高維矢量搜索方面表現(xiàn)出色。是一個(gè)搜索效率非常突出的向量庫,這也使其成為一些實(shí)時(shí)性要求高的應(yīng)用程序的絕佳選擇。Faiss是一個(gè)高效的相似性搜索和密集向量聚類庫。它包含的算法可以搜索任何大小的向量集,甚至多達(dá)超過RAM的向量大小。它還包含用于評(píng)估和參數(shù)調(diào)整的支持代碼。Faiss是用C++編寫的,帶有Python/numpy的完整包裝,一些常用的算法是在GPU上實(shí)現(xiàn)的。
Faiss是通過存儲(chǔ)一組向量的索引,并提供了一個(gè)函數(shù)在它們當(dāng)中進(jìn)行比較,從而實(shí)現(xiàn)搜索。
目前Faiss在GitHub上的Star已經(jīng)超過24K。
基于CPU、GPU的python安裝方法如下:
$ conda install -c pytorch faiss-cpu
$ conda install -c pytorch faiss-gpu
以上只能安裝一個(gè),不能同時(shí)安裝兩個(gè),因?yàn)楹笳呤乔罢叩某?/p>
3.Annoy
https://github.com/spotify/annoy
Annoy (Approximate Nearest Neighbors Oh Yeah)是由Spotify創(chuàng)建的一個(gè)輕量級(jí)且功能強(qiáng)大的向量數(shù)據(jù)庫。它專為快速搜索大型數(shù)據(jù)集而設(shè)計(jì),非常適合需要快速響應(yīng)的應(yīng)用。它是一個(gè)C++庫,但支持在Python中使用。
它通過創(chuàng)建大型的只讀文件數(shù)據(jù)結(jié)構(gòu),并將這些數(shù)據(jù)結(jié)構(gòu)映射到內(nèi)存中,以便許多進(jìn)程可以共享相同的數(shù)據(jù)。
ANNOY的核心是一種基于隨機(jī)投影和樹的算法。它由Erik Bernhardsson于2015年在Spotify工作時(shí)開發(fā)。ANNOY設(shè)計(jì)目標(biāo)是實(shí)現(xiàn)在100到1000個(gè)密集維度的數(shù)據(jù)集中進(jìn)行搜索。為了計(jì)算最近的鄰居,它將點(diǎn)集分成兩半,并遞歸地進(jìn)行,直到每個(gè)集合都有k個(gè)項(xiàng)目。通常k應(yīng)該在100左右(見下圖)。
關(guān)于Annoy的主要特征官方介紹如下:
- 支持多種相似算法:歐氏距離、曼哈頓距離、余弦距離、漢明距離、內(nèi)積距離。余弦距離等價(jià)于歸一化向量的歐幾里得距離= sqrt(2-2*cos(u,v))
- 如果你沒有太多的維度(比如<=100),效果會(huì)更好,但即使是1000維的維度,它的表現(xiàn)也還是非常優(yōu)秀。
- 內(nèi)存占用小
- 允許在多個(gè)進(jìn)程之間共享內(nèi)存
- 索引創(chuàng)建與查找是分開的(特別是,一旦創(chuàng)建了樹,就不能添加更多的項(xiàng))
- 原生Python支持,已在2.7、3.6和3.7中測(cè)試。
- 在磁盤上構(gòu)建索引,以便索引無法放入內(nèi)存的大數(shù)據(jù)集
python語言下的安裝annoy:
pip install annoy
python語言下的使用annoy:
from annoy import AnnoyIndex
import random
f = 40 # Length of item vector that will be indexed
t = AnnoyIndex(f, 'angular')
for i in range(1000):
v = [random.gauss(0, 1) for z in range(f)]
t.add_item(i, v)
t.build(10) # 10 trees
t.save('test.ann')
# ...
u = AnnoyIndex(f, 'angular')
u.load('test.ann') # super fast, will just mmap the file
print(u.get_nns_by_item(0, 1000)) # will find the 1000 nearest neighbors
4.Nmslib
https://github.com/nmslib/nmslib
Nmslib (Non-Metric Space Library)是一個(gè)于非度量空間的開源向量數(shù)據(jù)庫。是一個(gè)高效的跨平臺(tái)相似性搜索庫,也是一個(gè)評(píng)估相似性搜索方法的工具包,并且它的核心庫沒有任何第三方依賴項(xiàng)。
該項(xiàng)目的目標(biāo)是創(chuàng)建一個(gè)用于能夠在通用以及非度量空間中進(jìn)行搜索的全面工具包,包括:通用搜索方法、近似搜索方法、各種度量空間訪問方法以及非度量空間的方法。
Nmslib是一個(gè)可擴(kuò)展的庫,可以添加新的搜索方法和距離函數(shù)。支持在C++和Python、Java中使用,例如:可以使用Java等語言構(gòu)建一個(gè)查詢服務(wù)器。
5.Qdrant
https://github.com/qdrant/qdrant
Qdrant是一個(gè)包含向量數(shù)據(jù)庫和向量相似度搜索引擎的開源項(xiàng)目。它提供了一組便捷的API來執(zhí)行存儲(chǔ)、搜索和管理向量數(shù)據(jù),并且能夠同時(shí)存儲(chǔ)payload數(shù)據(jù),這就有利于自定義的數(shù)據(jù)過濾,這個(gè)方面在各種神經(jīng)網(wǎng)絡(luò)、基于語義的匹配、分面搜索、精準(zhǔn)推薦等應(yīng)用程序非常有用。
Qdrant是用Rust語言開發(fā)的,因此它能在高負(fù)載下也具備高效、可靠特性。Qdrant的使用非常簡(jiǎn)單:
(1)使用Docker啟動(dòng)
docker run -p 6333:6333 qdrant/qdrant
br
(2)在python中使用
安裝:
pip install qdrant-client
連接:
from qdrant_client import QdrantClient
qdrant = QdrantClient("http://localhost:6333") # Connect to existing Qdrant instance, for production
qdrant的特點(diǎn)如下:
- 過濾和有效數(shù)據(jù):Qdrant使JSON格式存儲(chǔ)Payload(有效數(shù)據(jù))與向量相關(guān)聯(lián),支持should、must和must_not條件的各種組合檢索方式,確保能夠檢索所有向量,這點(diǎn)與ElasticSearch的后過濾不同。
- 支持豐富的數(shù)據(jù)類型:Payload適應(yīng)不同的數(shù)據(jù)類型和查詢條件,包括字符串匹配、數(shù)值范圍、地理位置等。這些篩選條件使您能夠在相似性匹配的基礎(chǔ)上創(chuàng)建自定義業(yè)務(wù)邏輯。
- 查詢計(jì)劃和Payload索引:查詢規(guī)劃器利用存儲(chǔ)的Payload信息來優(yōu)化查詢。
- 硬件加速:利用現(xiàn)代CPU x86-x64架構(gòu),Qdrant在現(xiàn)代硬件上提供更快的搜索性能。
- 寫入前記錄日志:Qdrant通過更新確認(rèn)確保數(shù)據(jù)的持久性,即使在停電期間也是如此。更新日志存儲(chǔ)所有操作,從而可以輕松地重建最新的數(shù)據(jù)庫狀態(tài)。
- 分布式部署:從v0.8.0開始,Qdrant支持分布式部署。多個(gè)Qdrant機(jī)器形成一個(gè)集群,通過Raft協(xié)議進(jìn)行協(xié)調(diào),以進(jìn)行水平擴(kuò)展。
- 獨(dú)立運(yùn)行:Qdrant支持獨(dú)立運(yùn)行,不依賴外部數(shù)據(jù)庫或編排控制器,簡(jiǎn)化了配置。
6.Chroma
https://github.com/chroma-core/chroma
Chroma是一個(gè)開源嵌入式向量數(shù)據(jù)庫。基于Chroma可以輕松構(gòu)建LLM應(yīng)用程序。Chroma的設(shè)計(jì)非常簡(jiǎn)單、易用、靈活,可以滿足各種場(chǎng)景下的應(yīng)用。它支持使用第三方的embedding模型執(zhí)行查詢和元數(shù)據(jù)過濾。
下面是Chroma與OpenAI embedding搭配使用的架構(gòu)示意圖:
基于Docker的Chromadb可以參考:
- docker-compose:https://github.com/chroma-core/chroma/blob/main/docker-compose.yml
- dockerFile: https://github.com/chroma-core/chroma/blob/main/Dockerfile
在具體應(yīng)用開發(fā)上,Python下使用Chroma也非常簡(jiǎn)單。
安裝:
pip install chromadb
四個(gè)核心API的使用:
import chromadb
# setup Chroma in-memory, for easy prototyping. Can add persistence easily!
client = chromadb.Client()
# Create collection. get_collection, get_or_create_collection, delete_collection also available!
collection = client.create_collection("all-my-documents")
# Add docs to the collection. Can also update and delete. Row-based API coming soon!
collection.add(
documents=["This is document1", "This is document2"], # we handle tokenization, embedding, and indexing automatically. You can skip that and add your own embeddings as well
metadatas=[{"source": "notion"}, {"source": "google-docs"}], # filter on these!
ids=["doc1", "doc2"], # unique for each doc
)
# Query/search 2 most similar results. You can also .get by id
results = collection.query(
query_texts=["This is a query document"],
n_results=2,
# where={"metadata_field": "is_equal_to_this"}, # optional filter
# where_document={"$contains":"search_string"} # optional filter
)
Chroma的主要特點(diǎn)包括:
- 簡(jiǎn)單:類型完整、測(cè)試全面、文檔完整
- 整合:支持LangChain(python和js)、LlamaIndex等等。
- 開發(fā)、測(cè)試、生產(chǎn)過程:在python notebook中運(yùn)行的API可直接應(yīng)用到集群環(huán)境。
- 功能豐富:查詢、過濾、密度估計(jì)等
- 免費(fèi)、開源
7.LanceDB
https://github.com/lancedb/lancedb
LanceDB是一個(gè)開源的支持持久存儲(chǔ)的向量搜索數(shù)據(jù)庫,這個(gè)開源項(xiàng)目可以大大簡(jiǎn)化embeddings的檢索、過濾和管理。
LanceDB的內(nèi)核是用Rust開發(fā)的,并使用Lance構(gòu)建(Lance是一種為高性能ML工作負(fù)載設(shè)計(jì)的開源列格式)。Python和JavaScript等語言可以使用API操作LanceDB。
Python的使用方式如下:
安裝:
pip install lancedb
檢索:
import lancedb
uri = "data/sample-lancedb"
db = lancedb.connect(uri)
table = db.create_table("my_table",
data=[{"vector": [3.1, 4.1], "item": "foo", "price": 10.0},
{"vector": [5.9, 26.5], "item": "bar", "price": 20.0}])
result = table.search([100, 100]).limit(2).to_df()
LanceDB的主要功能特點(diǎn)如下:
- 無需管理服務(wù)器的生產(chǎn)規(guī)模向量搜索。
- 支持存儲(chǔ)、查詢以及過濾向量、元數(shù)據(jù)和多模態(tài)數(shù)據(jù)(文本、圖像、視頻、點(diǎn)云等)。
- 支持向量相似度搜索、全文檢索和SQL語法。
- 支持Python和JavaScript/Typescript。
- 零拷貝、自動(dòng)版本控制,無需額外基礎(chǔ)架構(gòu)即可管理數(shù)據(jù)版本。
- 支持基于GPU構(gòu)建向量索引。
- 支持與LangChain?、LlamaIndex、Apache-Arrow、Pandas、Polars、DuckDB等生態(tài)集成。
8.Vectra
https://github.com/Stevenic/vectra
Vectra是一個(gè)Node.js的本地向量數(shù)據(jù)庫,其功能類似于Pinecone或Qdrant,但區(qū)別是Vectra使用本地文件構(gòu)建。每個(gè)Vectra索引都對(duì)應(yīng)磁盤上的一個(gè)文件夾。文件夾中包含一個(gè)index.json文件,文件內(nèi)容包含索引的所有向量以及這些索引的元數(shù)據(jù)。創(chuàng)建索引時(shí),可以指定索引的元數(shù)據(jù)屬性,只有這些字段才會(huì)存儲(chǔ)在index.json文件中。而項(xiàng)目的其他元數(shù)據(jù)將會(huì)被保存到一個(gè)有GUID指定的文件中。
運(yùn)行時(shí),整個(gè)Vectra索引都被加載到內(nèi)存中,因此它的檢索效率非常高,甚至是實(shí)時(shí)的,但是它不適合用于類似需要保留長(zhǎng)上下文的聊天機(jī)器人場(chǎng)景。Vectra更適合用于一些小的語料庫、靜態(tài)數(shù)據(jù)或者一些問答文檔的檢索等應(yīng)用場(chǎng)景。
在Node.js中的使用如下:
安裝:
$ npm install vectra
創(chuàng)建實(shí)例:
if (!await index.isIndexCreated()) {
await index.createIndex();
}
創(chuàng)建索引:
import { LocalIndex } from 'vectra';
const index = new LocalIndex(path.join(__dirname, '..', 'index'));
添加數(shù)據(jù)到索引:
import { OpenAIApi, Configuration } from 'openai';
const configuration = new Configuration({
apiKey: `<YOUR_KEY>`,
});
const api = new OpenAIApi(configuration);
async function getVector(text: string) {
const response = await api.createEmbedding({
'model': 'text-embedding-ada-002',
'input': text,
});
return response.data.data[0].embedding;
}
async function addItem(text: string) {
await index.insertItem({
vector: await getVector(text),
metadata: { text }
});
}
// Add items
await addItem('apple');
await addItem('oranges');
await addItem('red');
await addItem('blue');
檢索數(shù)據(jù):
async function query(text: string) {
const vector = await getVector(input);
const results = await index.queryItems(vector, 3);
if (results.length > 0) {
for (const result of results) {
console.log(`[${result.score}] ${result.item.metadata.text}`);
}
} else {
console.log(`No results found.`);
}
}
await query('green');
/*
[0.9036569942401076] blue
[0.8758153664568566] red
[0.8323828606103998] apple
*/
await query('banana');
/*
[0.9033128691220631] apple
[0.8493374123092652] oranges
[0.8415324469533297] blue
*/
總之
以上這些開源向量數(shù)據(jù)庫每一個(gè)都有自己獨(dú)特的一面。選擇使用哪一款取決于項(xiàng)目的具體需求。如果您正在處理一個(gè)需要高速數(shù)據(jù)檢索的項(xiàng)目,那么Annoy可能是最合適的。但如果項(xiàng)目涉及非度量空間,那么Nmslib可能才是首選的。一個(gè)合適的向量數(shù)據(jù)庫可以成為AI解決方案當(dāng)中的記憶海綿體,讓AI不僅能推理還能記憶、檢索,提升AI應(yīng)用的效果。