【騰訊云云上實驗室-向量數據庫】Tencent Cloud VectorDB在實戰項目中替換Milvus測試

為什么嘗試使用Tencent Cloud VectorDB替換Milvus向量庫?

亮點:Tencent Cloud VectorDB支持Embedding,免去自己搭建模型的負擔(搭建一個生產環境的模型實在耗費精力和體力)。

騰訊云向量數據庫是什么?

騰訊云向量數據庫是一款全托管的自研企業級分布式數據庫服務,專用于存儲、檢索、分析多維向量數據。該數據庫支持多種索引類型和相似度計算方法,單索引支持10億級向量規模,可支持百萬級 QPS 及毫秒級查詢延遲。騰訊云向量數據庫不僅能為大模型提供外部知識庫,提高大模型回答的準確性,還可廣泛應用于推薦系統、NLP 服務、計算機視覺、智能客服等 AI 領域。

Milvus是什么?

Milvus是在2019年創建的,其唯一目標是存儲、索引和管理由深度神經網絡和其他機器學習(ML)模型生成的大規模嵌入向量。作為一個專門設計用于處理輸入向量查詢的數據庫,它能夠處理萬億級別的向量索引。與現有的關系型數據庫主要處理遵循預定義模式的結構化數據不同,Milvus從底層設計用于處理從非結構化數據轉換而來的嵌入向量。

項目展示

游戲內提問
問答緩存庫后臺管理系統

項目介紹游戲內部接入ChatGPT的智能NPC,可以與她進行語音交流。可以回答與游戲相關的問題(這個專業問題是為了編寫這個文章,專門添加到問答緩存庫中的,游戲內會拒絕回答此類問題)。為了加快ChatGPT的回復速度和降低ChatGPT的費用,增加問答緩存機制。這里運用向量數據庫的相似文本相似度高的特性,通過向量搜索,匹配相似度大于一定值,例如:0.95。搜索到相似問題,直接返回答案,不在進行ChatGPT訪問。

其次,存在緩存,針對相似問題,還可以給予特定回復答案。例如上面示例,當提問“介紹一下騰訊向量數據庫”,直接回復“騰訊云向量數據庫是一款全托管的自研企業級分布式數據庫服務,專用于存儲、檢索、分析多維向量數據。該數據庫支持多種索引類型和相似度計算方法,單索引支持10億級向量規模,可支持百萬級 QPS 及毫秒級查詢延遲。騰訊云向量數據庫不僅能為大模型提供外部知識庫,提高大模型回答的準確性,還可廣泛應用于推薦系統、NLP 服務、計算機視覺、智能客服等 AI 領域。”

為什么使用向量數據庫?

重點:速度
向量相似度匹配是很長的數組,例如:bge-large-zh模型文本轉向量,生成的是768維的float數組。拿問題文本轉換為的768維向量與緩存的所有問題的向量進行相似性計算,然后獲取最相似的幾條數據,這個運算量非常大,速度非常慢。
測試代碼:
與300個768維向量進行相似比對,獲取最相似的一條數據,耗時幾秒鐘。按照這個速度,如果與幾千上萬條數據進行這么計算,簡直無法忍受。
這時就必須使用向量數據庫了,向量數據庫可以支持毫秒級檢索上百萬行數據。本人曾使用Milvus數據庫,分別插入1000行數數據和插入10萬行數據,然后進行搜索對比,都在幾十毫秒返回結果,數據量的增多,對檢索速度幾乎沒有任何影響。

本項目哪里需要使用向量數據庫?

  • 玩家提問:玩家提問先通過embedding轉換為向量,在向量庫檢索相似的問題,滿足匹配條件,直接返回對應的答案。
  • 后臺相似問題檢索:后臺通過向量檢索相似問題,以便對特定問題進行增刪改查。

使用騰訊云向量數庫(Tencent Cloud VectorDB)的優點?

  1. 支持Embedding:騰訊云向量數據庫(Tencent Cloud VectorDB)提供將非結構化數據轉換為向量數據的能力,目前已支持文本 Embedding 模型,能夠覆蓋多種主流語言的向量轉換,包括但不限于中文、英文。對于小型項目這是一個非常大的優勢。可以降低自己搭建embedding模型或者使用第三方embedding模型的成本。
  2. FilterIndex的field_type支持數據類型簡單:只有String和Uint64,使用起來非常省心。而Milvus數據支持10幾種類型,對于初學者不友好,還要研究具體如何使用。

指定 Filter 字段的數據類型。取值如下:
String:字符型。若 name 為 id,則該參數固定為 FieldType.String。
Uint64:指無符號整數,該參數可設置為 FieldType.Uint64。

