中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
大模型RAG實戰(zhàn)|構(gòu)建知識庫:文檔和網(wǎng)頁的加載、轉(zhuǎn)換、索引與存儲


今天,開始寫一個新的系列《大模型RAG實戰(zhàn)》。上個月我在2篇文章中,介紹了如何使用LlamaIndex框架,通過少量代碼,實現(xiàn)本地可部署和運行的大模型RAG問答系統(tǒng)。我們要開發(fā)一個生產(chǎn)級的系統(tǒng),還需要對LlamaIndex的各個組件和技術(shù)進行深度的理解、運用和調(diào)優(yōu)。本系列將會聚焦在如何讓系統(tǒng)實用上,包括:知識庫的管理,檢索和查詢效果的提升,使用本地化部署的模型等主題。我將會講解相關(guān)的組件和技術(shù),輔以代碼示例。最終這些文章中的代碼將形成一套實用系統(tǒng)。

過去一年,大模型的發(fā)展突飛猛進。月之暗面的Kimi爆火,Llama3開源發(fā)布,大模型各項能力提升之大有目共睹。

對于大模型檢索增強生成(RAG)系統(tǒng)來說,我們越來越認識到,其核心不在于模型的能力,而是在于如何更好地構(gòu)建和使用知識庫,提升檢索的效能。

 1 

知識庫的三類數(shù)據(jù)

無論是企業(yè)還是個人,我們構(gòu)建知識庫,自然希望高質(zhì)量的數(shù)據(jù)越多越好。這些數(shù)據(jù)主要分為三類。

  • 文件:電腦上為數(shù)眾多的文件資料,包括方案、文稿、產(chǎn)品資料等,通常為PDF、DOCX、PPT等格式

  • 網(wǎng)頁:收集的網(wǎng)頁信息,比如我們在微信上打開和閱讀的公眾號文章。如果覺得這些文章有用,會收藏起來

  • 數(shù)據(jù)庫:保存在各種數(shù)據(jù)庫中的文本信息,比如企業(yè)內(nèi)部的信息系統(tǒng),會記錄用戶提出的問題與相應的解決方案

對于個人用戶,建立個人知識庫,主要是電腦上的文件資料和收藏的網(wǎng)頁信息。而對于企業(yè)來說,接入和利用已有信息系統(tǒng)的數(shù)據(jù)庫中的文本數(shù)據(jù),也非常關(guān)鍵。

LlamaIndex是一個專門針對構(gòu)建RAG系統(tǒng)開發(fā)的開源數(shù)據(jù)框架,對于以上三類數(shù)據(jù)的處理,都提供了很好的支持

 2 

數(shù)據(jù)處理的四個步驟

無論是哪一類數(shù)據(jù),LlamaIndex處理數(shù)據(jù)的過程,都分為四步:

1)加載數(shù)據(jù)(Load)

LlamaIndex提供了眾多數(shù)據(jù)接入組件(Data Connector),可以加載文件、網(wǎng)頁、數(shù)據(jù)庫,并提取其中的文本,形成文檔(Document)。未來還將能提取圖片、音頻等非結(jié)構(gòu)化數(shù)據(jù)。

最常用的是SimpleDirectoryReader,用來讀取文件系統(tǒng)指定目錄中的PDF、DOCX、JPG等文件。

我們在LlamaHub上,可以找到數(shù)百個數(shù)據(jù)接入組件,用來加載各種來源與格式的數(shù)據(jù),比如電子書epub格式文件的接入組件。

2) 轉(zhuǎn)換數(shù)據(jù)(Transform)

類似傳統(tǒng)的ETL,轉(zhuǎn)換數(shù)據(jù)是對文本數(shù)據(jù)的清洗和加工。通常,輸入是文檔(Document),輸出是節(jié)點(Node)。

數(shù)據(jù)處理的過程,主要是將文本分割為文本塊(Chunk),并通過嵌入模型,對文本塊進行嵌入(Embedding)。同時,可提取元數(shù)據(jù)(Metadata),例原文件的文件名和路徑。

這里有兩個重要的參數(shù),chunk_size和chunk_overlap,分別是文本塊分割的大小,和相互之間重疊的大小。我們需要調(diào)整這些參數(shù),從而達到最好的檢索效果。

3)建立索引(Index)

索引是一種數(shù)據(jù)結(jié)構(gòu),以便于通過大語言模型(LLM)來查詢生成的節(jié)點。

最常使用的是向量存儲索引(Vector Store Index),這種方式把每個節(jié)點(Node)的文本,逐一創(chuàng)建向量嵌入(vector embeddings),可以理解是文本語義的一種數(shù)字編碼。 

不同于傳統(tǒng)的關(guān)鍵詞匹配,通過向量檢索,比如余弦相似度,我們可以找到語義相近的文本,盡管在文字上有可能截然不同。

