大模型之深入探索RAG流程 原創(chuàng)
前言
在上一章【大模型之初識(shí)RAG】中,我們初步了解了RAG的基本概念和原理,并通過代碼實(shí)踐了一個(gè)簡(jiǎn)單的RAG流程。本章我們將基于RAG的基本流程,深入了解??文檔讀取(LOAD)?
??、??文檔切分(SPLIT)?
??、??向量化(EMBED)?
?? 和 ??存儲(chǔ)(STORE)?
? 的每個(gè)環(huán)節(jié),并結(jié)合代碼進(jìn)行常見場(chǎng)景的實(shí)踐。
RAG流程回顧
回顧RAG的流程如上所示,具體代碼見RAG代碼,本章不再贅述。
文檔讀取(LOAD)
簡(jiǎn)介:由于我們的知識(shí)廣泛存在各類文檔中,所以文檔讀取(??LOAD?
??)在RAG系統(tǒng)中承擔(dān)著 ??獲取數(shù)據(jù)?
? 的職責(zé)。
常見文件:
- 文本文件(.txt)
- CSV(.csv)
- PDF(.pdf)
- Word 文檔(.docx)
- Excel 工作簿(.xlsx)
- PPT 演示文稿(.pptx)
- HTML 文件(.html)
- Markdown 文件(.md)
常見的文件處理庫(kù):
- langchain_community.document_loaders
- 在langchain_community的API文檔中有數(shù)十種文件的處理API,除了上述常見的文件之外,還有.srt字幕文件、.ipynb文件、代碼片段等支持。
CSV文件加載器
CSVLoader函數(shù)說明
class langchain_community.document_loaders.csv_loader.CSVLoader(
file_path:Union[str,Path],
source_column:Optional[str]=None,
metadata_columns:Sequence[str]=(),
csv_args:Optional[Dict]=None,
encoding:Optional[str]=None,
autodetect_encoding:bool=False)
說明:
- ?
?file_path?
?:指定要加載的 CSV 文件的路徑
例如:"data/myfile.csv"
- ?
?source_column?
?(可選):指定哪一列作為數(shù)據(jù)的主要來源。
例如:"text"
- ?
?metadata_columns?
?:指定哪些列應(yīng)作為元數(shù)據(jù)加載。
例如:["name", "age"]
- ?
?csv_args?
?(可選):自定義 CSV 加載的行為。
例如:{"delimiter": ";", "header": 0}(指定分隔符為分號(hào),并將第一行作為表頭)
示例
示例1:僅加載.csv文件示例:
from langchain_community.document_loaders import CSVLoader
students_loader = CSVLoader(file_path="testfiles/students.csv")
docs = students_loader.load()
docs
運(yùn)行結(jié)果:
# [Document(metadata={'source': 'testfiles/students.csv', 'row': 0}, page_cnotallow='name: Tom\nage: 12\nscore: 77'),
# Document(metadata={'source': 'testfiles/students.csv', 'row': 1}, page_cnotallow='name: Jerry\nage: 11\nscore: 88'),
# Document(metadata={'source': 'testfiles/students.csv', 'row': 2}, page_cnotallow='name: Jim\nage: 12\nscore: 96')]
說明:
- metadata:文檔元數(shù)據(jù),包括文檔來源、行號(hào)等,用來進(jìn)行溯源使用。
- page_content:文檔內(nèi)容,即文本內(nèi)容。
示例2:加載.csv文件指定列作為元數(shù)據(jù):
from langchain_community.document_loaders import CSVLoader
students_loader = CSVLoader(file_path="testfiles/students.csv", metadata_columns=["name", "score"])
docs = students_loader.load()
docs
運(yùn)行結(jié)果:
# [Document(metadata={'source': 'testfiles/students.csv', 'row': 0, 'name': 'Tom', 'score': '77'}, page_cnotallow='age: 12'),
# Document(metadata={'source': 'testfiles/students.csv', 'row': 1, 'name': 'Jerry', 'score': '88'}, page_cnotallow='age: 11'),
# Document(metadata={'source': 'testfiles/students.csv', 'row': 2, 'name': 'Jim', 'score': '96'}, page_cnotallow='age: 12')]
示例3:使用RAG鏈測(cè)試大模型的知識(shí)理解能力
from langchain_community.document_loaders importCSVLoader
from langchain_core.output_parsers importStrOutputParser
from langchain_core.runnables importRunnablePassthrough
from langchain_chroma importChroma
from langchain_core.prompts importChatPromptTemplate
from utils import get_qwen_models
defformat_docs(docs):
return"\n\n".join(doc.page_content for doc in docs)
# 連接大模型
llm, chat, embed = get_qwen_models()
# 讀取.csv文件
students_loader =CSVLoader(file_path="testfiles/students.csv")
docs = students_loader.load()
# 向量化入庫(kù)
vectorstore =Chroma.from_documents(documents=docs, embedding=embed)
retriever = vectorstore.as_retriever(search_kwargs={"k":2})
prompt =ChatPromptTemplate.from_messages([
("human","""You are an assistant for question-answering tasks.
Use the following pieces of retrieved context to answer the question.
If you don't know the answer, just say that you don't know.
Use three sentences maximum and keep the answer concise.
Question: {question}
Context: {context}
Answer:""")
])
# RAG 鏈
rag_chain =(
{"context": retriever | format_docs,
"question":RunnablePassthrough()}
| prompt
| chat
|StrOutputParser()
)
rag_chain.invoke(input="誰的成績(jī)最高?")
運(yùn)行結(jié)果:
# 'Jerry的成績(jī)最高,得了88分。'
TXT文件加載器
TXTLoader函數(shù)說明
class langchain_community.document_loaders.text.TextLoader(
file_path: Union[str, Path],
encoding: Optional[str] = None,
autodetect_encoding: bool = False)
說明:
- ?
?file_path?
?:指定要加載的文本文件的路徑。 - ?
?encoding?
?(可選):指定文本文件的編碼格式,一般是"utf-8"
示例
from langchain_community.document_loaders import TextLoader
txt_loader = TextLoader(file_path="testfiles/測(cè)試文件.txt", encoding="utf8")
docs = txt_loader.load()
docs
運(yùn)行結(jié)果:
[Document(metadata={'source': 'testfiles/測(cè)試文件.txt'}, page_cnotallow='大語(yǔ)言模型作為人工智能領(lǐng)域的重要技術(shù)之一,具有廣泛的應(yīng)用場(chǎng)景。以下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:\n\n1. 機(jī)器翻譯\n描述:大語(yǔ)言模型通過訓(xùn)練可以學(xué)習(xí)不同語(yǔ)言之間的語(yǔ)法和語(yǔ)義規(guī)則,實(shí)現(xiàn)自動(dòng)翻譯。這種技術(shù)已廣泛應(yīng)用于跨國(guó)企業(yè)溝通、國(guó)際合作等領(lǐng)域,如谷歌翻譯等產(chǎn)品。盡管在處理長(zhǎng)句子和歧義消解等方面仍面臨挑戰(zhàn),但隨著技術(shù)的發(fā)展,其準(zhǔn)確性和流暢度不斷提升。\n\n2. 智能客服與聊天機(jī)器人\n描述:大語(yǔ)言模型被用于開發(fā)智能客服助手和聊天機(jī)器人,能夠理解用戶的問題并提供相應(yīng)的解決方案或轉(zhuǎn)達(dá)給相關(guān)部門。這不僅提高了客服效率,還提升了用戶體驗(yàn)。例如,通過自然語(yǔ)言處理技術(shù),智能客服助手可以分析用戶情感狀態(tài),及時(shí)發(fā)現(xiàn)問題并優(yōu)化服務(wù)。\n\n3. 文本生成與創(chuàng)作\n描述:大語(yǔ)言模型能夠生成符合語(yǔ)法規(guī)則的文章、新聞、小說等文本內(nèi)容。通過學(xué)習(xí)大量文本數(shù)據(jù),模型可以生成具有創(chuàng)造性和相關(guān)性的內(nèi)容,廣泛應(yīng)用于新聞報(bào)道、廣告營(yíng)銷等領(lǐng)域。此外,它還能根據(jù)給定主題或關(guān)鍵詞生成文章,為創(chuàng)作者提供靈感和輔助。\n\n4. 情感分析\n描述:大語(yǔ)言模型通過分析文本中的情感傾向和情感表達(dá),幫助企業(yè)了解客戶反饋和情感狀態(tài),從而制定更精準(zhǔn)的營(yíng)銷策略或優(yōu)化客戶服務(wù)。這種技術(shù)還可用于社交媒體監(jiān)控,實(shí)時(shí)分析公眾對(duì)某一主題或事件的情緒和反應(yīng)。\n\n5. 自動(dòng)問答系統(tǒng)\n描述:通過學(xué)習(xí)大量問題和答案,大語(yǔ)言模型能夠自動(dòng)生成符合語(yǔ)法規(guī)則的問題和答案。這種自動(dòng)問答系統(tǒng)可應(yīng)用于智能助手、搜索引擎等領(lǐng)域,為用戶提供高效、準(zhǔn)確的信息服務(wù)。結(jié)合知識(shí)圖譜技術(shù),問答系統(tǒng)的知識(shí)檢索和推理能力得到進(jìn)一步增強(qiáng)。\n\n6. 自動(dòng)摘要與總結(jié)\n描述:大語(yǔ)言模型能夠自動(dòng)對(duì)文本進(jìn)行摘要和總結(jié),提取關(guān)鍵信息,幫助用戶快速了解文本主旨和重點(diǎn)。這種技術(shù)在學(xué)術(shù)論文、新聞報(bào)道等領(lǐng)域具有重要應(yīng)用價(jià)值,提高了信息獲取的效率。\n\n7. 代碼生成與自動(dòng)化編程\n描述:大語(yǔ)言模型通過學(xué)習(xí)大量代碼數(shù)據(jù),可以理解編程語(yǔ)言的語(yǔ)法和邏輯規(guī)則,實(shí)現(xiàn)代碼的自動(dòng)生成。這有助于非技術(shù)用戶生成基本代碼,同時(shí)為專業(yè)編程人員提供輔助,加快開發(fā)進(jìn)程。然而,在復(fù)雜任務(wù)中仍需人工審核和調(diào)整。\n\n8. 信息檢索與推薦系統(tǒng)\n描述:大語(yǔ)言模型可應(yīng)用于改善搜索引擎結(jié)果和內(nèi)容推薦算法。通過分析用戶查詢意圖和上下文信息,模型能夠提供更準(zhǔn)確、個(gè)性化的搜索結(jié)果和內(nèi)容推薦,提升用戶體驗(yàn)和滿意度。\n\n9. 生物醫(yī)學(xué)研究\n描述:在生物醫(yī)學(xué)領(lǐng)域,大語(yǔ)言模型可用于分析基因組數(shù)據(jù)、蛋白質(zhì)相互作用等,加速藥物發(fā)現(xiàn)和新療法的研究。例如,通過預(yù)測(cè)基因變異的功能影響,研究者能夠更全面地分析人類基因組的潛在風(fēng)險(xiǎn)和治療靶點(diǎn)。\n\n10. 語(yǔ)音識(shí)別與生成\n描述:大語(yǔ)言模型在語(yǔ)音識(shí)別和語(yǔ)音生成方面也展現(xiàn)出巨大潛力。通過將語(yǔ)音轉(zhuǎn)錄為文本或?qū)⑽谋巨D(zhuǎn)化為語(yǔ)音,該技術(shù)使得人們與計(jì)算機(jī)的交互更加自然和便捷。這對(duì)于有聽力或視覺障礙的人群尤為重要,有助于他們更好地理解和享受音視頻內(nèi)容。\n\n綜上所述,大語(yǔ)言模型在多個(gè)領(lǐng)域都具有廣泛的應(yīng)用前景和巨大的價(jià)值潛力。隨著技術(shù)的不斷進(jìn)步和完善,我們有理由相信大語(yǔ)言模型將在未來的人工智能領(lǐng)域發(fā)揮更加重要的作用。')]
PDF文件加載器
PyMuPDFLoader函數(shù)說明
class langchain_community.document_loaders.pdf.PyMuPDFLoader(
file_path:str,*,
headers:Optional[Dict]=None,
extract_images:bool=False,
**kwargs:Any)
說明:
- ?
?extract_images?
?:指示是否從 PDF 中提取圖像。如果設(shè)置為 True,將嘗試提取 PDF 中的所有圖像。 - 使用前需要安裝相關(guān)依賴:?
?pip install PyMuPDF?
?
示例
from langchain_community.document_loaders import PyMuPDFLoader
pdf_loader = PyMuPDFLoader(file_path="testfiles/測(cè)試文件.pdf")
docs = pdf_loader.load()
docs
運(yùn)行結(jié)果:
# metadata數(shù)據(jù)詳情
metadata={'source':'testfiles/測(cè)試文件.pdf',
'file_path':'testfiles/測(cè)試文件.pdf',
'page':0,'total_pages':21,
'format':'PDF 1.6',
'title':'JSON 是什么?',
'author':'番茄花園',
'subject':'',
'keywords':'',
'creator':'WPS Office 個(gè)人版',
'producer':'PDFlib 7.0.3 (C++/Win32)',
'creationDate':"D:20090304181435+08'00'",
'modDate':"D:20100525102623+08'00'",'trapped':''
}
原始PDF文件如下:
說明:通過對(duì)比可以看到
- pagecontent與PDF文件內(nèi)容一致。
- metadata數(shù)據(jù)有比較多的字段,例如:format,title,author,subject,keywords,creator,producer,creationDate,modDate等。
EXCEL文件加載器
UnstructuredExcelLoader函數(shù)說明
class langchain_community.document_loaders.excel.UnstructuredExcelLoader(
file_path: Union[str, Path],
mode: str = 'single',
**unstructured_kwargs: Any)
說明:
- 使用前需要安裝相關(guān)依賴:?
?pip install unstructured?
?。
示例
from langchain_community.document_loaders import UnstructuredExcelLoader
excel_loader = UnstructuredExcelLoader(file_path="testfiles/測(cè)試文件.xlsx", encoding="utf8")
docs = excel_loader.load()
docs
運(yùn)行結(jié)果:
原始文件:
PPT文件加載器
UnstructuredPowerPointLoader函數(shù)說明
class langchain_community.document_loaders.powerpoint.UnstructuredPowerPointLoader(
file_path:Union[str,List[str],Path,List[Path]],*,
mode:str='single',
**unstructured_kwargs:Any)
說明:
- 使用前需要安裝相關(guān)依賴:?
?pip install python-pptx?
?。
示例
from langchain_community.document_loaders import UnstructuredPowerPointLoader
ppt_loader = UnstructuredPowerPointLoader(file_path="testfiles/測(cè)試文件.pptx", mode="single")
docs = ppt_loader.load()
docs[0].page_content
運(yùn)行結(jié)果:
原始文件:
說明:
- 通過對(duì)比,可以看到PPT中的文字會(huì)被提取出來,圖片會(huì)被清洗掉。
WORD文件加載器
UnstructuredWordDocumentLoader函數(shù)說明
class langchain_community.document_loaders.word_document.UnstructuredWordDocumentLoader(
file_path:Union[str,List[str],Path,List[Path]],*,
mode:str='single',
**unstructured_kwargs:Any)
說明:
- 使用前需要安裝相關(guān)依賴:?
?pip install python-docx?
?。
示例
from langchain_community.document_loaders import UnstructuredWordDocumentLoader
word_loader = UnstructuredWordDocumentLoader(file_path="testfiles/測(cè)試文件.docx", mode="single")
docs = ppt_loader.load()
docs
運(yùn)行結(jié)果:
原始文件:
MARKDOWN文件加載器
UnstructuredMarkdownLoader函數(shù)說明
class langchain_community.document_loaders.markdown.UnstructuredMarkdownLoader(
file_path:Union[str,List[str],Path,List[Path]],*,
mode:str='single',
**unstructured_kwargs:Any)
- 使用前需要安裝相關(guān)依賴:?
?pip install markdown?
?。
示例
from langchain_community.document_loaders import UnstructuredMarkdownLoader
md_loader = UnstructuredMarkdownLoader(file_path="testfiles/測(cè)試文件.md", mode="single")
docs = md_loader.load()
docs
運(yùn)行結(jié)果:
原始文件:
HTML文件加載器
UnstructuredHTMLLoader函數(shù)說明
class langchain_community.document_loaders.html.UnstructuredHTMLLoader(
file_path:Union[str,List[str],Path,List[Path]],*,
mode:str='single',
**unstructured_kwargs:Any)
說明:
- model可以設(shè)置為'elements',表示將HTML元素作為文檔進(jìn)行切分。
示例
from langchain_community.document_loaders import UnstructuredHTMLLoader
html_file = "testfiles/測(cè)試文件.htm"
html_loader = UnstructuredHTMLLoader(file_path=html_file, mode="single")
docs = html_loader.load()
docs[0].page_content
運(yùn)行結(jié)果:
原始文件:
補(bǔ)充說明: 如果將上面的mode改為mode="elements",運(yùn)行如下,但是得到內(nèi)容對(duì)于建立知識(shí)庫(kù)沒有太大幫助。
SQL文件加載器
SQLDatabaseLoader函數(shù)說明
class langchain_community.document_loaders.sql_database.SQLDatabaseLoader(
query:Union[str,Select],
db:SQLDatabase,*,
parameters:Optional[Dict[str,Any]]=None,
page_content_mapper:Optional[Callable[[...],str]]=None,
metadata_mapper:Optional[Callable[[...],Dict[str,Any]]]=None,
source_columns:Optional[Sequence[str]]=None,
include_rownum_into_metadata:bool=False,
include_query_into_metadata:bool=False)
說明:
- ?
?query?
?:指定要執(zhí)行的 SQL 查詢。
例如:query = "SELECT * FROM documents"
- ?
?db?
?: 指定要連接的 SQL 數(shù)據(jù)庫(kù)實(shí)例。 - ?
?parameters?
?(可選):可選參數(shù),用于傳遞 SQL 查詢的參數(shù),以便于動(dòng)態(tài)查詢。
例如:parameters = {"id": 1}
- ?
?page_content_mapper?
?(可選):可選的映射函數(shù),用于處理查詢結(jié)果中的每一行,返回格式化后的內(nèi)容。 - ?
?metadata_mapper?
?(可選):可選的映射函數(shù),用于處理查詢結(jié)果中的每一行,返回元數(shù)據(jù)字典。
例如:metadata_mapper=lambda row: {"id": row['id'], "created_at": row['created_at']}
- ?
?source_columns?
?(可選):可選參數(shù),指定要從查詢結(jié)果中提取的列名。 - ?
?include_rownum_into_metadata?
?:指示是否將行號(hào)包含在元數(shù)據(jù)中。 - ?
?include_query_into_metadata?
?:指示是否將執(zhí)行的 SQL 查詢包含在元數(shù)據(jù)中。 - 使用前需要安裝相關(guān)依賴:?
?pip install sqlalchemy?
?。
示例
from langchain_community.document_loaders importSQLDatabaseLoader
from langchain_community.utilities importSQLDatabase
from sqlalchemy import create_engine
# 創(chuàng)建 SQLite 數(shù)據(jù)庫(kù)引擎,指定數(shù)據(jù)庫(kù)文件的路徑
engine = create_engine(url="sqlite:///testfiles/students.db")
# 使用創(chuàng)建的引擎實(shí)例化 SQLDatabase 對(duì)象
db =SQLDatabase(engine=engine)
# 創(chuàng)建 SQLDatabaseLoader 實(shí)例,指定要執(zhí)行的 SQL 查詢
sql_loader =SQLDatabaseLoader(query="SELECT * FROM stu_score;", db=db,
include_query_into_metadata=True,
include_rownum_into_metadata=True)
docs = sql_loader.load()
docs
運(yùn)行結(jié)果:
原始文件:
以上只是對(duì)各類文件加載器的簡(jiǎn)單梳理,在實(shí)際應(yīng)用中需要進(jìn)行進(jìn)一步的封裝,例如:
- 封裝為class方式
- 以文件后綴名自動(dòng)判斷調(diào)用的加載器
- 添加更多回溯信息
- ......
在開源項(xiàng)目QAnything(網(wǎng)易的一款開源RAG系統(tǒng))中,該項(xiàng)目中的qanything_kernel有著比較詳細(xì)的封裝,可以參考。
文檔切分(SPLIT)
按照字符切分
CharacterTextSplitter類說明
class langchain_text_splitters.character.CharacterTextSplitter:
def __init__(self, chunk_size: int, chunk_overlap: int = 0):
說明:
- chunk_size:指定每個(gè)文本片段的最大字符長(zhǎng)度。
- chunk_overlap:指定相鄰文本片段之間的重疊字符數(shù)。重疊可以幫助保持上下文的一致性。
示例
from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importCharacterTextSplitter
text_loader =TextLoader(file_path="testfiles/測(cè)試文件.txt", encoding="utf8")
docs = text_loader.load()
# 字符級(jí)文本切分器
spliter =CharacterTextSplitter(separator ='\n\n', chunk_size=128, chunk_overlap=32)
results = spliter.split_documents(documents=docs)
# 打印切分結(jié)果
print(f'切分個(gè)數(shù):{len(results)}')
for idx, chunk inenumerate(results):
print(f'第{idx+1}段,長(zhǎng)度為:{len(chunk.page_content)}')
print(f'切分內(nèi)容:\n{chunk.page_content}')
print("-*-"*30+"\n")
運(yùn)行結(jié)果:
# chunk_size=128, chunk_overlap=32
切分個(gè)數(shù):12
第1段,長(zhǎng)度為:50
切分內(nèi)容:
大語(yǔ)言模型作為人工智能領(lǐng)域的重要技術(shù)之一,具有廣泛的應(yīng)用場(chǎng)景。以下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第2段,長(zhǎng)度為:124
切分內(nèi)容:
1.機(jī)器翻譯
描述:大語(yǔ)言模型通過訓(xùn)練可以學(xué)習(xí)不同語(yǔ)言之間的語(yǔ)法和語(yǔ)義規(guī)則,實(shí)現(xiàn)自動(dòng)翻譯。這種技術(shù)已廣泛應(yīng)用于跨國(guó)企業(yè)溝通、國(guó)際合作等領(lǐng)域,如谷歌翻譯等產(chǎn)品。盡管在處理長(zhǎng)句子和歧義消解等方面仍面臨挑戰(zhàn),但隨著技術(shù)的發(fā)展,其準(zhǔn)確性和流暢度不斷提升。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第3段,長(zhǎng)度為:131
切分內(nèi)容:
2.智能客服與聊天機(jī)器人
描述:大語(yǔ)言模型被用于開發(fā)智能客服助手和聊天機(jī)器人,能夠理解用戶的問題并提供相應(yīng)的解決方案或轉(zhuǎn)達(dá)給相關(guān)部門。這不僅提高了客服效率,還提升了用戶體驗(yàn)。例如,通過自然語(yǔ)言處理技術(shù),智能客服助手可以分析用戶情感狀態(tài),及時(shí)發(fā)現(xiàn)問題并優(yōu)化服務(wù)。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第4段,長(zhǎng)度為:125
切分內(nèi)容:
3.文本生成與創(chuàng)作
描述:大語(yǔ)言模型能夠生成符合語(yǔ)法規(guī)則的文章、新聞、小說等文本內(nèi)容。通過學(xué)習(xí)大量文本數(shù)據(jù),模型可以生成具有創(chuàng)造性和相關(guān)性的內(nèi)容,廣泛應(yīng)用于新聞報(bào)道、廣告營(yíng)銷等領(lǐng)域。此外,它還能根據(jù)給定主題或關(guān)鍵詞生成文章,為創(chuàng)作者提供靈感和輔助。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第5段,長(zhǎng)度為:106
...
切分內(nèi)容:
綜上所述,大語(yǔ)言模型在多個(gè)領(lǐng)域都具有廣泛的應(yīng)用前景和巨大的價(jià)值潛力。隨著技術(shù)的不斷進(jìn)步和完善,我們有理由相信大語(yǔ)言模型將在未來的人工智能領(lǐng)域發(fā)揮更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
# 如果改為chunk_size=512, chunk_overlap=32
切分個(gè)數(shù):3
第1段,長(zhǎng)度為:436
切分內(nèi)容:
大語(yǔ)言模型作為人工智能領(lǐng)域的重要技術(shù)之一,具有廣泛的應(yīng)用場(chǎng)景。以下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:
1.機(jī)器翻譯
描述:大語(yǔ)言模型通過訓(xùn)練可以學(xué)習(xí)不同語(yǔ)言之間的語(yǔ)法和語(yǔ)義規(guī)則,實(shí)現(xiàn)自動(dòng)翻譯。這種技術(shù)已廣泛應(yīng)用于跨國(guó)企業(yè)溝通、國(guó)際合作等領(lǐng)域,如谷歌翻譯等產(chǎn)品。盡管在處理長(zhǎng)句子和歧義消解等方面仍面臨挑戰(zhàn),但隨著技術(shù)的發(fā)展,其準(zhǔn)確性和流暢度不斷提升。
2.智能客服與聊天機(jī)器人
描述:大語(yǔ)言模型被用于開發(fā)智能客服助手和聊天機(jī)器人,能夠理解用戶的問題并提供相應(yīng)的解決方案或轉(zhuǎn)達(dá)給相關(guān)部門。這不僅提高了客服效率,還提升了用戶體驗(yàn)。例如,通過自然語(yǔ)言處理技術(shù),智能客服助手可以分析用戶情感狀態(tài),及時(shí)發(fā)現(xiàn)問題并優(yōu)化服務(wù)。
3.文本生成與創(chuàng)作
描述:大語(yǔ)言模型能夠生成符合語(yǔ)法規(guī)則的文章、新聞、小說等文本內(nèi)容。通過學(xué)習(xí)大量文本數(shù)據(jù),模型可以生成具有創(chuàng)造性和相關(guān)性的內(nèi)容,廣泛應(yīng)用于新聞報(bào)道、廣告營(yíng)銷等領(lǐng)域。此外,它還能根據(jù)給定主題或關(guān)鍵詞生成文章,為創(chuàng)作者提供靈感和輔助。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第2段,長(zhǎng)度為:443
切分內(nèi)容:
4.情感分析
描述:大語(yǔ)言模型通過分析文本中的情感傾向和情感表達(dá),幫助企業(yè)了解客戶反饋和情感狀態(tài),從而制定更精準(zhǔn)的營(yíng)銷策略或優(yōu)化客戶服務(wù)。這種技術(shù)還可用于社交媒體監(jiān)控,實(shí)時(shí)分析公眾對(duì)某一主題或事件的情緒和反應(yīng)。
5.自動(dòng)問答系統(tǒng)
描述:通過學(xué)習(xí)大量問題和答案,大語(yǔ)言模型能夠自動(dòng)生成符合語(yǔ)法規(guī)則的問題和答案。這種自動(dòng)問答系統(tǒng)可應(yīng)用于智能助手、搜索引擎等領(lǐng)域,為用戶提供高效、準(zhǔn)確的信息服務(wù)。結(jié)合知識(shí)圖譜技術(shù),問答系統(tǒng)的知識(shí)檢索和推理能力得到進(jìn)一步增強(qiáng)。
6.自動(dòng)摘要與總結(jié)
描述:大語(yǔ)言模型能夠自動(dòng)對(duì)文本進(jìn)行摘要和總結(jié),提取關(guān)鍵信息,幫助用戶快速了解文本主旨和重點(diǎn)。這種技術(shù)在學(xué)術(shù)論文、新聞報(bào)道等領(lǐng)域具有重要應(yīng)用價(jià)值,提高了信息獲取的效率。
...
綜上所述,大語(yǔ)言模型在多個(gè)領(lǐng)域都具有廣泛的應(yīng)用前景和巨大的價(jià)值潛力。隨著技術(shù)的不斷進(jìn)步和完善,我們有理由相信大語(yǔ)言模型將在未來的人工智能領(lǐng)域發(fā)揮更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
遞歸方式切分
RecursiveCharacterTextSplitter函數(shù)說明
class langchain_text_splitters.character.RecursiveCharacterTextSplitter(
separators:Optional[List[str]]=None,
keep_separator:bool=True,
is_separator_regex:bool=False,
**kwargs:Any
)
說明:
- separators:用于指定切分文本時(shí)使用的分隔符列表??梢园〒Q行符、句號(hào)、逗號(hào)等。
- keep_separator:指定在切分后是否保留分隔符。如果設(shè)置為 True,切分后的文本片段將包含分隔符。
- is_separator_regex:指定 separators 是否為正則表達(dá)式。如果設(shè)置為 True,則 separators 將被視為正則表達(dá)式。
示例
from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importRecursiveCharacterTextSplitter
text_loader =TextLoader(file_path="testfiles/測(cè)試文件.txt", encoding="utf8")
docs = text_loader.load()
separators=["\n",".","。","!","!","?","?",";",";","……","…","、",",",","," "]
# 創(chuàng)建 RecursiveCharacterTextSplitter 實(shí)例
splitter =RecursiveCharacterTextSplitter(
separators=separators,
keep_separator=True,
is_separator_regex=False,
chunk_size=128,
chunk_overlap=32
)
results = splitter.split_documents(documents=docs)
# 打印切分結(jié)果
print(f'切分個(gè)數(shù):{len(results)}')
for idx, chunk inenumerate(results):
print(f'第{idx+1}段,長(zhǎng)度為:{len(chunk.page_content)}')
print(f'切分內(nèi)容:\n{chunk.page_content}')
print("-*-"*30+"\n")
運(yùn)行結(jié)果:
切分個(gè)數(shù):13
第1段,長(zhǎng)度為:59
切分內(nèi)容:
大語(yǔ)言模型作為人工智能領(lǐng)域的重要技術(shù)之一,具有廣泛的應(yīng)用場(chǎng)景。以下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:
1.機(jī)器翻譯
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第2段,長(zhǎng)度為:124
切分內(nèi)容:
1.機(jī)器翻譯
描述:大語(yǔ)言模型通過訓(xùn)練可以學(xué)習(xí)不同語(yǔ)言之間的語(yǔ)法和語(yǔ)義規(guī)則,實(shí)現(xiàn)自動(dòng)翻譯。這種技術(shù)已廣泛應(yīng)用于跨國(guó)企業(yè)溝通、國(guó)際合作等領(lǐng)域,如谷歌翻譯等產(chǎn)品。盡管在處理長(zhǎng)句子和歧義消解等方面仍面臨挑戰(zhàn),但隨著技術(shù)的發(fā)展,其準(zhǔn)確性和流暢度不斷提升。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第3段,長(zhǎng)度為:13
切分內(nèi)容:
2.智能客服與聊天機(jī)器人
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第4段,長(zhǎng)度為:117
切分內(nèi)容:
描述:大語(yǔ)言模型被用于開發(fā)智能客服助手和聊天機(jī)器人,能夠理解用戶的問題并提供相應(yīng)的解決方案或轉(zhuǎn)達(dá)給相關(guān)部門。這不僅提高了客服效率,還提升了用戶體驗(yàn)。例如,通過自然語(yǔ)言處理技術(shù),智能客服助手可以分析用戶情感狀態(tài),及時(shí)發(fā)現(xiàn)問題并優(yōu)化服務(wù)。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第5段,長(zhǎng)度為:125
...
切分內(nèi)容:
綜上所述,大語(yǔ)言模型在多個(gè)領(lǐng)域都具有廣泛的應(yīng)用前景和巨大的價(jià)值潛力。隨著技術(shù)的不斷進(jìn)步和完善,我們有理由相信大語(yǔ)言模型將在未來的人工智能領(lǐng)域發(fā)揮更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
對(duì)比CharacterTextSplitter的執(zhí)行結(jié)果,RecursiveCharacterTextSplitter在切分長(zhǎng)文本時(shí),可以切分出更小的文本片段,并且可以保留分隔符。
按照Token切分
TokenTextSplitter函數(shù)說明
class langchain_text_splitters.base.TokenTextSplitter(
encoding_name:str='gpt2',
model_name:Optional[str]=None,
allowed_special:Union[Literal['all'],AbstractSet[str]]={},
disallowed_special:Union[Literal['all'],Collection[str]]='all',
**kwargs:Any
)
說明:
- model_name(可選):可選參數(shù),用于指定特定的語(yǔ)言模型名稱。
- allowed_special:指定被允許的特殊令牌集合。
- disallowed_special:指定不允許的特殊令牌集合。
- 使用前需要安裝依賴:?
?pip install tiktoken?
?。 - encoding_name:指定用于令牌化文本的編碼名稱。該選項(xiàng)通過以下代碼可以得到常見選項(xiàng):
import tiktoken
tiktoken.list_encoding_names()
# 運(yùn)行結(jié)果:
# ['gpt2', 'r50k_base', 'p50k_base', 'p50k_edit', 'cl100k_base', 'o200k_base']
- ?
?gpt2?
??:這是 OpenAI 的??GPT-2?
?? 模型使用的編碼,基于??Byte Pair Encoding (BPE)?
?。它適用于大多數(shù)基于 GPT-2 的任務(wù),能夠有效處理英語(yǔ)文本。 - ?
?r50k_base?
??:這是針對(duì)??OpenAI?
?? 的模型(如??GPT-3?
??)的一種編碼,使用了??50,000?
? 個(gè)最常見的子詞單位。它是一種更為精簡(jiǎn)的編碼方式,適用于對(duì)文本進(jìn)行更細(xì)粒度的切分。 - ?
?p50k_base?
??:基于??BPE?
?? 的編碼,使用??50,000?
?? 個(gè)子詞單位。該編碼主要用于處理更復(fù)雜的文本生成和理解任務(wù),適合與??GPT-3?
? 及相關(guān)模型的配合使用。 - ?
?p50k_edit?
??:這是??p50k_base?
? 的一種變體,專門優(yōu)化用于文本編輯任務(wù)。這種編碼關(guān)注于文本的修改和調(diào)整,適合需要對(duì)文本進(jìn)行細(xì)微編輯的應(yīng)用場(chǎng)景。 - ?
?cl100k_base?
??:這是針對(duì)更大規(guī)模模型(如??GPT-4?
??)的一種編碼,使用了??100,000?
? 個(gè)子詞單位。它能夠處理更復(fù)雜和多樣化的文本,適合高性能的文本生成和理解任務(wù)。 - ?
?o200k_base?
??:這是一個(gè)更高級(jí)的編碼,使用了??200,000?
? 個(gè)子詞單位,旨在處理極為復(fù)雜的文本任務(wù)。它適合需要處理大量信息或多樣化文本的應(yīng)用,能夠提供更高的靈活性和精度。
以上選項(xiàng)內(nèi)容由ChatGPT輔助生成,如有錯(cuò)誤,請(qǐng)及時(shí)反饋。
示例
import tiktoken
from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importTokenTextSplitter
text_loader =TextLoader(file_path="testfiles/測(cè)試文件.txt", encoding="utf8")
docs = text_loader.load()
splitter =TokenTextSplitter(encoding_name="o200k_base",
chunk_size=128,
chunk_overlap=64)
results = splitter.split_documents(documents=docs)
# 打印切分結(jié)果
print(f'切分個(gè)數(shù):{len(results)}')
for idx, chunk inenumerate(results):
print(f'第{idx+1}段,長(zhǎng)度為:{len(chunk.page_content)}')
print(f'切分內(nèi)容:\n{chunk.page_content}')
print("-*-"*30+"\n")
運(yùn)行結(jié)果:
切分個(gè)數(shù):13
第1段,長(zhǎng)度為:185
切分內(nèi)容:
大語(yǔ)言模型作為人工智能領(lǐng)域的重要技術(shù)之一,具有廣泛的應(yīng)用場(chǎng)景。以下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:
1.機(jī)器翻譯
描述:大語(yǔ)言模型通過訓(xùn)練可以學(xué)習(xí)不同語(yǔ)言之間的語(yǔ)法和語(yǔ)義規(guī)則,實(shí)現(xiàn)自動(dòng)翻譯。這種技術(shù)已廣泛應(yīng)用于跨國(guó)企業(yè)溝通、國(guó)際合作等領(lǐng)域,如谷歌翻譯等產(chǎn)品。盡管在處理長(zhǎng)句子和歧義消解等方面仍面臨挑戰(zhàn),但隨著技術(shù)的發(fā)展,其準(zhǔn)確性和流暢度不斷提升。
2.智能客服
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第2段,長(zhǎng)度為:198
切分內(nèi)容:
種技術(shù)已廣泛應(yīng)用于跨國(guó)企業(yè)溝通、國(guó)際合作等領(lǐng)域,如谷歌翻譯等產(chǎn)品。盡管在處理長(zhǎng)句子和歧義消解等方面仍面臨挑戰(zhàn),但隨著技術(shù)的發(fā)展,其準(zhǔn)確性和流暢度不斷提升。
2.智能客服與聊天機(jī)器人
描述:大語(yǔ)言模型被用于開發(fā)智能客服助手和聊天機(jī)器人,能夠理解用戶的問題并提供相應(yīng)的解決方案或轉(zhuǎn)達(dá)給相關(guān)部門。這不僅提高了客服效率,還提升了用戶體驗(yàn)。例如,通過自然語(yǔ)言處理技術(shù),智能客服助手可以分析用戶情感狀態(tài),
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第3段,長(zhǎng)度為:215
切分內(nèi)容:
與聊天機(jī)器人
描述:大語(yǔ)言模型被用于開發(fā)智能客服助手和聊天機(jī)器人,能夠理解用戶的問題并提供相應(yīng)的解決方案或轉(zhuǎn)達(dá)給相關(guān)部門。這不僅提高了客服效率,還提升了用戶體驗(yàn)。例如,通過自然語(yǔ)言處理技術(shù),智能客服助手可以分析用戶情感狀態(tài),及時(shí)發(fā)現(xiàn)問題并優(yōu)化服務(wù)。
3.文本生成與創(chuàng)作
...
綜上所述,大語(yǔ)言模型在多個(gè)領(lǐng)域都具有廣泛的應(yīng)用前景和巨大的價(jià)值潛力。隨著技術(shù)的不斷進(jìn)步和完善,我們有理由相信大語(yǔ)言模型將在未來的人工智能領(lǐng)域發(fā)揮更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
如果將encoding_name設(shè)置為'gpt2',則切分結(jié)果如下:
切分個(gè)數(shù):43
第1段,長(zhǎng)度為:65
切分內(nèi)容:
大語(yǔ)言模型作為人工智能領(lǐng)域的重要技術(shù)之一,具有廣泛的應(yīng)用場(chǎng)景。以下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:
1.機(jī)器翻譯
描述:大?
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第2段,長(zhǎng)度為:62
切分內(nèi)容:
?下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:
1.機(jī)器翻譯
描述:大語(yǔ)言模型通過訓(xùn)練可以學(xué)習(xí)不同語(yǔ)言之間的語(yǔ)法和語(yǔ)義規(guī)則,實(shí)現(xiàn)
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第3段,長(zhǎng)度為:58
切分內(nèi)容:
?言模型通過訓(xùn)練可以學(xué)習(xí)不同語(yǔ)言之間的語(yǔ)法和語(yǔ)義規(guī)則,實(shí)現(xiàn)自動(dòng)翻譯。這種技術(shù)已廣泛應(yīng)用于跨國(guó)企業(yè)溝通、國(guó)際合作等領(lǐng)?
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
通過對(duì)比,可以看到o200k_base的效果要優(yōu)于gpt2。
按照markdown標(biāo)題切分
示例
from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importMarkdownTextSplitter
text_loader =TextLoader(file_path="testfiles/測(cè)試文件.md", encoding="utf8")
docs = text_loader.load()
# 創(chuàng)建 MarkdownTextSplitter 實(shí)例
splitter =MarkdownTextSplitter(chunk_size=128, chunk_overlap=64)
results = splitter.split_documents(documents=docs)
# 打印切分結(jié)果
print(f'切分個(gè)數(shù):{len(results)}')
for idx, chunk inenumerate(results):
print(f'第{idx+1}段,長(zhǎng)度為:{len(chunk.page_content)}')
print(f'切分內(nèi)容:\n{chunk.page_content}')
print("-*-"*30+"\n")
運(yùn)行結(jié)果:
切分個(gè)數(shù):196
第1段,長(zhǎng)度為:126
切分內(nèi)容:
## 前言
本章我們將通過LLaMA-Factory具體實(shí)踐大模型訓(xùn)練的三個(gè)階段,包括:預(yù)訓(xùn)練、監(jiān)督微調(diào)和偏好糾正。
## 大模型訓(xùn)練回顧
練的三個(gè)階段.png)
## 訓(xùn)練目標(biāo)
通過實(shí)踐大模型的三個(gè)訓(xùn)練階段,訓(xùn)練一個(gè)醫(yī)療大模型
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第2段,長(zhǎng)度為:123
切分內(nèi)容:
## 訓(xùn)練過程實(shí)施
### 準(zhǔn)備訓(xùn)練框架
`LLaMA Factory`是一款開源低代碼大模型微調(diào)框架,集成了業(yè)界最廣泛使用的微調(diào)技術(shù),支持通過Web UI界面零代碼微調(diào)大模型,目前已經(jīng)成為開源社區(qū)內(nèi)最受歡迎的微調(diào)框架,GitHub星標(biāo)超過2萬。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
第3段,長(zhǎng)度為:118
切分內(nèi)容:
#### 運(yùn)行環(huán)境要求
-硬件:
- GPU:推薦使用24GB顯存的顯卡或者更高配置
...
## 參考資料
[Github:LLaMA-Factory的README文件](https://github.com/hiyouga/LLaMA-Factory/blob/main/data/README.md)
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
對(duì)于Markdown文本,使用MarkdownTextSplitter進(jìn)行切分,切分效果比較好。
向量化(EMBED)
考慮到RAG系統(tǒng)一般都有私有化部署的需求(因?yàn)閿?shù)據(jù)涉密),所以對(duì)應(yīng)的向量化的方式有兩種:本地化 和 在線化。
本地化
在開源項(xiàng)目QAnything中,其提供了一種使用本地模型的方法,其大致步驟是:
- 在本地保存了一個(gè)向量化模型。
- 在調(diào)用向量化模型時(shí),使用本地的模型.
embedding_client = EmbeddingClient(
server_url=LOCAL_EMBED_SERVICE_URL,
model_name=LOCAL_EMBED_MODEL_NAME,
model_versinotallow='1',
resp_wait_s=120,
tokenizer_path='qanything_kernel/connector/embedding/embedding_model_0630')
由于示例代碼的集成度較高,剝離核心代碼執(zhí)行成本較大,所以此處并未實(shí)踐,只是引用相關(guān)的信息。
在線化
使用HuggingFaceEmbeddings
LangChain社區(qū)提供了HuggingFaceEmbeddings,該類可以加載HuggingFace的預(yù)訓(xùn)練模型,并使用該模型進(jìn)行向量化。
from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importRecursiveCharacterTextSplitter
from langchain_chroma importChroma
from langchain.embeddings importHuggingFaceEmbeddings
# 加載文本
text_loader =TextLoader(file_path="testfiles/測(cè)試文件.txt", encoding="utf8")
docs = text_loader.load()
# 切分文本
spliter =RecursiveCharacterTextSplitter(chunk_size=128, chunk_overlap=64)
docs = spliter.split_documents(documents=docs)
# 初始化 HuggingFaceEmbeddings
embedding_function =HuggingFaceEmbeddings(model_name="bert-base-chinese")
# 創(chuàng)建向量數(shù)據(jù)庫(kù)
store =Chroma(embedding_functinotallow=embedding_function, persist_directory="chroma_data")
# 將文檔添加到數(shù)據(jù)庫(kù)中
store.add_documents(documents=docs)
# 進(jìn)行相似性搜索
store.similarity_search(query="小米估值多少?", k=2)
說明:
- 使用前需要安裝依賴?
?pip install sentence-transformers?
?
運(yùn)行結(jié)果:
[Document(metadata={'source': 'testfiles/測(cè)試文件.txt'}, page_cnotallow='1. 機(jī)器翻譯\n描述:大語(yǔ)言模型通過訓(xùn)練可以學(xué)習(xí)不同語(yǔ)言之間的語(yǔ)法和語(yǔ)義規(guī)則,實(shí)現(xiàn)自動(dòng)翻譯。這種技術(shù)已廣泛應(yīng)用于跨國(guó)企業(yè)溝通、國(guó)際合作等領(lǐng)域,如谷歌翻譯等產(chǎn)品。盡管在處理長(zhǎng)句子和歧義消解等方面仍面臨挑戰(zhàn),但隨著技術(shù)的發(fā)展,其準(zhǔn)確性和流暢度不斷提升。'),
Document(metadata={'source': 'testfiles/測(cè)試文件.txt'}, page_cnotallow='1. 機(jī)器翻譯\n描述:大語(yǔ)言模型通過訓(xùn)練可以學(xué)習(xí)不同語(yǔ)言之間的語(yǔ)法和語(yǔ)義規(guī)則,實(shí)現(xiàn)自動(dòng)翻譯。這種技術(shù)已廣泛應(yīng)用于跨國(guó)企業(yè)溝通、國(guó)際合作等領(lǐng)域,如谷歌翻譯等產(chǎn)品。盡管在處理長(zhǎng)句子和歧義消解等方面仍面臨挑戰(zhàn),但隨著技術(shù)的發(fā)展,其準(zhǔn)確性和流暢度不斷提升。')]
使用QianfanEmbeddings
由于Qwen的API有樣本為6個(gè)的限制,所以此處試用百度千帆大模型的向量化API。
# util.py
defget_ernie_models():
"""
加載文心系列大模型
"""
# LLM 大語(yǔ)言模型(單輪對(duì)話版)
from langchain_community.llms importQianfanLLMEndpoint
# Chat 聊天版大模型(支持多輪對(duì)話)
from langchain_community.chat_models importQianfanChatEndpoint
# Embeddings 嵌入模型
from langchain_community.embeddings importQianfanEmbeddingsEndpoint
llm =QianfanLLMEndpoint(model="ERNIE-Bot-turbo", temperature=0.1, top_p=0.2)
chat =QianfanChatEndpoint(model="ERNIE-Lite-8K", top_p=0.2, temperature=0.1)
embed =QianfanEmbeddingsEndpoint(model="bge-large-zh")
return llm, chat, embed
from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importRecursiveCharacterTextSplitter
from langchain_chroma importChroma
from utils import get_ernie_models
# 連接大模型
llm_ernie, chat_ernie, embed_ernie = get_ernie_models()
# 加載文本
text_loader =TextLoader(file_path="testfiles/測(cè)試文件.txt", encoding="utf8")
docs = text_loader.load()
# 切分文本
spliter =RecursiveCharacterTextSplitter(chunk_size=128, chunk_overlap=64)
docs = spliter.split_documents(documents=docs)
# 使用 ernie 模型創(chuàng)建向量數(shù)據(jù)庫(kù)
store =Chroma.from_documents(documents=docs,
embedding=embed_ernie,
persist_directory="chroma_data2")
store.similarity_search(query="小米估值多少?", k=2)
運(yùn)行結(jié)果:
[Document(metadata={'source': 'testfiles/測(cè)試文件.txt'}, page_cnotallow='2. 智能客服與聊天機(jī)器人'),
Document(metadata={'source': 'testfiles/測(cè)試文件.txt'}, page_cnotallow='大語(yǔ)言模型作為人工智能領(lǐng)域的重要技術(shù)之一,具有廣泛的應(yīng)用場(chǎng)景。以下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:')]
通過對(duì)比
- 使用QianfanEmbeddingsEndpoint向量化后,在相似性搜索時(shí)有兩個(gè)內(nèi)容返回;而使用HuggingFaceEmbeddings向量化后,在相似性搜索時(shí)只有第一個(gè)內(nèi)容返回。
- 相似性搜索后的內(nèi)容,看起來與我們Query查詢的問題似乎不太相關(guān),只是模型在向量層面計(jì)算是比較相似。
原理探尋
import numpy as np
from utils import get_ernie_models
llm_ernie, chat_ernie, embed_ernie = get_ernie_models()
query = np.array(embed_ernie.embed_query(text="小米估值多少?"))
doc1 = np.array(embed_ernie.embed_query(text="2. 智能客服與聊天機(jī)器人"))
doc2 = np.array(embed_ernie.embed_query(text="大語(yǔ)言模型作為人工智能領(lǐng)域的重要技術(shù)之一,具有廣泛的應(yīng)用場(chǎng)景。以下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:"))
# 歐式距離
result1 =((query - doc1)**2).sum()
print(f'query 和 doc1 的歐式距離為:{result1}')
result2 =((query - doc2)**2).sum()
print(f'query 和 doc2 的歐式距離為:{result2}')
# 相關(guān)系數(shù)
corr1 =1- result1 /2**0.5
print(f'query 和 doc1 的相關(guān)系數(shù)為:{corr1}')
corr2 =1- result2 /2**0.5
print(f'query 和 doc2 的相關(guān)系數(shù)為:{corr2}')
運(yùn)行結(jié)果:
# query 和 doc1 的歐式距離為:0.6204636182956037
# query 和 doc2 的歐式距離為:0.8112505547683875
# query 和 doc1 的相關(guān)系數(shù)為:0.561265968023637
# query 和 doc2 的相關(guān)系數(shù)為:0.42635923148192456
對(duì)比如下代碼執(zhí)行結(jié)果:
# 相關(guān)性轉(zhuǎn)換
store.similarity_search_with_relevance_scores(query="小米估值多少?", k=2)
運(yùn)行結(jié)果:
[(Document(metadata={'source': 'testfiles/測(cè)試文件.txt'}, page_cnotallow='2. 智能客服與聊天機(jī)器人'),
0.5612658250623314),
(Document(metadata={'source': 'testfiles/測(cè)試文件.txt'}, page_cnotallow='大語(yǔ)言模型作為人工智能領(lǐng)域的重要技術(shù)之一,具有廣泛的應(yīng)用場(chǎng)景。以下是十個(gè)方面的應(yīng)用場(chǎng)景及其詳細(xì)描述:'),
0.4263594055624078)]
由上可以看到:
- 相似度計(jì)算:通過計(jì)算兩個(gè)向量的歐式距離,可以得到兩個(gè)向量之間的相似度,計(jì)算結(jié)果越小代表越接近。
- 相似度轉(zhuǎn)換:通過計(jì)算兩個(gè)向量的相關(guān)系數(shù),可以得到兩個(gè)向量之間的相似度,計(jì)算結(jié)果越大代表越相似。
- 歐式距離計(jì)算方法:$d(\mathbf{a}, \mathbf) = \sqrt{\sum_{i=1}^{n} (a_i - b_i)^2}$
- 相關(guān)系數(shù)計(jì)算方法:$r = 1 - \frac{d(\mathbf{query}, \mathbf{doc})}{\sqrt{2}}$
- ?
?similarity_search?
? 即為相似度計(jì)算。 - ?
?similarity_search_with_relevance_scores?
?? 即為相似度轉(zhuǎn)換,它是??smimilarity_search?
? 的擴(kuò)展,可以返回相似度。
存儲(chǔ)(STORE)
如上述示例,我們對(duì)數(shù)據(jù)進(jìn)行向量化之后,下一步需要存儲(chǔ)至向量數(shù)據(jù)庫(kù)。目前市面上的向量數(shù)據(jù)庫(kù)眾多,主流的向量數(shù)據(jù)庫(kù)對(duì)比如下所示:
向量數(shù)據(jù)庫(kù) | URL | GitHub Star | Language | Cloud |
chroma | chroma | 7.4K | Python | ? |
milvus | milvus | 21.5K | Go/Python/C++ | ? |
pinecone | pinecone | ? | ? | ? |
qdrant | qdrant | 11.8K | Rust | ? |
typesense | typesense | 12.9K | C++ | ? |
weaviate | weaviate | 6.9K | Go | ? |
本例中,我們主要了解Chroma的使用。
Chroma簡(jiǎn)介
介紹:Chroma 是一個(gè)開源的向量數(shù)據(jù)庫(kù),專為處理和存儲(chǔ)高維向量而設(shè)計(jì),特別適用于機(jī)器學(xué)習(xí)和深度學(xué)習(xí)應(yīng)用。
特性:
- 高效的向量存儲(chǔ):Chroma 提供高效的向量存儲(chǔ)和檢索功能,能夠處理大規(guī)模數(shù)據(jù)集。
- 相似性搜索:支持快速的相似性搜索,允許用戶根據(jù)查詢向量找到最相似的向量。
- 靈活的Embedding支持:可以與多種Embedding模型集成。
- 持久化存儲(chǔ):支持將數(shù)據(jù)持久化存儲(chǔ),確保在重啟后數(shù)據(jù)不會(huì)丟失。
- 開源和社區(qū)支持:Chroma 是開源項(xiàng)目,用戶可以自由使用和修改,同時(shí)也享受社區(qū)的支持和貢獻(xiàn)。
資料:
- 官網(wǎng)主頁(yè):https://www.trychroma.com/
- 官網(wǎng)文檔:https://docs.trychroma.com/
- Github主頁(yè):https://github.com/chroma-core/
- Github項(xiàng)目:https://github.com/chroma-core/chroma/
Chroma使用的幾種方式
初次了解Chroma的使用時(shí),我被五花八門的API搞得云里霧里,一會(huì)是Chromadb,一會(huì)是langchain_chroma..... 因此,查詢了部分資料之后,總結(jié)Chroma的使用方式大致是以下三種方式:
- 第一種方式:是使用Chromadb的源生API接口使用,包括常見的增刪改查接口:?
?create_collection()?
??、??collection.add()?
??、??collection.query()?
?... - 第二種方式:是通過Langchain的組合包使用Chroma,常見的是:?
?Chroma.from_documents()?
??、??similarity_search()?
??、??similarity_search_by_vector()?
?... - 第三種方式:是通過Retriever檢索器的方式使用Chroma。
通過Chromadb的源生接口使用Chroma
Chroma 可以以多種形式進(jìn)行使用:
- 第一種:in-memory with ephemeral。短暫模式,數(shù)據(jù)保存在內(nèi)存中,程序一旦結(jié)束數(shù)據(jù)就被銷毀。
- 第二種:in-memory with persistance。持久化模式,數(shù)據(jù)保存在sqlite數(shù)據(jù)庫(kù)中,程序結(jié)束數(shù)據(jù)仍然存在。
- 第三種:client/server模式。
本次實(shí)踐中,主要嘗試 ??持久化模式?
?? 和 ??Client/Server模式?
?。
持久化模式
第一步:安裝chroma庫(kù)
pip install chromadb -i https://pypi.tuna.tsinghua.edu.cn/simple
第二步:創(chuàng)建Chromadb實(shí)例
import chromadb
from chromadb import Settings
chroma_client = chromadb.PersistentClient(path="chroma_db")
第三步:創(chuàng)建或獲取被查詢集合
# 方式一:創(chuàng)建一個(gè)新的集合
# collection = chroma_client.create_collection(name="my_collection")
# 方式二:對(duì)于已存在的集合,可以直接通過名稱獲取,如果集合不存在會(huì)報(bào)錯(cuò)。
# collection = chroma_client.get_collection(name="my_collection")
# 方式三:如果給定名稱的集合已經(jīng)存在則直接獲取,否則創(chuàng)建。
collection = chroma_client.get_or_create_collection(name="my_collection")
第四步:添加數(shù)據(jù)到集合中
collection.add(
ids=["id1","id2","id3","id4","id5"],
documents=["浙江的省會(huì)是杭州","河北的省會(huì)是石家莊","山東的省會(huì)是濟(jì)南","杭州是個(gè)美麗的城市","杭州位于浙江省"],
metadatas=[{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"}],
)
第五步:查詢集合中的數(shù)據(jù)
results = collection.query(
query_texts=["西湖在哪個(gè)?。?],
n_results=2,
)
說明:
- query_texts: 查詢的文本
- n_results: 查詢結(jié)果的數(shù)量
運(yùn)行結(jié)果:
{'ids':[['id5','id1']],
'distances':[[0.669669112082433,0.6793151914879495]],
'metadatas':[[{'source':'myDoc'},{'source':'myDoc'}]],
'embeddings':None,
'documents':[['杭州位于浙江省','浙江的省會(huì)是杭州']],
'uris':None,
'data':None,
'included':['metadatas','documents','distances']}
Client/Server模式
第一步:?jiǎn)?dòng)Chroma服務(wù)端
chroma run --path my_chroma
說明:
- --path:指定Chroma服務(wù)端存儲(chǔ)數(shù)據(jù)的路徑。
- --host:可以指定Chroma服務(wù)端監(jiān)聽的IP地址,默認(rèn)localhost
- --port:可以指定Chroma服務(wù)端監(jiān)聽的端口號(hào),默認(rèn)8000
第二步:創(chuàng)建Chromadb實(shí)例
import chromadb
from chromadb import Client
from chromadb import Settings
# 配置連接信息
setting = Settings(chroma_server_host="localhost",
chroma_server_http_port=8000)
chroma_client = Client(settings=setting)
第三步:創(chuàng)建或獲取被查詢集合
collection = chroma_client.get_or_create_collection(name="my_collection")
第四步:添加數(shù)據(jù)到集合中
collection.add(
ids=["id1","id2","id3","id4","id5"],
documents=["浙江的省會(huì)是杭州","河北的省會(huì)是石家莊","山東的省會(huì)是濟(jì)南","杭州是個(gè)美麗的城市","杭州位于浙江省"],
metadatas=[{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"}],
)
第五步:查詢集合中的數(shù)據(jù)
results = collection.query(
query_texts=["西湖在哪個(gè)???"],
n_results=2,
)
results
運(yùn)行結(jié)果:
{'ids':[['id5','id1']],
'distances':[[0.6696690917015076,0.6793153882026672]],
'metadatas':[[{'source':'myDoc'},{'source':'myDoc'}]],
'embeddings':None,
'documents':[['杭州位于浙江省','浙江的省會(huì)是杭州']],
'uris':None,
'data':None,
'included':['metadatas','documents','distances']}
對(duì)比 本地持久化 和 Client/Server模式,兩者的使用過程基本一致,只是在Client實(shí)例化時(shí)略有不同。
- 本地持久化模型:?
?chroma_client = chromadb.PersistentClient(path="chroma_db")?
? - Client/Server模式:首先配置?
?Settings?
?? 連接信息,然后調(diào)用??chroma_client = Client(settings=setting)?
?
查看chromadb的源碼,可以看到其內(nèi)部實(shí)現(xiàn)了DB常見的各類增刪改查操作:
備注:實(shí)際項(xiàng)目產(chǎn)品開發(fā)中,知識(shí)庫(kù)需要通過上述的chromadb實(shí)現(xiàn)知識(shí)庫(kù)的管理(增刪改查)。
通過Langchain的組合包使用Chroma
除了上述??chromadb?
??的方式,也可以使用??Langchain_chroma?
?的方式使用Chroma,兩者的使用場(chǎng)景區(qū)別是:
chromadb:
- 自定義應(yīng)用:當(dāng)開發(fā)者需要構(gòu)建特定的應(yīng)用,且對(duì)數(shù)據(jù)庫(kù)的操作有較高的靈活性需求時(shí),可以使用?
?chromadb?
?。 - 數(shù)據(jù)分析:需要對(duì)存儲(chǔ)的數(shù)據(jù)進(jìn)行復(fù)雜查詢和分析時(shí),使用底層接口可以更好地滿足需求。
- 高性能需求:在需要優(yōu)化性能的情況下,開發(fā)者可以通過底層接口進(jìn)行更細(xì)致的調(diào)整。
langchain_chroma:
- 快速原型開發(fā):當(dāng)開發(fā)者希望快速構(gòu)建原型或 MVP(最小可行產(chǎn)品)時(shí),?
?langchain_chroma ?
?提供了便捷的接口。 - NLP檢索:提供更高層次的抽象,適用于檢索類任務(wù),如文檔檢索、語(yǔ)義搜索等。
具體使用方法:
from langchain.text_splitter importCharacterTextSplitter
from langchain_chroma importChroma
from langchain.document_loaders importPyMuPDFLoader
from chromadb importSettings
from utils import get_ernie_models
from utils import get_qwen_models
# 連接大模型
llm_qwen, chat_qwen, embed_qwen = get_qwen_models()
llm_ernie, chat_ernie, embed_ernie = get_ernie_models()
# 加載文檔
pdf_loader =PyMuPDFLoader("testfiles/西游記.pdf")
documents = pdf_loader.load()
# 切分文檔
text_splitter =CharacterTextSplitter(chunk_size=100, chunk_overlap=32)
docs = text_splitter.split_documents(documents)
# 配置連接信息
client = chromadb.HttpClient(host='localhost', port=8000)
chroma_db =Chroma(
embedding_functinotallow=embed_qwen,
client=client
)
batch_size =6# 每次處理的樣本數(shù)量
# 分批入庫(kù)
for i inrange(0,len(docs), batch_size):
batch = docs[i:i + batch_size]# 獲取當(dāng)前批次的樣本
chroma_db.add_documents(documents=batch)# 入庫(kù)
# 查詢
query ="白骨精被打死幾次?"
docs = chroma_db.similarity_search(query, k=3)
print(len(docs))
# 打印結(jié)果
for doc in docs:
print("="*100)
print(doc.page_content)
運(yùn)行結(jié)果:
說明:
- 在langchain_chroma中,通過client_settings參數(shù),可以l連接Chroma服務(wù)端。
- 在Chroma中,通過add_documents方法,可以批量入庫(kù);不過對(duì)于西游記這樣的小說來說,入庫(kù)時(shí)間比較長(zhǎng),約5分鐘。
西游記可以從夸克網(wǎng)盤:西游記下載
通過Retriever檢索器的方式使用Chroma
在實(shí)際項(xiàng)目開發(fā)中,一般需要將Chroma的向量庫(kù)作為檢索器(Retriever)與模型組成chain鏈,以實(shí)現(xiàn)問答系統(tǒng)的問答能力。
使用方法
在上述Langchain_chroma的代碼基礎(chǔ)上,增加以下代碼:
retriever = chroma_db.as_retriever(search_type="similarity_score_threshold",
search_kwargs={"k": 4, "score_threshold": 0.1})
retriever.invoke(input="白骨精被打死幾次?")
運(yùn)行結(jié)果:
函數(shù)說明:
1、as_retriever: 功能:as_retriever 方法將 Chroma 數(shù)據(jù)庫(kù)轉(zhuǎn)換為一個(gè)檢索器(retriever),使其能夠根據(jù)給定的查詢進(jìn)行文檔檢索。這個(gè)檢索器可以使用不同的搜索類型和參數(shù)來優(yōu)化檢索結(jié)果。
參數(shù)
- ?
?search_type?
?: 指定檢索的類型。常見的選項(xiàng)包括: - ?
?"similarity_score_threshold"?
?:根據(jù)相似度分?jǐn)?shù)進(jìn)行檢索,只有超過指定閾值的結(jié)果才會(huì)被返回。 - ?
?search_kwargs?
?: 包含與搜索相關(guān)的額外參數(shù)。常用參數(shù)包括: - ?
?k?
?: 指定要返回的最相關(guān)文檔的數(shù)量。例如,k=4 表示返回前 4 個(gè)相關(guān)文檔。 - ?
?score_threshold?
?:設(shè)置相似度分?jǐn)?shù)的閾值。只有相似度分?jǐn)?shù)高于該閾值的文檔才會(huì)被返回。例如,score_threshold=0.1 表示返回分?jǐn)?shù)大于 0.1 的文檔。
2、invoke: 功能:invoke 方法用于執(zhí)行實(shí)際的檢索操作,根據(jù)提供的輸入查詢返回相關(guān)的文檔。 參數(shù):
- ?
?input?
?:要查詢的輸入文本。
內(nèi)容小結(jié)
- RAG的建庫(kù)的整體流程為:文檔讀取(LOAD) -> 文檔切分(SPLIT) -> 向量化(EMBED) -> 存儲(chǔ)(STORE)
- 在文檔讀取(LOAD)時(shí):
langchain_community.document_loaders有多個(gè)加載器,可以加載多種格式的文件,如PDF、EXCEL、PPT、WORD、MARKDOWN、HTML等。
- 在文檔切分(SPLIT)時(shí):
字符級(jí)切分、遞歸方式切分、Token方式切分等,一般情況可以使用遞歸RecursiveCharacterTextSplitter切分。
使用TokenTextSplitter切分時(shí),注意選擇對(duì)應(yīng)的encoding_name,如:'o200k_base'。
對(duì)于Markdown文檔,可以使用MarkdownTextSplitter。
- 在向量化(EMBED)時(shí):
有在線化和本地化,對(duì)于數(shù)據(jù)敏感有本地化部署的情況下,需要考慮使用本地模型進(jìn)行向量化的方案。
在線的向量化有HuggingFaceEmbeddings和第三方模型(如:QianfanEmbeddings)
在技術(shù)原理層面,計(jì)算??知識(shí)?
??與??查詢?
?相似度一般使用的是歐式距離。
- 在存儲(chǔ)(STORE)時(shí):
可供選擇的向量數(shù)據(jù)庫(kù)有多種,其中較為常用的是Chroma。
Chroma支持多種運(yùn)行方式:短暫模式、持久化模式和Client/Server模式。
使用chromadb的原生接口,可以進(jìn)行增刪改查等操作,適用于知識(shí)的管理。
使用langchain_chroma,可以快速原型開發(fā),適用于檢索類任務(wù)。
使用retriever,可以將Chroma的向量庫(kù)作為檢索器(Retriever),與模型組成chain鏈,實(shí)現(xiàn)問答系統(tǒng)的問答能力。
本文轉(zhuǎn)載自公眾號(hào)一起AI技術(shù) 作者:熱情的Dongming