研究Tencent Cloud VectorDB,測試并封裝代碼庫my_tc_vector_db.py

if __name__ == '__main__':# 初始化myTcVectorDB = MyTcVectorDB("http://****************.tencentclb.com:30000", "root","2epSOV3HK6tiyALo6UqE3mGV**************")# 刪除數據庫myTcVectorDB.drop_collection("db-qa", "question_768")myTcVectorDB.drop_database("db-qa")# 創建數據庫myTcVectorDB.create_database("db-qa")# 創建索引和embedding,并創建集合index = Index(FilterIndex(name='id', field_type=FieldType.String, index_type=IndexType.PRIMARY_KEY),FilterIndex(name='question', field_type=FieldType.String, index_type=IndexType.FILTER),VectorIndex(name='vector', dimension=768, index_type=IndexType.HNSW,metric_type=MetricType.COSINE, params=HNSWParams(m=16, efconstruction=200)))embedding = Embedding(vector_field='vector', field='text', model=EmbeddingModel.BGE_BASE_ZH)collection = myTcVectorDB.create_collection("db-qa", "question_768", index, embedding)# 批量插入myTcVectorDB.upsert("db-qa", "question_768", [Document(id='0001', text='羅貫中', question='羅貫中'),Document(id='0002', text='吳承恩', question='吳承恩'),Document(id='0003', text='曹雪芹', question='曹雪芹'),Document(id='0004', text='郭富城', question='郭富城')])# 單條插入myTcVectorDB.upsert_one("db-qa", "question_768", id='0005', text='周杰倫', question='周杰倫')myTcVectorDB.upsert_one("db-qa", "question_768", id='0006', text='林俊杰', question='林俊杰')# 刪除0003myTcVectorDB.delete_by_id("db-qa", "question_768", "0003")# 文本搜索(無需向量轉換)text = myTcVectorDB.search_by_text("db-qa", "question_768", "郭富城")# 打印結果print_object(text)# 僅打印idif len(text[0]) > 0:for i in text[0]:print(i['id'])

解釋代碼功能:

  1. 初始化:傳入tcVectorDB的url、username和key,創建myTcVectorDB.

  2. 刪除數據庫db-qa下的數據集question_768,然后刪除數據庫db-qa

  3. 重新創建數據庫db-qa

  4. 指定索引和embedding,并創建集合question_768:這里指定id為主鍵、question為FilterIndex標量索引,vector為VectorIndex向量索引(注意官方文檔說明:指定向量索引字段名,固定為 vector。)因為使用中文檢索,Embedding使用BGE_BASE_ZH。官方文檔的VectorIndex介紹

  5. 批量插入測試數據

  6. 單行插入測試數據

  7. 測試刪除單行數據

  8. 測試文本搜索,并打印結果

MyTcVectorDB庫代碼

import jsonimport tcvectordb
from tcvectordb.model.collection import Embedding
from tcvectordb.model.document import Document, SearchParams
from tcvectordb.model.enum import ReadConsistency, MetricType, FieldType, IndexType, EmbeddingModel
from tcvectordb.model.index import Index, FilterIndex, VectorIndex, HNSWParamsclass MyTcVectorDB:def __init__(self, url: str, username: str, key: str, timeout: int = 30):self._client = tcvectordb.VectorDBClient(url=url, username=username, key=key,read_consistency=ReadConsistency.EVENTUAL_CONSISTENCY, timeout=timeout)def create_database(self, database_name: str):"""Create a database:param database_name: database name:return: database"""return self._client.create_database(database_name=database_name)def drop_database(self, database_name: str):"""Drop a database:param database_name: database name:return: result"""return self._client.drop_database(database_name=database_name)def create_collection(self, db_name: str, collection_name: str, index: Index, ebd: Embedding):db = self._client.database(db_name)# 第二步,創建 Collectioncoll = db.create_collection(name=collection_name,shard=1,replicas=0,description='this is a collection of question embedding',index=index,embedding=ebd)return colldef drop_collection(self, db_name: str, collection_name: str):"""Drop a collection:param db_name: db name:param collection_name: collection name:return: result"""db = self._client.database(db_name)return db.drop_collection(collection_name)def upsert_one(self, db_name: str, collection_name: str, **kwargs):"""Upsert one document to collection:param db_name : db name:param collection_name: collection name:param document: Document:return: result"""db = self._client.database(db_name)coll = db.collection(collection_name)res = coll.upsert(documents=[Document(**kwargs)])return resdef upsert(self, db_name: str, collection_name: str, documents):"""Upsert documents to collection:param db_name : db name:param collection_name: collection name:param documents: list of Document:return: result"""db = self._client.database(db_name)coll = db.collection(collection_name)res = coll.upsert(documents=documents)return resdef search_by_text(self, db_name: str, collection_name: str, text: str, limit: int = 10):"""Search documents by text:param db_name : db name:param collection_name: collection name:param text: text:return: result"""db = self._client.database(db_name)coll = db.collection(collection_name)# searchByText 返回類型為 Dict,接口查詢過程中 embedding 可能會出現截斷,如發生截斷將會返回響應 warn 信息,如需確認是否截斷可以# 使用 "warning" 作為 key 從 Dict 結果中獲取警告信息,查詢結果可以通過 "documents" 作為 key 從 Dict 結果中獲取res = coll.searchByText(embeddingItems=[text],params=SearchParams(ef=200),limit=limit)return res.get('documents')def delete_by_id(self, db_name: str, collection_name: str, document_id):"""Delete document by id:param db_name : db name:param collection_name: collection name:param document_id: document id:return: result"""db = self._client.database(db_name)coll = db.collection(collection_name)res = coll.delete(document_ids=[document_id])return resdef print_object(obj):"""Print object"""for elem in obj:# ensure_ascii=False 保證中文不亂碼if hasattr(elem, '__dict__'):print(json.dumps(vars(elem), indent=4, ensure_ascii=False))else:print(json.dumps(elem, indent=4, ensure_ascii=False))

開始動手使用Tencent Cloud VectorDB在項目中替換Milvus

1、創建問題庫db-qa和集合question_768

與測試代碼基本一致

    # 初始化myTcVectorDB = MyTcVectorDB("http://****tencentclb.com:30000", "root","2epSOV3HK6tiyALo6UqE3mGVMbpP*******")# 創建數據庫myTcVectorDB.create_database("db-qa")# 創建索引和embedding,并創建集合index = Index(FilterIndex(name='id', field_type=FieldType.String, index_type=IndexType.PRIMARY_KEY),FilterIndex(name='question', field_type=FieldType.String, index_type=IndexType.FILTER),VectorIndex(name='vector', dimension=768, index_type=IndexType.HNSW,metric_type=MetricType.COSINE, params=HNSWParams(m=16, efconstruction=200)))embedding = Embedding(vector_field='vector', field='text', model=EmbeddingModel.BGE_BASE_ZH)collection = myTcVectorDB.create_collection("db-qa", "question_768", index, embedding)

2、游戲端和后臺文本向量搜索,用MyTcVectorDB替換Milvus

兩處代碼基本一致。這里去掉文本轉向量的步驟,因為TcVectorDB支持Embedding

    # 獲取問題轉換后的向量# success, vector = get_vector_from_text(question)# if not success:#     return {"code": -1, "id": 0, "answer": "向量計算失敗"}# results = questionCollection.search(vector, limit)results = myVectorDB.search_by_text("db-qa", "question_768", question, limit)...

上面代碼需要注意一點,騰訊向量數據的search結果與milvus的搜索結果是不一樣的,需要做一下適配。

3、重建向量數據庫

問答緩存的數據保存在mysql數據庫,向量數據庫主要作用是向量搜索。如果更換向量庫,只需要重建向量庫即可。下面代碼:

  1. 從mysql中獲取所有的問題
  2. 遍歷所有問答
  3. 把問題作為向量索引,問答的id為標量索引插入向量庫中
    當前mysql數據庫中有大幾千條數據,重新構建向量就耗時10分鐘左右。
def rebuild_vector():# 查找所有的數據select_all = qaTable.select_all_qa()# 遍歷所有的數據for qa in select_all:insertId = qa[0]question = qa[1]timestamp = int(time.time())print(question)# 計算向量# 更新向量# success, vector = get_vector_from_text(question)# if not success:#     # 向量計算失敗,question#     logging.error("向量計算失敗,insertId:%s, question:%s", insertId, question)#     continue# # 刪除原有的向量# questionCollection.delete_question(insertId)# # 插入新的向量# questionCollection.insert_question(insertId, vector, question, timestamp)myVectorDB.delete_by_id("db-qa", "question_768", str(insertId))myVectorDB.upsert_one("db-qa", "question_768", id=str(insertId), text=question, question=question)return "重建向量庫成功"

4、修改后臺展示,看下修改后的效果圖更換騰訊云向量庫

  • 使用的文本轉向量的模型是:BGE_BASE_ZH
  • 向量索引是:VectorIndex(name=‘vector’, dimension=768, index_type=IndexType.HNSW, metric_type=MetricType.COSINE, params=HNSWParams(m=16, efconstruction=200))
  • 搜索文本返回結果代表的是相似度,保存在score中。

總結:

  1. 使用騰訊向量數據庫要比使用Milvus更加簡單易用,無需自己部署服務器。
  2. 騰訊云向量庫支持主流Embedding,直接支持文本向量搜索,避免自己部署Embedding模型,并避免調用文本轉向量的過程。對于開發者來說非常便利。
    如果是個人,或者小型項目開發,非常值得使用騰訊云數據庫。如果是大型項目,不缺錢的話也非常推薦使用騰訊云數據庫,穩定、高效且安全。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164470.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164470.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164470.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

rsync配置和守護進程實踐

目錄 一、rsync概念 1.rsync簡介 2.rsync特點 3、增量和全局傳輸 二、Rsync工作方式 1.準備好rsync備份服務器 2.本地的數據傳輸模式 3.遠程的數據傳輸模式 4.rsync數據推拉模式 三、實踐 1.準備三臺虛擬機 2.都安裝rsync服務 3.拉取遠程文件 3.推送文件 4.rsyn…

Oracle用戶(User)和表空間(Tablespace)

3. 用戶和表空間 3.1. 用戶 1)概念 Oracle數據庫中,用戶(User)是訪問數據庫的途徑和認證方式,同時,用戶也是數據庫對象的邏輯集合。我們通過數據庫用戶和密碼來登錄數據庫,然后,可以在該用戶下創建和操作數據庫對象。 2)創建和配置 創建Oracle用戶,需要具備創建…

python系統編程

文章目錄 系統編程系統工具概述sys模塊os模塊 腳本運行上下文當前工作路徑命令行參數shell環境變量標準流 文件和目錄工具文件工具目錄工具 并行系統工具進程分支線程 系統編程 系統工具 概述 python系統模塊: 模塊名作用*sys負責導出與怕以后呢解釋器本身相關的組件*os包含…

Django DRF序列化器serializer

以下案例由淺到深&#xff0c;逐步深入&#xff0c;通過實例介紹了序列化器的使用方法&#xff0c;和其中遇到的常見問題的解決。 一、序列化器serializers.Serializer 1、urls.py urlpatterns [path("api/<str:version>/depart/",views.DepartView.as_vie…

緩存雪崩、擊穿、穿透及解決方案_保證緩存和數據庫一致性

文章目錄 緩存雪崩、擊穿、穿透1.緩存雪崩造成緩存雪崩解決緩存雪崩 2. 緩存擊穿造成緩存擊穿解決緩存擊穿 3.緩存穿透造成緩存穿透解決緩存穿透 更新數據時&#xff0c;如何保證數據庫和緩存的一致性&#xff1f;1. 先更新數據庫&#xff1f;先更新緩存&#xff1f;解決方案 2…

【問題解決】RuntimeError: apex.optimizers.FusedSGD requires cuda extension 問題解決

在使用 apex 庫時&#xff0c;按照官方的方式安裝后&#xff0c;雖然安裝成功&#xff0c;但調用的時候會報錯如下&#xff0c;也就是說其實沒有成功安裝可調用 cuda 的 apex&#xff1a; RuntimeError: apex.optimizers.FusedSGD requires cuda extension我找了很多解決方式&…

【藍橋杯省賽真題46】Scratch魔術表演 藍橋杯scratch圖形化編程 中小學生藍橋杯省賽真題講解

目錄 scratch魔術表演 一、題目要求 編程實現 二、案例分析 1、角色分析

微信小程序bindtap和catchtap的區別?

子元素用bindtap綁定事件后&#xff0c;執行的時候&#xff0c;會冒泡到父元素&#xff08;觸發父親元素上綁定的bindtap事件&#xff09; 如果不想冒泡到父元素&#xff0c;可以用catchtap代替 bindtap事件綁定不會阻止冒泡事件向上冒泡 catchtap事件綁定可以阻止冒泡事件向上…

centos 7.7 安裝Python-3.7.4

一、安裝PYTHON 編譯依賴包 1.1 首先安裝gcc編譯器&#xff0c;gcc有些系統版本已經默認安裝&#xff0c;通過 gcc --version 查看&#xff0c;沒安裝的先安裝gcc&#xff0c; yum -y install gcc glibc make1.2 安裝其它依賴包&#xff0c;&#xff08;注&#xff1a;不要缺…

【雙指針】和為 s 的兩個數字