4)存儲數(shù)據(jù)(Store)

默認情況下,以上操作生成的數(shù)據(jù)都保存在內(nèi)存中。要避免每次重來,我們需要將這些數(shù)據(jù)進行持久化處理。

LlamaIndex 提供了內(nèi)置的persisit()方法,將索引數(shù)據(jù)持久化保存在磁盤文件中。更常見的做法是通過索引存儲器(Index Store),將索引保存在向量數(shù)據(jù)庫中,如Chroma、LanceDB等。

知識庫的管理,不僅要保存索引數(shù)據(jù),也要保存所有文檔(Document)及其提取的節(jié)點(Node)。

LLamaIndex提供了文檔存儲器(Document Store),把這些文本數(shù)據(jù)保存在MongoDB、Redis等NoSQL數(shù)據(jù)庫中,這樣我們可以對每一個節(jié)點進行增刪改查。

 3 

代碼實現(xiàn)示例

下面結(jié)合代碼,介紹構(gòu)建知識庫的過程。

我們將使用LlamaIndex來加載和轉(zhuǎn)換文檔和網(wǎng)頁數(shù)據(jù),建立向量索引,并把索引保存在Chroma,把文檔和節(jié)點保存在MongoDB

示例1:加載本地文件

對于在本地文件系統(tǒng)中的文件,LlamaIndex提供了非常簡便的方法來讀?。?strong>SimpleDirectoryReader。

我們只需要將已有的文件,放在指定的目錄下,比如./data,通過這個方法就可以全部加載該目錄下的所有文件,包括子目錄中的文件。

from llama_index.core import SimpleDirectoryReaderdocuments = SimpleDirectoryReader(input_dir='./data', recursive=True).load_data() print(f'Loaded {len(documents)} Files')

如果,我們在知識庫中上傳了新的文件,還可以指定加載這個文件,而非讀取整個目錄。

SimpleDirectoryReader(input_files=['path/to/file1', 'path/to/file2'])

文件加載后,LlamaIndex會逐一提取其中的文本信息,形成文檔(Document)。通常一個文件對應一個文檔。

示例2:加載網(wǎng)頁信息

LlamaIndex讀取和加載網(wǎng)頁信息也很簡單。這里,我們用到另一個工具SimpleWebPageReader。

給出一組網(wǎng)頁的URL,我們使用這個工具可以提取網(wǎng)頁中的文字信息,并分別加載到文檔(Document)中。

pages = ['https://mp.weixin.qq.com/s/LQNWNp7nI_hI1iFpuZ9Dfw', 'https://mp.weixin.qq.com/s/m8eI2czdXT1knX-Q20T6OQ', 'https://mp.weixin.qq.com/s/prnDzOQ8HjUmonNp0jhRfw', 'https://mp.weixin.qq.com/s/YB44--865vYkmUJhEv73dQ', 'https://mp.weixin.qq.com/s/SzON91-fZgkQvzdzkXJoCA', 'https://mp.weixin.qq.com/s/zVlKUxJ_C6GjTh0ePS-f8w', 'https://mp.weixin.qq.com/s/gXlX_8mKnQSmI0R1me40Ag', 'https://mp.weixin.qq.com/s/z9eV8Q8TJ4c-IhvJ1Ag34w']
documents = SimpleWebPageReader(html_to_text=True).load_data( pages)print(f'Loaded {len(documents)} Web Pages')

代碼中我給出的網(wǎng)頁,是我寫的《大衛(wèi)說流程》系列文章。你可以改為任何你想讀取的網(wǎng)頁。未來,你可以針對這些網(wǎng)頁內(nèi)容來向大模型提問。

使用這個工具,我們需要安裝llama-index-readers-web和html2text組件。為了行文簡潔,未來不再說明。你可以在運行代碼時根據(jù)提示,安裝所需的Python庫和組件。

示例3:分割數(shù)據(jù)成塊

接下來,我們通過文本分割器(Text Splitter)將加載的文檔(Document)分割為多個節(jié)點(Node)。

LlamaIndex使用的默認文本分割器是SentenceSplitter。我們可以設(shè)定文本塊的大小是256,重疊的大小是50。文本塊越小,那么節(jié)點的數(shù)量就越多。

from llama_index.core.node_parser import SentenceSplitternodes = SentenceSplitter(chunk_size=256, chunk_overlap=50).get_nodes_from_documents(documents)print(f'Load {len(nodes)} Nodes')

之前我介紹過文本分割器Spacy,對中文支持更好。我們可以通過Langchain引入和使用。

from llama_index.core.node_parser import LangchainNodeParserfrom langchain.text_splitter import SpacyTextSplitterspacy_text_splitter = LangchainNodeParser(SpacyTextSplitter( pipeline='zh_core_web_sm', chunk_size = 256, chunk_overlap = 50))


示例4:數(shù)據(jù)轉(zhuǎn)換管道與知識庫去重

上一步給出的數(shù)據(jù)轉(zhuǎn)換方法,其實并不實用。問題在于沒有對文檔進行管理。我們重復運行時,將會重復加載,導致知識庫內(nèi)重復的內(nèi)容越來越多。

為了解決這個問題,我們可以使用LlamaIndex提供的數(shù)據(jù)采集管道(Ingestion Pipeline)的功能,默認的策略為更新插入(upserts,實現(xiàn)對文檔進行去重處理。

from llama_index.core.ingestion import IngestionPipelinepipeline = IngestionPipeline(    transformations=[        spacy_text_splitter,        embed_model,    ],    docstore=MongoDocumentStore.from_uri(uri=MONGO_URI),    vector_store=chroma_vector_store,)nodes = pipeline.run(documents=documents)print(f'Ingested {len(nodes)} Nodes')

示例5:索引與存儲的配置

在上面的數(shù)據(jù)采集管道的代碼示例中,我們配置了用來生成向量索引的嵌入模型(embed_model),以及采用Chroma作為向量庫,MongoDB作為文檔庫,對數(shù)據(jù)進行持久化存儲。

嵌入模型的配置如下。這里我們通過之前介紹過的HugginFace的命令行工具,將BAAI的bge-small-zh-v1.5嵌入模型下載到本地,放在“l(fā)ocalmodels”目錄下。

from llama_index.embeddings.huggingface import HuggingFaceEmbeddingembed_model = HuggingFaceEmbedding(model_name='./localmodels/bge-small-zh-v1.5')

然后配置向量庫,Chroma將把數(shù)據(jù)存儲在我們指定的“storage”目錄下。

import chromadbfrom llama_index.vector_stores.chroma import ChromaVectorStoredb = chromadb.PersistentClient(path='./storage')chroma_collection = db.get_or_create_collection('think')chroma_vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

我們可以使用Redis或MongoDB來存儲處理后的文檔、節(jié)點及相關(guān)信息,包括文檔庫(docstore)和索引信息庫(index_store)。

作為示例,我們選用在本機上安裝的MongoDB。

from llama_index.core import StorageContextfrom llama_index.storage.docstore.mongodb import MongoDocumentStorefrom llama_index.storage.index_store.mongodb import MongoIndexStore
MONGO_URI = 'mongodb://localhost:27017'
storage_context = StorageContext.from_defaults( docstore=MongoDocumentStore.from_uri(uri=MONGO_URI), index_store=MongoIndexStore.from_uri(uri=MONGO_URI), vector_store=chroma_vector_store,)

示例6:構(gòu)建知識庫

現(xiàn)在,我們可以將此前的數(shù)據(jù)采集管道生成的文檔和節(jié)點,載入到文檔知識庫中(docstore)。

storage_context.docstore.add_documents(nodes)print(f'Load {len(storage_context.docstore.docs)} documents into docstore')

這步完成后,我們在MongoDB中,可以找到一個名為“db_docstore”的數(shù)據(jù)庫,里面有三張表,分別是:

  • docstore/data

  • docstore/metadata

  • docstore/ref_doc_info

我們可以通過MongoDB,來查詢相關(guān)的文檔和節(jié)點,元數(shù)據(jù)以及節(jié)點之間的關(guān)系信息。

未來,當你有更多的文件和網(wǎng)頁需要放入知識庫中,只需要遵循以上的步驟加載和處理。

示例7:實現(xiàn)RAG問答

完成知識庫的構(gòu)建之后,我們可以設(shè)定使用本地的LLM,比如通過Ollama下載使用Gemma 2B模型。

然后,加載索引,生成查詢引擎(Query Engine),你就可以針對知識庫中的內(nèi)容進行提問了。

from llama_index.llms.ollama import Ollamallm_ollama = Ollama(model='gemma:2b', request_timeout=600.0)Settings.llm = llm_ollama
from llama_index.core import VectorStoreIndexindex = VectorStoreIndex.from_vector_store( vector_store=chroma_vector_store, )
query_engine = index.as_query_engine()response = query_engine.query('流程有哪三個特征?')

以上,主要介紹了使用LlamaIndex構(gòu)建知識庫的過程。

未來,我們可以結(jié)合Streamlit、Flask等前端框架,進一步開發(fā)成一個完善的知識庫管理系統(tǒng),以便對知識內(nèi)容進行持續(xù)的增加與更新,并支持靈活的配置文本分割的各項參數(shù)和選擇嵌入模型。

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
大模型系列——解讀RAG
專為數(shù)據(jù)庫打造:DB-GPT用私有化LLM技術(shù)定義數(shù)據(jù)庫下一代交互方式
搭建個人CFD知識庫
談談如何構(gòu)建一個大型語言模型LLM應用程序【有示例】
文檔搜索
個人知識管理的方法和工具
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服