凡客誠(chéng)品是品牌嗎廣州seo外包
一、背景
大語(yǔ)言模型應(yīng)用未來(lái)一定是開(kāi)發(fā)熱點(diǎn),現(xiàn)在一個(gè)比較成功的應(yīng)用是外掛知識(shí)庫(kù)。相比chatgpt這個(gè)知識(shí)庫(kù)比較龐大,效果比較好的接口。外掛知識(shí)庫(kù)+大模型的方式可以在不損失太多效果的條件下獲得數(shù)據(jù)安全。
二、原理
現(xiàn)在比較流行的一個(gè)方案是langchain+chatglm,這已經(jīng)算是一個(gè)成品了,也可以考慮自己上手捏一下泥巴,langchain學(xué)習(xí)成本有點(diǎn)高,可以直接利用prompt來(lái)完成問(wèn)問(wèn)題會(huì)簡(jiǎn)單很多。具體方案我參考了這個(gè)文章:大模型外掛(向量)知識(shí)庫(kù) - 知乎 (zhihu.com)?基本的思路簡(jiǎn)化成這張圖
?簡(jiǎn)單的說(shuō)就是根據(jù)用戶問(wèn)題,從知識(shí)庫(kù)獲取與“問(wèn)題”相關(guān)的“文檔片段”, 讓大模型根據(jù)文檔片段來(lái)回答“問(wèn)題”。其實(shí)這種根據(jù)指定內(nèi)容回答問(wèn)題的模型也是挺成熟的,至少huggingface上就有很多,只不過(guò)那些模型是根據(jù)BERT模型+QA數(shù)據(jù)集微調(diào)好的。我們相信chatglm這類大模型理解問(wèn)題和總結(jié)內(nèi)容的能力一定更強(qiáng)。
這里就涉及到一個(gè)如何獲取“問(wèn)題”相關(guān)的“文檔片段”的過(guò)程了,其實(shí)可以直接用文本檢索方式,但傳統(tǒng)的全文檢索由于是詞的匹配,因此對(duì)純粹的問(wèn)句效果可能不好。因此現(xiàn)在主流的方式是用向量匹配,就是把“問(wèn)題”和知識(shí)庫(kù)的文本都轉(zhuǎn)成向量,再用向量的近似搜索獲取更為相關(guān)的結(jié)果。
應(yīng)用這種方式會(huì)很容易想到一個(gè)問(wèn)題,也是上面知乎文章中提到的對(duì)稱語(yǔ)義檢索。即一定會(huì)把與“問(wèn)題”接近的語(yǔ)句作為第一返回,它只是文字表述和問(wèn)題一樣,但并不是問(wèn)題的答案。例如
也許這不是個(gè)問(wèn)題,因?yàn)檎l(shuí)會(huì)在知識(shí)庫(kù)里留下大量問(wèn)句呢?或者你可以通過(guò)預(yù)處理把問(wèn)題和大量正文綁定起來(lái)就不會(huì)匹配出“問(wèn)題”了。所以使用向量的效果到底比純粹的全文檢索是否更好我也不清楚,畢竟檢索效果還和預(yù)處理時(shí)候文本片段的切割、向量轉(zhuǎn)換、向量最近鄰查詢效果 有關(guān)系。
三、實(shí)現(xiàn)
這里我直接使用了text2vec + chromadb簡(jiǎn)單實(shí)現(xiàn)。text2vec負(fù)責(zé)對(duì)文本轉(zhuǎn)為向量, chromadb負(fù)責(zé)進(jìn)行向量檢索。
text2vec地址在shibing624/text2vec-base-chinese · Hugging Face?,預(yù)訓(xùn)練模型不算大
chromadb是一個(gè)新出的向量數(shù)據(jù)庫(kù),很多功能不完善,只是為了快速地體驗(yàn)一下向量存儲(chǔ)檢索功能,🔑 Getting Started | Chroma (trychroma.com)
本來(lái)功能是想做成一個(gè)獨(dú)立于大模型服務(wù)的服務(wù):
?但是還是有點(diǎn)麻煩,最后還是選擇直接在chatglm原生的客戶端里直接加向量存儲(chǔ)和檢索的功能。就是直接在內(nèi)存里完成,也就是下圖綠色的部分就行了。
?
?代碼就增加三處。1. 知識(shí)庫(kù)讀取、轉(zhuǎn)換、存chromadb;2. 問(wèn)題轉(zhuǎn)換、檢索chromadb、獲得文本片段;3. prompt改成“問(wèn)題+文本片段”
#.....
import glob
import chromadb
from text2vec import SentenceModel#.....@st.cache_resource
def get_vectordb():model = SentenceModel('shibing624/text2vec-base-chinese')client = chromadb.Client()texts = []for filename in glob.glob(f"texts/*.txt"):with open(filename, encoding='utf-8') as f:texts.append(f.read())embeddings = model.encode(texts).tolist()collection = client.get_or_create_collection("testname")ids = [f'id{x+1}' for x in range(len(texts))]collection.add(ids=ids, embeddings=embeddings, documents=texts)return collection, modeldef query_related(text:str, model:SentenceModel, coll):embedding = model.encode(text).tolist()result = coll.query( query_embeddings=embedding, n_results=1)['documents']return result[0][0]#.....
collection, t2v = get_vectordb()#...改大max_length
max_length = st.sidebar.slider('max_length', 0, 32768, 32768, step=1
)#.....
if button:input_placeholder.markdown(prompt_text)related_text = query_related(prompt_text, t2v, collection)prompt_text = f"'''\n{related_text}\n''' \n請(qǐng)從上文提取信息并回答:“{prompt_text}”"
代碼難度不大,一開(kāi)始讀取text2vec時(shí)候就把本地texts目錄里的文本讀取出來(lái)并轉(zhuǎn)為向量。這里我是每一篇文本轉(zhuǎn)一個(gè)向量,查詢到最近似的也只保留首個(gè)文檔。 可能按段落分割更好,如果是按段落,那么查詢到多個(gè)文本片段可以按需要拼接起來(lái)。
我把代碼開(kāi)源在gitee上:llm_simple-kb-plugin: chatglm2外掛知識(shí)庫(kù)的簡(jiǎn)單實(shí)現(xiàn), 這是直接在web_demo2.py上修改的 (gitee.com)
四、結(jié)果
問(wèn)個(gè)問(wèn)題:“向量數(shù)據(jù)庫(kù)是什么?” ,原版chatglm2的回答:
很顯然是這些年與數(shù)據(jù)庫(kù)信息相關(guān)內(nèi)容的總結(jié)。
這是增加了相關(guān)文章以后的效果:
?感覺(jué)chatglm2-6B的總結(jié)能力還是有點(diǎn)弱,我的文章列了12個(gè)向量數(shù)據(jù)庫(kù),這里并沒(méi)有提取完,雖然它只會(huì)給10條,但是前3個(gè)不知道哪里推導(dǎo)出來(lái)的。
五、總結(jié)
實(shí)驗(yàn)出來(lái)效果比想象中還是要差,我猜測(cè)原因主要有兩個(gè),一是大模型參數(shù)不夠,涌現(xiàn)不出來(lái)。二是涉及對(duì)信息加工的中間過(guò)程,越多參與的中間步驟造成的精度損失會(huì)成倍放大。目前看起來(lái)大模型應(yīng)用要實(shí)現(xiàn)工業(yè)化要求,可能還是比想象中要難,這只是一個(gè)外掛知識(shí)庫(kù)讓大模型做總結(jié)的功能而已,但是未來(lái)想象空間還是很大的,我也相信如我開(kāi)篇所說(shuō):大語(yǔ)言模型應(yīng)用未來(lái)一定會(huì)是開(kāi)發(fā)熱點(diǎn)。