和為 s 的兩個數字 文章目錄 和為 s 的兩個數字題目描述算法思路暴力枚舉雙指針 代碼編寫Java代碼C代碼編寫 LCR 179. 查找總價格為目標值的兩個商品 - 力扣&#xff08;LeetCode&#xff09; 題目描述 購物車內的商品價格按照升序記錄于數組 price。請在購物車中找到兩個商品…

Android修行手冊-超出父布局進行顯示以及超出父布局實現點擊

Unity3D特效百例案例項目實戰源碼Android-Unity實戰問題匯總游戲腳本-輔助自動化Android控件全解手冊再戰Android系列Scratch編程案例軟考全系列Unity3D學習專欄藍橋系列ChatGPT和AIGC &#x1f449;關于作者 專注于Android/Unity和各種游戲開發技巧&#xff0c;以及各種資源分…

shopee數據分析軟件丨探索Shopee數據分析軟件——知蝦

隨著電子商務的快速發展&#xff0c;越來越多的商家和企業開始關注數據分析的重要性。在這個競爭激烈的市場中&#xff0c;了解消費者行為、市場趨勢和競爭對手的策略是取得成功的關鍵。而Shopee數據分析軟件——知蝦&#xff0c;成為了許多商家和企業的首選工具。本文將深入探…

ubuntu20.04 nginx 部署靜態網頁

1、安裝nginx Ubuntu環境下安裝部署Nginx&#xff08;有網&#xff09;_ubuntu 安裝nginx_荒Huang的博客-CSDN博客 2、壓縮并上傳文件到服務器指定位置(unzip命令)&#xff0c;修改nginx配置文件&#xff0c;指定root目錄為文件的目錄&#xff0c;index 值為指定的html文件 …

【拿完年終獎后】想要轉行網絡安全,一定不要錯過這個時間段。

網絡安全&#xff0c;作為當下互聯網行業中較為熱門的崗位&#xff0c;薪資可觀、人才需求量大&#xff0c;作為轉行必考慮。 在這里奉勸所有零基礎想轉行&#xff08;入門&#xff09; 網絡安全的朋友們 在轉行之前&#xff0c;一定要對網絡安全行業做一個大概了解&#xf…

latex通過bib添加參考文獻作者名字有特殊符號如字母上有兩點亂碼解決辦法

一、背景 在使用latex寫英文論文時&#xff0c;一般是通過bib的方式添加參考文獻。但有的參考文獻作者是法國人或其他國家的&#xff0c;名字會有特殊符號&#xff0c;如某個字母上有兩個點&#xff0c;或者聲調符號等等&#xff0c;如下圖所示&#xff1a; 如果不進行特殊操作…

【C++初階】第一站:C++入門基礎(中)

前言&#xff1a; 這篇文章是c入門基礎的第一站的中篇,涉及的知識點 函數重載:函數重載的原理--名字修飾 引用:概念、特性、使用場景、常引用、傳值、傳引用效率比較的知識點 目錄 5. 函數重載 &#xff08;續&#xff09; C支持函數重載的原理--名字修飾(name Mangling) 為什么…

ACE前攝器Proactor

轉載的&#xff0c;已經找不到原文地址了 Proactor是異步模式的網絡處理器&#xff0c;ACE中叫做“前攝器”。 先講幾個概念&#xff1a; 前攝器&#xff08;Proactor&#xff09;&#xff0d;異步的事件多路分離器、處理器&#xff0c;是核心處理類。啟動后由3個線程…

csv文件添加文件內容和讀取

append content to file import numpy as np acc_listnp.array([0.97,0.92,0.93,0.89]) # 注意這個地方添加文件不需要特別聲明是什么文件 file open("result.csv", "a") print("{:.2f}, {:.2f}".format(acc_list.mean(), acc_list.std()), f…

【JavaEE】Spring小練習——存儲和獲取對象

一、題目&#xff1a; 在 Spring 項目中&#xff0c;通過 main 方法獲取到 Controller 類&#xff0c;調用 Controller 里面通過注入的方式調用Service 類&#xff0c;Service 再通過注入的方式獲取到 Repository 類&#xff0c;Repository 類里面有一個方法構建?個 User 對象…

YOLO目標檢測——垃圾檢測數據集下載分享【含對應voc、coco和yolo三種格式標簽】

實際項目應用&#xff1a;智能化垃圾分類系統、垃圾回收和處理領域的優化管理等方面數據集說明&#xff1a;垃圾分類檢測數據集&#xff0c;真實場景的高質量圖片數據&#xff0c;數據場景豐富&#xff0c;含報紙、蛋殼、礦泉水瓶、電池、拉鏈頂罐、塑料餐盒、紙質藥盒、香蕉皮…