一驴一、向量數(shù)據(jù)庫介紹
向量數(shù)據(jù)庫能夠有效存儲和快速檢索向量數(shù)據(jù)肝断,特別是在人工智能和大數(shù)據(jù)分析中驰凛,能夠支持復(fù)雜的數(shù)據(jù)類型和高效的相似度搜索担扑,極大地提升了數(shù)據(jù)處理和分析的效率和精度。百度向量數(shù)據(jù)庫 VectorDB支持多種索引類型和相似度算法涌献,不僅能配合大模型打造專業(yè)知識庫,還可以應(yīng)用于圖片搜索枢劝,音樂推薦卜壕,文本分類等領(lǐng)域。
二被冒、向量索引的選擇
VectorDB當(dāng)前支持FLAT和HNSW索引轮蜕,同時也支持“無索引”,即不對向量字段建立任何向量索引跃洛,仍然可以提供向量檢索汇竭,而且是召回率為100%的KNN檢索。如何根據(jù)業(yè)務(wù)特點(diǎn)選擇這些索引细燎,我們通過一個表格來進(jìn)行對比分析:
索引類型 | 索引簡介 | 成本 | 性能 | 召回率 | 適用場景 |
---|---|---|---|---|---|
無索引 | 不建立向量索引,在檢索時悼凑,需要先將原始向量數(shù)據(jù)從磁盤中讀取并加載到內(nèi)存璧瞬,然后在內(nèi)存中執(zhí)行KNN檢索。 | 很低 | 很低 | 很高(100%) | 對成本有苛刻要求渔欢,同時對性能要求不高的場景瘟忱。 |
FLAT | 即平坦索引苫幢,顧名思義垫挨,將原始向量數(shù)據(jù)平坦地?cái)[放在內(nèi)存中,不增加任何輔助機(jī)制伞梯。在檢索時帚屉,需要計(jì)算每個向量與目標(biāo)向量的相似性,所以一般也被稱為“暴力檢索”攻旦。其本質(zhì)是全內(nèi)存+KNN檢索,相比于無索引且预,其數(shù)據(jù)需要全內(nèi)存烙无,會帶來相應(yīng)的成本。 | 高 | 中低 | 很高(100%) | 可以接受較高成本涮拗,也可以接受稍差一點(diǎn)的性能(相比于非暴力檢索)迂苛,但是對召回率有苛刻要求的場景。 |
HNSW | HNSW的全稱是Hierarchical Navigable Small World三幻,即分層可導(dǎo)航小世界念搬,是一種經(jīng)典的圖結(jié)構(gòu)索引,該索引的優(yōu)勢在于性能和召回率都比較穩(wěn)定锁蠕,整體效果受向量數(shù)據(jù)集的分布/傾斜的影響很小懊蒸。HNSW索引目前最為廣泛使用的索引方法之一骑丸,用于支撐ANN檢索妒貌。 | 高 | 高(但在極限過濾場景下铸豁,可能會很低) | 高(但在極限過濾場景下,可能會很低) | 可以接受較高的成本节芥,對性能也有較高的訴求,對召回率也有較高的訴求的場景蚣驼。綜合上來看是比較平衡的場景相艇,此類場景廣泛存在。 |
Puck | Puck是百度自行研發(fā)的向量索引留储,在百度內(nèi)部得到了廣泛的應(yīng)用咙轩,索引了上萬億條向量。Puck是倒排類索引赔嚎,但在基礎(chǔ)倒排結(jié)構(gòu)上做了大量的改造和優(yōu)化胧弛,效果提升明顯。 | 高 | 高 | 中结缚、高 | 與圖結(jié)構(gòu)索引不同的是,倒排類索引在構(gòu)建索引之前尤勋,往往需要在采樣數(shù)據(jù)集的基礎(chǔ)上執(zhí)行一個基于K-Means聚類的訓(xùn)練過程訓(xùn)練出碼本茵宪,Puck也不例外。訓(xùn)練過程比較消耗資源暖哨,因此訓(xùn)練時間可能較長凰狞,故此類索引不建議頻繁重建沛慢,更適用于向量規(guī)模較大(比如單個數(shù)據(jù)集達(dá)到上億級別)达布,且對召回率沒有過于嚴(yán)格要求的場景√煽啵基于大語言模型的應(yīng)用場景不建議使用該索引产还。 |
HNSW索引看起來非常平衡,但在實(shí)際應(yīng)用中集乔,受該索引算法的固有特性影響坡椒,容易出現(xiàn)性能急劇下降或者召回率嚴(yán)重下滑的情況,這種情況一般出現(xiàn)在“極限過濾”的場景汗唱。所謂極限過濾場景丈攒,是指在檢索時,需要將該索引集合中的絕大部分?jǐn)?shù)據(jù)都過濾掉际插,只檢索極小一部分?jǐn)?shù)據(jù)显设。主要原因在于,在構(gòu)建HNSW的圖結(jié)構(gòu)時捕捂,依據(jù)的是構(gòu)建集合中的全部數(shù)據(jù)及其他們之間的距離指攒,而在檢索時,由于絕大部分?jǐn)?shù)據(jù)又都過濾掉了不參與距離計(jì)算允悦,檢索的結(jié)果中可能出現(xiàn)嚴(yán)重的漏召現(xiàn)象,從而導(dǎo)致召回率嚴(yán)重下降猿挚,當(dāng)然其嚴(yán)重程度也受數(shù)據(jù)的分布影響驶鹉。這類極限場景容易出現(xiàn)在ToC的業(yè)務(wù)中,比如一個ToC業(yè)務(wù)办绝,有很多終端用戶姚淆,但是每個終端用戶的數(shù)據(jù)量很小(例如幾百幾千條)降淮,同時在檢索的時候搏讶,由于用戶隱私問題,只能檢索屬于該用戶自身的數(shù)據(jù)媒惕。如果按照數(shù)十萬上百萬的規(guī)模來對這類數(shù)據(jù)集構(gòu)建HNSW索引妒蔚,一個索引集中包含數(shù)百到上千個用戶的數(shù)據(jù),檢索時僅檢索其中的一個用戶的數(shù)據(jù)肴盏,就會造成極限過濾場景菜皂。這類極限過濾場景并不容易優(yōu)化。
三幌墓、開通VDB
請參考官方文檔:https://cloud.baidu.com/doc/VDB/s/hlrsoazuf
四常侣、AppBuilder-SDK操作VDB
共3步:
- 將數(shù)據(jù)segments插入VDB數(shù)據(jù)庫;
- 構(gòu)造查詢胳施;
- 從VDB返回查詢信息。
詳見代碼注釋焦辅。
import os
import appbuilder
from appbuilder import AppBuilderTracer
tracer=AppBuilderTracer(
enable_phoenix = False, # 暫時關(guān)閉Tracer
enable_console = False,
)
#開始Trace
tracer.start_trace()
# 請前往千帆AppBuilder官網(wǎng)創(chuàng)建密鑰,流程詳見:https://cloud.baidu.com/doc/AppBuilder/s/Olq6grrt6#1%E3%80%81%E5%88%9B%E5%BB%BA%E5%AF%86%E9%92%A5
os.environ["APPBUILDER_TOKEN"] = 'bce-v3/ALTAK-bppeq3zxoIY1Kc4CvfB6j/74ca5e86a49606d2e84bb49d86a0230f8fb1b97f'
segments = appbuilder.Message(["Guoluan同學(xué)是大二老生", "Guoluan同學(xué)在黑龍江大學(xué)就讀", "Guoluan同學(xué)從3歲開始跳舞", "黑大誕生于延安","Guoluan同學(xué)的專業(yè)是計(jì)算機(jī)及應(yīng)用","Guoluan同學(xué)的生日跟財(cái)神爺一天","昨天交了453.2的英語書本費(fèi)","黑龍江大學(xué)今年8月24日開學(xué)"])
# 初始化構(gòu)建索引
vector_index = appbuilder.BaiduVDBVectorStoreIndex.from_params(
instance_id='vdb-bj-driaxot******',# 替換為你的VDB的instance_id
api_key='vdb$20uajh*****',# VBD的key即root用戶的密碼
drop_exists=True,# 如果索引存在則刪除剃根,否則可能會查出多條相同數(shù)據(jù)
)
vector_index.add_segments(segments)
# 循環(huán)提問和回答
while True:
user_input = input("請輸入你的問題: ")
if user_input=='exit':
break
query = appbuilder.Message(user_input)
retriever = vector_index.as_retriever()
res = retriever(query,3) # 第2個參數(shù)為top_k即返回幾條記錄
# print(res)
for item in res.content:
if item['score']>0.8:
print(f"從向量數(shù)據(jù)庫查詢score>0.8的結(jié)果為:{item['text']}狈醉,score為{item['score']}")
else:
print(f"其他參考結(jié)果:{item['text']}惠险,score為{item['score']}")
# 結(jié)束trace
tracer.end_trace()
執(zhí)行python代碼,當(dāng)查詢計(jì)算機(jī)的專業(yè)課時渣慕,根據(jù)語義搜索的效果如下圖: