原標題:基于亞馬遜云科技的大語言模型知識問答應用落地實踐
隨著大語言模型效果明顯提升,其相關的應用不斷涌現(xiàn)呈現(xiàn)出越來越火爆的趨勢。其中一種比較被廣泛關注的技術路線是大語言模型(LLM)+知識召回(Knowledge Retrieval)的方式,在私域知識問答方面可以很好的彌補通用大語言模型的一些短板,解決通用大語言模型在專業(yè)領域回答缺乏依據(jù)、存在幻覺等問題。其基本思路是把私域知識文檔進行切片然后向量化后續(xù)通過向量檢索進行召回,再作為上下文輸入到大語言模型進行歸納總結(jié)。
在這個技術方向的具體實踐中,知識庫可以采取基于倒排和基于向量的兩種索引方式進行構(gòu)建,它對于知識問答流程中的知識召回這步起關鍵作用,和普通的文檔索引或日志索引不同,知識的向量化需要借助深度模型的語義化能力,存在文檔切分,向量模型部署&推理等額外步驟。知識向量化建庫過程中,不僅僅需要考慮原始的文檔量級,還需要考慮切分粒度,向量維度等因素,最終被向量數(shù)據(jù)庫索引的知識條數(shù)可能達到一個非常大的量級,可能由以下兩方面的原因引起:
各個行業(yè)的既有文檔量很高,如金融、醫(yī)藥、法律領域等,新增量也很大。
為了召回效果的追求,對文檔的切分常常會采用按句或者按段進行多粒度的冗余存貯。
這些細節(jié)對知識向量數(shù)據(jù)庫的寫入和查詢性能帶來一定的挑戰(zhàn),為了優(yōu)化向量化知識庫的構(gòu)建和管理,基于亞馬遜云科技的服務,構(gòu)建了如下圖的知識庫構(gòu)建流程:
通過S3 Bucket的Handler實時觸發(fā)Lambda啟動對應知識文件入庫的Glue job
Glue Job中會進行文檔解析和拆分,并調(diào)用SageMaker的Embedding模型進行向量化
通過Bulk方式注入到Amazon OpenSearch中去
并對整個流程中涉及的多個方面,包括如何進行知識向量化,向量數(shù)據(jù)庫調(diào)優(yōu)總結(jié)了一些 實踐和心得。
知識向量化
文檔拆分
知識向量化的前置步驟是進行知識的拆分,語義完整性的保持是最重要的考量。分兩個方面展開討論。該如何選用以下兩個關注點分別總結(jié)了一些經(jīng)驗:
a. 拆分片段的方法
關于這部分的工作,Langchain作為一種流行的大語言模型集成框架,提供了非常多的Document Loader和Text Spiltters,其中的一些實現(xiàn)具有借鑒意義,但也有不少實現(xiàn)效果是重復的。
目前使用較多的基礎方式是采用Langchain中的RecursiveCharacterTextSplitter,屬于是Langchain的默認拆分器。它采用這個多級分隔字符列表——[“\n\n”, “\n”, ” “, “”]來進行拆分,默認先按照段落做拆分,如果拆分結(jié)果的chunk_size超出,再繼續(xù)利用下一級分隔字符繼續(xù)拆分,直到滿足chunk_size的要求。
但這種做法相對來說還是比較粗糙,還是可能會造成一些關鍵內(nèi)容會被拆開。對于一些其他的文檔格式可以有一些更細致的做法。
FAQ文件,必須按照一問一答粒度拆分,后續(xù)向量化的輸入可以僅僅使用問題,也可以使用問題+答案
Markdown文件,”#”是用于標識標題的特殊字符,可以采用MarkdownHeaderTextSplitter作為分割器,它能更好的保證內(nèi)容和標題對應的被提取出來。
PDF文件,會包含更豐富的格式信息。Langchain里面提供了非常多的Loader,但Langchain中的PDFMinerPDFasHTMLLoader的切分效果上會更好,它把PDF轉(zhuǎn)換成HTML,通過HTML的
塊進行切分,這種方式能保留每個塊的字號信息,從而可以推導出每塊內(nèi)容的隸屬關系,把一個段落的標題和上一級父標題關聯(lián)上,使得信息更加完整。
b. 模型對片段長度的支持
由于拆分的片段后續(xù)需要通過向量化模型進行推理,所以必須考慮向量化模型的Max_seq_length的限制,超出這個限制可能會導致出現(xiàn)截斷,導致語義不完整。從支持的Max_seq_length來劃分,目前主要有兩類Embedding模型,如下表所示(這四個是有過實踐經(jīng)驗的模型)。
模型名稱 |
Max_seq_length |
paraphrase-multilingual-mpnet-base-v2(sbert.net) |
128 |
text2vec-base-chinese(text2vec) |
128 |
text2vec-large-chinese(text2vec) |
512 |
text-embedding-ada-002(openai) |
8192 |
這里的Max_seq_length是指Token數(shù),和字符數(shù)并不等價。依據(jù)之前的測試經(jīng)驗,前三個模型一個token約為1.5個漢字字符左右。而對于大語言模型,如chatglm,一個token一般為2個字符左右。如果在切分時不方便計算token數(shù),也可以簡單按照這個比例來簡單換算,保證不出現(xiàn)截斷的情況。
前三個模型屬于基于Bert的Embedding模型,OpenAI的text-embedding-ada-002模型是基于GPT3的模型。前者適合句或者短段落的向量化,后者OpenAI的SAAS化接口,適合長文本的向量化,但不能私有化部署。
可以根據(jù)召回效果進行驗證選擇。從目前的實踐經(jīng)驗上看text-embedding-ada-002對于中文的相似性打分排序性可以,但區(qū)分度不夠(集中0.7左右),不太利于直接通過閾值判斷是否有相似知識召回。
另外,對于長度限制的問題也有另外一種改善方法,可以對拆分的片段進行編號,相鄰的片段編號也臨近,當召回其中一個片段時,可以通過向量數(shù)據(jù)庫的range search把附近的片段也召回回來,也能保證召回內(nèi)容的語意完整性。
向量化模型選擇
前面提到四個模型只是提到了模型對于文本長度的支持差異,效果方面目前并沒有非常權(quán)威的結(jié)論?梢酝ㄟ^leaderboard來了解各個模型的性能,榜上的大多數(shù)的模型的評測還是基于公開數(shù)據(jù)集的benchmark,對于真實生產(chǎn)中的場景benchmark結(jié)論是否成立還需要case by case地來看。但原則上有以下幾方面的經(jīng)驗可以分享:
經(jīng)過垂直領域Finetune的模型比原始向量模型有明顯優(yōu)勢
目前的向量化模型分為兩類,對稱和非對稱。未進行微調(diào)的情況下,對于FAQ建議走對稱召回,也就是Query到Question的召回。對于文檔片段知識,建議使用非對稱召回模型,也就是Query到Answer(文檔片段)的召回。
沒有效果上的明顯的差異的情況下,盡量選擇向量維度短的模型,高維向量(如openai的text-embedding-ada-002)會給向量數(shù)據(jù)庫造成檢索性能和成本兩方面的壓力。
向量化并行
真實的業(yè)務場景中,文檔的規(guī)模在百到百萬這個數(shù)量級之間。按照冗余的多級召回方式,對應的知識條目 可能達到億的規(guī)模。由于整個離線計算的規(guī)模很大,所以必須并發(fā)進行,否則無法滿足知識新增和向量檢索效果迭代的要求。步驟上主要分為以下三個計算階段。
文檔切分并行
計算的并發(fā)粒度是文件級別的,處理的文件格式也是多樣的,如TXT純文本,Markdown,PDF等,其對應的切分邏輯也有差異。而使用Spark這種大數(shù)據(jù)框架來并行處理過重,并不合適。使用多核實例進行多進程并發(fā)處理則過于原始,任務的觀測追蹤上不太方便。所以可以選用AWS Glue的Python shell引擎進行處理。主要有如下好處:
方便的按照文件粒度進行并發(fā),并發(fā)度簡單可控。具有重試、超時等機制,方便任務的追蹤和觀察,日志直接對接到AWS CloudWatch
方便的構(gòu)建運行依賴包,通過參數(shù)–additional-python-modules指定即可,同時Glue Python的運行環(huán)境中已經(jīng)自帶了opensearch_py等依賴
向量化推理并行
由于切分的段落和句子相對于文檔數(shù)量也膨脹了很多倍,向量模型的推理吞吐能力決定了整個流程的吞吐能力。這里采用SageMaker Endpoint來部署向量化模型,一般來說為了提供模型的吞吐能力,可以采用GPU實例推理,以及多節(jié)點Endpoint/Endpoint彈性伸縮能力,Server-Side/Client-Side Batch推理能力這些都是一些有效措施。具體到離線向量知識庫構(gòu)建這個場景,可以采用如下幾種策略:
GPU實例部署:向量化模型CPU實例是可以推理的。但離線場景下,推理并發(fā)度高,GPU相對于CPU可以達到20倍左右的吞吐量提升。所以離線場景可以采用GPU推理,在線場景CPU推理的策略。
多節(jié)點Endpoint對于臨時的大并發(fā)向量生成,通過部署多節(jié)點Endpoint進行處理,處理完畢后可以關閉
利用Client-Side Batch推理:離線推理時,Client-side batch構(gòu)造十分容易。無需開啟Server-side Batch推理,一般來說Sever-side batch都會有個等待時間,如50ms或100ms,對于推理延遲比較高的大語言模型比較有效,對于向量化推理則不太適用。
OpenSearch批量注入
Amazon OpenSearch的寫入操作,在實現(xiàn)上可以通過bulk批量進行,比單條寫入有很大優(yōu)勢。
向量數(shù)據(jù)庫優(yōu)化
向量數(shù)據(jù)庫選擇哪種近似搜索算法,選擇合適的集群規(guī)模以及集群設置調(diào)優(yōu)對于知識庫的讀寫性能也十分關鍵,主要需要考慮以下幾個方面:
算法選擇
在OpenSearch里,提供了兩種k-NN的算法:HNSW (Hierarchical Navigable Small World)和IVF(Inverted File)。
在選擇k-NN搜索算法時,需要考慮多個因素。如果內(nèi)存不是限制因素,建議優(yōu)先考慮使用HNSW算法,因為HNSW算法可以同時保證latency和recall。如果內(nèi)存使用量需要控制,可以考慮使用IVF算法,它可以在保持類似HNSW的查詢速度和質(zhì)量的同時,減少內(nèi)存使用量。但是,如果內(nèi)存是較大的限制因素,可以考慮為HNSW或IVF算法添加PQ編碼,以進一步減少內(nèi)存使用量。需要注意的是,添加PQ編碼可能會降低準確率。因此,在選擇算法和優(yōu)化方法時,需要綜合考慮多個因素,以滿足具體的應用需求。
集群規(guī)模預估
選定了算法后,可以根據(jù)公式,計算所需的內(nèi)存進而推導出k-NN集群大小
批量注入優(yōu)化
在向知識向量庫中注入大量數(shù)據(jù)時,需要關注一些關鍵的性能優(yōu)化,以下是一些主要的優(yōu)化策略:
Disable refresh interval
增加indexing線程
增加knn內(nèi)存占比
投稿郵箱:chuanbeiol@163.com 詳情請訪問川北在線:http://sanmuled.cn/