链载Ai

标题: 大模型之深入探索RAG流程 [打印本页]

作者: 链载Ai    时间: 昨天 12:01
标题: 大模型之深入探索RAG流程

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.2em;font-weight: bold;display: table;margin-right: auto;margin-bottom: 2em;margin-left: auto;padding-right: 0.2em;padding-left: 0.2em;background: rgb(15, 76, 129);color: rgb(255, 255, 255);">前言

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">在上一章【大模型之初识RAG】中,我们初步了解了RAG的基本概念和原理,并通过代码实践了一个简单的RAG流程。本章我们将基于RAG的基本流程,深入了解文档读取(LOAD)文档切分(SPLIT)向量化(EMBED)存储(STORE)的每个环节,并结合代码进行常见场景的实践。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.2em;font-weight: bold;display: table;margin: 4em auto 2em;padding-right: 0.2em;padding-left: 0.2em;background: rgb(15, 76, 129);color: rgb(255, 255, 255);">RAG流程回顾

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;color: rgb(63, 63, 63);">ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-radius: 4px;display: block;margin: 0.1em auto 0.5em;height: auto !important;" title="null" src="https://api.ibos.cn/v4/weapparticle/accesswximg?aid=97149&url=aHR0cHM6Ly9tbWJpei5xcGljLmNuL3N6X21tYml6X3BuZy9EYUJHdmE2bmljUGljT2RQUWFGQjVOcWRwbTBuYjBIcHEwZ25xbUZrYU9seG4xcHJKRmsyYThqbDhqZ3BuN2ljQzFqRUxXRTFtRzU2bWdJeVdpYjFFbm1PZkEvNjQwP3d4X2ZtdD1wbmcmYW1w;from=appmsg"/>

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">回顾RAG的流程如上所示,具体代码见RAG代码,本章不再赘述。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.2em;font-weight: bold;display: table;margin: 4em auto 2em;padding-right: 0.2em;padding-left: 0.2em;background: rgb(15, 76, 129);color: rgb(255, 255, 255);">文档读取(LOAD)

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">简介:由于我们的知识广泛存在各类文档中,所以文档读取(LOAD)在RAG系统中承担着获取数据的职责。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">常见文件

常见的文件处理库

CSV文件加载器

CSVLoader函数说明

classlangchain_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)

说明:

示例

示例1:仅加载.csv文件示例:

fromlangchain_community.document_loadersimportCSVLoader

students_loader=CSVLoader(file_path="testfiles/students.csv")
docs=students_loader.load()
docs

运行结果:

#[Document(metadata={'source':'testfiles/students.csv','row':0},page_content='name:Tom\nage:12\nscore:77'),
#Document(metadata={'source':'testfiles/students.csv','row':1},page_content='name:Jerry\nage:11\nscore:88'),
#Document(metadata={'source':'testfiles/students.csv','row':2},page_content='name:Jim\nage:12\nscore:96')]

说明:

示例2:加载.csv文件指定列作为元数据:

fromlangchain_community.document_loadersimportCSVLoader

students_loader=CSVLoader(file_path="testfiles/students.csv",metadata_columns=["name","score"])
docs=students_loader.load()
docs

运行结果:

#[Document(metadata={'source':'testfiles/students.csv','row':0,'name':'Tom','score':'77'},page_content='age:12'),
#Document(metadata={'source':'testfiles/students.csv','row':1,'name':'Jerry','score':'88'},page_content='age:11'),
#Document(metadata={'source':'testfiles/students.csv','row':2,'name':'Jim','score':'96'},page_content='age:12')]

示例3:使用RAG链测试大模型的知识理解能力

fromlangchain_community.document_loadersimportCSVLoader
fromlangchain_core.output_parsersimportStrOutputParser
fromlangchain_core.runnablesimportRunnablePassthrough
fromlangchain_chromaimportChroma
fromlangchain_core.promptsimportChatPromptTemplate
fromutilsimportget_qwen_models

defformat_docs(docs):
return"\n\n".join(doc.page_contentfordocindocs)

#连接大模型
llm,chat,embed=get_qwen_models()

#读取.csv文件
students_loader=CSVLoader(file_path="testfiles/students.csv")
docs=students_loader.load()

#向量化入库
vectorstore=Chroma.from_documents(documents=docs,embedding=embed)

retriever=vectorstore.as_retriever(search_kwargs={"k":2})

prompt=ChatPromptTemplate.from_messages([
("human","""Youareanassistantforquestion-answeringtasks.
Usethefollowingpiecesofretrievedcontexttoanswerthequestion.
Ifyoudon'tknowtheanswer,justsaythatyoudon'tknow.
Usethreesentencesmaximumandkeeptheanswerconcise.
Question:{question}
Context:{context}
Answer:""")
])

#RAG链
rag_chain=(
{"context":retriever|format_docs,
"question":RunnablePassthrough()}
|prompt
|chat
|StrOutputParser()
)

rag_chain.invoke(input="谁的成绩最高?")

运行结果:

#'Jerry的成绩最高,得了88分。'

TXT文件加载器

TXTLoader函数说明

classlangchain_community.document_loaders.text.TextLoader(
file_path:Union[str,Path],
encoding:Optional[str]=None,
autodetect_encoding:bool=False)

说明:

示例

fromlangchain_community.document_loadersimportTextLoader

txt_loader=TextLoader(file_path="testfiles/测试文件.txt",encoding="utf8")

docs=txt_loader.load()
docs

运行结果:

[Document(metadata={'source':'testfiles/测试文件.txt'},page_content='大语言模型作为人工智能领域的重要技术之一,具有广泛的应用场景。以下是十个方面的应用场景及其详细描述:\n\n1.机器翻译\n描述:大语言模型通过训练可以学习不同语言之间的语法和语义规则,实现自动翻译。这种技术已广泛应用于跨国企业沟通、国际合作等领域,如谷歌翻译等产品。尽管在处理长句子和歧义消解等方面仍面临挑战,但随着技术的发展,其准确性和流畅度不断提升。\n\n2.智能客服与聊天机器人\n描述:大语言模型被用于开发智能客服助手和聊天机器人,能够理解用户的问题并提供相应的解决方案或转达给相关部门。这不仅提高了客服效率,还提升了用户体验。例如,通过自然语言处理技术,智能客服助手可以分析用户情感状态,及时发现问题并优化服务。\n\n3.文本生成与创作\n描述:大语言模型能够生成符合语法规则的文章、新闻、小说等文本内容。通过学习大量文本数据,模型可以生成具有创造性和相关性的内容,广泛应用于新闻报道、广告营销等领域。此外,它还能根据给定主题或关键词生成文章,为创作者提供灵感和辅助。\n\n4.情感分析\n描述:大语言模型通过分析文本中的情感倾向和情感表达,帮助企业了解客户反馈和情感状态,从而制定更精准的营销策略或优化客户服务。这种技术还可用于社交媒体监控,实时分析公众对某一主题或事件的情绪和反应。\n\n5.自动问答系统\n描述:通过学习大量问题和答案,大语言模型能够自动生成符合语法规则的问题和答案。这种自动问答系统可应用于智能助手、搜索引擎等领域,为用户提供高效、准确的信息服务。结合知识图谱技术,问答系统的知识检索和推理能力得到进一步增强。\n\n6.自动摘要与总结\n描述:大语言模型能够自动对文本进行摘要和总结,提取关键信息,帮助用户快速了解文本主旨和重点。这种技术在学术论文、新闻报道等领域具有重要应用价值,提高了信息获取的效率。\n\n7.代码生成与自动化编程\n描述:大语言模型通过学习大量代码数据,可以理解编程语言的语法和逻辑规则,实现代码的自动生成。这有助于非技术用户生成基本代码,同时为专业编程人员提供辅助,加快开发进程。然而,在复杂任务中仍需人工审核和调整。\n\n8.信息检索与推荐系统\n描述:大语言模型可应用于改善搜索引擎结果和内容推荐算法。通过分析用户查询意图和上下文信息,模型能够提供更准确、个性化的搜索结果和内容推荐,提升用户体验和满意度。\n\n9.生物医学研究\n描述:在生物医学领域,大语言模型可用于分析基因组数据、蛋白质相互作用等,加速药物发现和新疗法的研究。例如,通过预测基因变异的功能影响,研究者能够更全面地分析人类基因组的潜在风险和治疗靶点。\n\n10.语音识别与生成\n描述:大语言模型在语音识别和语音生成方面也展现出巨大潜力。通过将语音转录为文本或将文本转化为语音,该技术使得人们与计算机的交互更加自然和便捷。这对于有听力或视觉障碍的人群尤为重要,有助于他们更好地理解和享受音视频内容。\n\n综上所述,大语言模型在多个领域都具有广泛的应用前景和巨大的价值潜力。随着技术的不断进步和完善,我们有理由相信大语言模型将在未来的人工智能领域发挥更加重要的作用。')]

PDF文件加载器

PyMuPDFLoader函数说明

classlangchain_community.document_loaders.pdf.PyMuPDFLoader(
file_path:str,*,
headers:Optional[Dict]=None,
extract_images:bool=False,
**kwargs:Any)

说明:

示例

fromlangchain_community.document_loadersimportPyMuPDFLoader

pdf_loader=PyMuPDFLoader(file_path="testfiles/测试文件.pdf")

docs=pdf_loader.load()
docs

运行结果:

#metadata数据详情
metadata={'source':'testfiles/测试文件.pdf',
'file_path':'testfiles/测试文件.pdf',
'page':0,'total_pages':21,
'format':'PDF1.6',
'title':'JSON是什么?',
'author':'番茄花园',
'subject':'',
'keywords':'',
'creator':'WPSOffice个人版',
'producer':'PDFlib7.0.3(C++/Win32)',
'creationDate':"D:20090304181435+08'00'",
'modDate':"D:20100525102623+08'00'",'trapped':''
}

原始PDF文件如下:

说明:通过对比可以看到

EXCEL文件加载器

UnstructuredExcelLoader函数说明

classlangchain_community.document_loaders.excel.UnstructuredExcelLoader(
file_path:Union[str,Path],
mode:str='single',
**unstructured_kwargs:Any)

说明:

示例

fromlangchain_community.document_loadersimportUnstructuredExcelLoader

excel_loader=UnstructuredExcelLoader(file_path="testfiles/测试文件.xlsx",encoding="utf8")

docs=excel_loader.load()
docs

运行结果:

原始文件:

PPT文件加载器

UnstructuredPowerPointLoader函数说明

classlangchain_community.document_loaders.powerpoint.UnstructuredPowerPointLoader(
file_path:Union[str,List[str],Path,List[Path]],*,
mode:str='single',
**unstructured_kwargs:Any)

说明:

示例

fromlangchain_community.document_loadersimportUnstructuredPowerPointLoader

ppt_loader=UnstructuredPowerPointLoader(file_path="testfiles/测试文件.pptx",mode="single")

docs=ppt_loader.load()

docs[0].page_content

运行结果:

原始文件:

说明:

WORD文件加载器

UnstructuredWordDocumentLoader函数说明

classlangchain_community.document_loaders.word_document.UnstructuredWordDocumentLoader(
file_path:Union[str,List[str],Path,List[Path]],*,
mode:str='single',
**unstructured_kwargs:Any)

说明:

示例

fromlangchain_community.document_loadersimportUnstructuredWordDocumentLoader

word_loader=UnstructuredWordDocumentLoader(file_path="testfiles/测试文件.docx",mode="single")

docs=ppt_loader.load()
docs

运行结果:

原始文件:

MARKDOWN文件加载器

UnstructuredMarkdownLoader函数说明

classlangchain_community.document_loaders.markdown.UnstructuredMarkdownLoader(
file_path:Union[str,List[str],Path,List[Path]],*,
mode:str='single',
**unstructured_kwargs:Any)

示例

fromlangchain_community.document_loadersimportUnstructuredMarkdownLoader

md_loader=UnstructuredMarkdownLoader(file_path="testfiles/测试文件.md",mode="single")

docs=md_loader.load()

docs

运行结果:

原始文件:

HTML文件加载器

UnstructuredHTMLLoader函数说明

classlangchain_community.document_loaders.html.UnstructuredHTMLLoader(
file_path:Union[str,List[str],Path,List[Path]],*,
mode:str='single',
**unstructured_kwargs:Any)

说明:

示例

fromlangchain_community.document_loadersimportUnstructuredHTMLLoader

html_file="testfiles/测试文件.htm"

html_loader=UnstructuredHTMLLoader(file_path=html_file,mode="single")

docs=html_loader.load()

docs[0].page_content

运行结果:

原始文件:

补充说明: 如果将上面的mode改为mode="elements",运行如下,但是得到内容对于建立知识库没有太大帮助。

SQL文件加载器

SQLDatabaseLoader函数说明

classlangchain_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)

说明:

示例

fromlangchain_community.document_loadersimportSQLDatabaseLoader
fromlangchain_community.utilitiesimportSQLDatabase
fromsqlalchemyimportcreate_engine

#创建SQLite数据库引擎,指定数据库文件的路径
engine=create_engine(url="sqlite:///testfiles/students.db")

#使用创建的引擎实例化SQLDatabase对象
db=SQLDatabase(engine=engine)

#创建SQLDatabaseLoader实例,指定要执行的SQL查询
sql_loader=SQLDatabaseLoader(query="SELECT*FROMstu_score;",db=db,
include_query_into_metadata=True,
include_rownum_into_metadata=True)

docs=sql_loader.load()
docs

运行结果:

原始文件:

以上只是对各类文件加载器的简单梳理,在实际应用中需要进行进一步的封装,例如:

在开源项目QAnything(网易的一款开源RAG系统)中,该项目中的qanything_kernel有着比较详细的封装,可以参考。

文档切分(SPLIT)

按照字符切分

CharacterTextSplitter类说明

classlangchain_text_splitters.character.CharacterTextSplitter:
def__init__(self,chunk_size:int,chunk_overlap:int=0):

说明:

示例

fromlangchain_community.document_loadersimportTextLoader
fromlangchain_text_splittersimportCharacterTextSplitter

text_loader=TextLoader(file_path="testfiles/测试文件.txt",encoding="utf8")

docs=text_loader.load()

#字符级文本切分器
spliter=CharacterTextSplitter(separator='\n\n',chunk_size=128,chunk_overlap=32)

results=spliter.split_documents(documents=docs)

#打印切分结果
print(f'切分个数:{len(results)}')

foridx,chunkinenumerate(results):
print(f'第{idx+1}段,长度为:{len(chunk.page_content)}')
print(f'切分内容:\n{chunk.page_content}')
print("-*-"*30+"\n")

运行结果:

#chunk_size=128,chunk_overlap=32
切分个数:12
第1段,长度为:50
切分内容:
大语言模型作为人工智能领域的重要技术之一,具有广泛的应用场景。以下是十个方面的应用场景及其详细描述:
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,长度为:124
切分内容:
1.机器翻译
描述:大语言模型通过训练可以学习不同语言之间的语法和语义规则,实现自动翻译。这种技术已广泛应用于跨国企业沟通、国际合作等领域,如谷歌翻译等产品。尽管在处理长句子和歧义消解等方面仍面临挑战,但随着技术的发展,其准确性和流畅度不断提升。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,长度为:131
切分内容:
2.智能客服与聊天机器人
描述:大语言模型被用于开发智能客服助手和聊天机器人,能够理解用户的问题并提供相应的解决方案或转达给相关部门。这不仅提高了客服效率,还提升了用户体验。例如,通过自然语言处理技术,智能客服助手可以分析用户情感状态,及时发现问题并优化服务。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第4段,长度为:125
切分内容:
3.文本生成与创作
描述:大语言模型能够生成符合语法规则的文章、新闻、小说等文本内容。通过学习大量文本数据,模型可以生成具有创造性和相关性的内容,广泛应用于新闻报道、广告营销等领域。此外,它还能根据给定主题或关键词生成文章,为创作者提供灵感和辅助。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第5段,长度为:106
...
切分内容:
综上所述,大语言模型在多个领域都具有广泛的应用前景和巨大的价值潜力。随着技术的不断进步和完善,我们有理由相信大语言模型将在未来的人工智能领域发挥更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
#如果改为chunk_size=512,chunk_overlap=32
切分个数:3
第1段,长度为:436
切分内容:
大语言模型作为人工智能领域的重要技术之一,具有广泛的应用场景。以下是十个方面的应用场景及其详细描述:

1.机器翻译
描述:大语言模型通过训练可以学习不同语言之间的语法和语义规则,实现自动翻译。这种技术已广泛应用于跨国企业沟通、国际合作等领域,如谷歌翻译等产品。尽管在处理长句子和歧义消解等方面仍面临挑战,但随着技术的发展,其准确性和流畅度不断提升。

2.智能客服与聊天机器人
描述:大语言模型被用于开发智能客服助手和聊天机器人,能够理解用户的问题并提供相应的解决方案或转达给相关部门。这不仅提高了客服效率,还提升了用户体验。例如,通过自然语言处理技术,智能客服助手可以分析用户情感状态,及时发现问题并优化服务。

3.文本生成与创作
描述:大语言模型能够生成符合语法规则的文章、新闻、小说等文本内容。通过学习大量文本数据,模型可以生成具有创造性和相关性的内容,广泛应用于新闻报道、广告营销等领域。此外,它还能根据给定主题或关键词生成文章,为创作者提供灵感和辅助。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,长度为:443
切分内容:
4.情感分析
描述:大语言模型通过分析文本中的情感倾向和情感表达,帮助企业了解客户反馈和情感状态,从而制定更精准的营销策略或优化客户服务。这种技术还可用于社交媒体监控,实时分析公众对某一主题或事件的情绪和反应。

5.自动问答系统
描述:通过学习大量问题和答案,大语言模型能够自动生成符合语法规则的问题和答案。这种自动问答系统可应用于智能助手、搜索引擎等领域,为用户提供高效、准确的信息服务。结合知识图谱技术,问答系统的知识检索和推理能力得到进一步增强。

6.自动摘要与总结
描述:大语言模型能够自动对文本进行摘要和总结,提取关键信息,帮助用户快速了解文本主旨和重点。这种技术在学术论文、新闻报道等领域具有重要应用价值,提高了信息获取的效率。
...

综上所述,大语言模型在多个领域都具有广泛的应用前景和巨大的价值潜力。随着技术的不断进步和完善,我们有理由相信大语言模型将在未来的人工智能领域发挥更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

递归方式切分

RecursiveCharacterTextSplitter函数说明

classlangchain_text_splitters.character.RecursiveCharacterTextSplitter(
separators:Optional[List[str]]=None,
keep_separator:bool=True,
is_separator_regex:bool=False,
**kwargs:Any
)

说明:

示例

fromlangchain_community.document_loadersimportTextLoader
fromlangchain_text_splittersimportRecursiveCharacterTextSplitter

text_loader=TextLoader(file_path="testfiles/测试文件.txt",encoding="utf8")

docs=text_loader.load()

separators=["\n",".","。","!","!","?","?",";",";","……","…","、",",",",",""]


#创建RecursiveCharacterTextSplitter实例
splitter=RecursiveCharacterTextSplitter(
separators=separators,
keep_separator=True,
is_separator_regex=False,
chunk_size=128,
chunk_overlap=32
)

results=splitter.split_documents(documents=docs)

#打印切分结果
print(f'切分个数:{len(results)}')

foridx,chunkinenumerate(results):
print(f'第{idx+1}段,长度为:{len(chunk.page_content)}')
print(f'切分内容:\n{chunk.page_content}')
print("-*-"*30+"\n")

运行结果:

切分个数:13
第1段,长度为:59
切分内容:
大语言模型作为人工智能领域的重要技术之一,具有广泛的应用场景。以下是十个方面的应用场景及其详细描述:

1.机器翻译
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,长度为:124
切分内容:
1.机器翻译
描述:大语言模型通过训练可以学习不同语言之间的语法和语义规则,实现自动翻译。这种技术已广泛应用于跨国企业沟通、国际合作等领域,如谷歌翻译等产品。尽管在处理长句子和歧义消解等方面仍面临挑战,但随着技术的发展,其准确性和流畅度不断提升。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,长度为:13
切分内容:
2.智能客服与聊天机器人
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第4段,长度为:117
切分内容:
描述:大语言模型被用于开发智能客服助手和聊天机器人,能够理解用户的问题并提供相应的解决方案或转达给相关部门。这不仅提高了客服效率,还提升了用户体验。例如,通过自然语言处理技术,智能客服助手可以分析用户情感状态,及时发现问题并优化服务。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第5段,长度为:125
...
切分内容:
综上所述,大语言模型在多个领域都具有广泛的应用前景和巨大的价值潜力。随着技术的不断进步和完善,我们有理由相信大语言模型将在未来的人工智能领域发挥更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

对比CharacterTextSplitter的执行结果,RecursiveCharacterTextSplitter在切分长文本时,可以切分出更小的文本片段,并且可以保留分隔符。

按照Token切分

TokenTextSplitter函数说明

classlangchain_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
)

说明:

importtiktoken
tiktoken.list_encoding_names()

#运行结果:
#['gpt2','r50k_base','p50k_base','p50k_edit','cl100k_base','o200k_base']

以上选项内容由ChatGPT辅助生成,如有错误,请及时反馈。

示例

importtiktoken
fromlangchain_community.document_loadersimportTextLoader
fromlangchain_text_splittersimportTokenTextSplitter

text_loader=TextLoader(file_path="testfiles/测试文件.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)


#打印切分结果
print(f'切分个数:{len(results)}')

foridx,chunkinenumerate(results):
print(f'第{idx+1}段,长度为:{len(chunk.page_content)}')
print(f'切分内容:\n{chunk.page_content}')
print("-*-"*30+"\n")

运行结果:

切分个数:13
第1段,长度为:185
切分内容:
大语言模型作为人工智能领域的重要技术之一,具有广泛的应用场景。以下是十个方面的应用场景及其详细描述:

1.机器翻译
描述:大语言模型通过训练可以学习不同语言之间的语法和语义规则,实现自动翻译。这种技术已广泛应用于跨国企业沟通、国际合作等领域,如谷歌翻译等产品。尽管在处理长句子和歧义消解等方面仍面临挑战,但随着技术的发展,其准确性和流畅度不断提升。

2.智能客服
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,长度为:198
切分内容:
种技术已广泛应用于跨国企业沟通、国际合作等领域,如谷歌翻译等产品。尽管在处理长句子和歧义消解等方面仍面临挑战,但随着技术的发展,其准确性和流畅度不断提升。

2.智能客服与聊天机器人
描述:大语言模型被用于开发智能客服助手和聊天机器人,能够理解用户的问题并提供相应的解决方案或转达给相关部门。这不仅提高了客服效率,还提升了用户体验。例如,通过自然语言处理技术,智能客服助手可以分析用户情感状态,
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,长度为:215
切分内容:
与聊天机器人
描述:大语言模型被用于开发智能客服助手和聊天机器人,能够理解用户的问题并提供相应的解决方案或转达给相关部门。这不仅提高了客服效率,还提升了用户体验。例如,通过自然语言处理技术,智能客服助手可以分析用户情感状态,及时发现问题并优化服务。

3.文本生成与创作
...

综上所述,大语言模型在多个领域都具有广泛的应用前景和巨大的价值潜力。随着技术的不断进步和完善,我们有理由相信大语言模型将在未来的人工智能领域发挥更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

如果将encoding_name设置为'gpt2',则切分结果如下:

切分个数:43
第1段,长度为:65
切分内容:
大语言模型作为人工智能领域的重要技术之一,具有广泛的应用场景。以下是十个方面的应用场景及其详细描述:

1.机器翻译
描述:大�
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,长度为:62
切分内容:
�下是十个方面的应用场景及其详细描述:

1.机器翻译
描述:大语言模型通过训练可以学习不同语言之间的语法和语义规则,实现
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,长度为:58
切分内容:
�言模型通过训练可以学习不同语言之间的语法和语义规则,实现自动翻译。这种技术已广泛应用于跨国企业沟通、国际合作等领�
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

通过对比,可以看到o200k_base的效果要优于gpt2。

按照markdown标题切分

示例

fromlangchain_community.document_loadersimportTextLoader
fromlangchain_text_splittersimportMarkdownTextSplitter

text_loader=TextLoader(file_path="testfiles/测试文件.md",encoding="utf8")

docs=text_loader.load()

#创建MarkdownTextSplitter实例
splitter=MarkdownTextSplitter(chunk_size=128,chunk_overlap=64)

results=splitter.split_documents(documents=docs)

#打印切分结果
print(f'切分个数:{len(results)}')

foridx,chunkinenumerate(results):
print(f'第{idx+1}段,长度为:{len(chunk.page_content)}')
print(f'切分内容:\n{chunk.page_content}')
print("-*-"*30+"\n")

运行结果:

切分个数:196
第1段,长度为:126
切分内容:
##前言
本章我们将通过LLaMA-Factory具体实践大模型训练的三个阶段,包括:预训练、监督微调和偏好纠正。

##大模型训练回顾
![](大模型训练的三个阶段.png)

##训练目标
通过实践大模型的三个训练阶段,训练一个医疗大模型
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,长度为:123
切分内容:
##训练过程实施
###准备训练框架
`LLaMAFactory`是一款开源低代码大模型微调框架,集成了业界最广泛使用的微调技术,支持通过WebUI界面零代码微调大模型,目前已经成为开源社区内最受欢迎的微调框架,GitHub星标超过2万。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,长度为:118
切分内容:
####运行环境要求
-硬件:
-GPU:推荐使用24GB显存的显卡或者更高配置
...
##参考资料
[Github:LLaMA-Factory的README文件](https://github.com/hiyouga/LLaMA-Factory/blob/main/data/README.md)
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

对于Markdown文本,使用MarkdownTextSplitter进行切分,切分效果比较好。

向量化(EMBED)

考虑到RAG系统一般都有私有化部署的需求(因为数据涉密),所以对应的向量化的方式有两种:本地化 和 在线化。

本地化

在开源项目QAnything中,其提供了一种使用本地模型的方法,其大致步骤是:

embedding_client=EmbeddingClient(
server_url=LOCAL_EMBED_SERVICE_URL,
model_name=LOCAL_EMBED_MODEL_NAME,
model_version='1',
resp_wait_s=120,
tokenizer_path='qanything_kernel/connector/embedding/embedding_model_0630')

由于示例代码的集成度较高,剥离核心代码执行成本较大,所以此处并未实践,只是引用相关的信息。

在线化

使用HuggingFaceEmbeddings

LangChain社区提供了HuggingFaceEmbeddings,该类可以加载HuggingFace的预训练模型,并使用该模型进行向量化。

fromlangchain_community.document_loadersimportTextLoader
fromlangchain_text_splittersimportRecursiveCharacterTextSplitter
fromlangchain_chromaimportChroma
fromlangchain.embeddingsimportHuggingFaceEmbeddings

#加载文本
text_loader=TextLoader(file_path="testfiles/测试文件.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")

#创建向量数据库
store=Chroma(embedding_function=embedding_function,persist_directory="chroma_data")

#将文档添加到数据库中
store.add_documents(documents=docs)

#进行相似性搜索
store.similarity_search(query="小米估值多少?",k=2)

说明:

运行结果:

[Document(metadata={'source':'testfiles/测试文件.txt'},page_content='1.机器翻译\n描述:大语言模型通过训练可以学习不同语言之间的语法和语义规则,实现自动翻译。这种技术已广泛应用于跨国企业沟通、国际合作等领域,如谷歌翻译等产品。尽管在处理长句子和歧义消解等方面仍面临挑战,但随着技术的发展,其准确性和流畅度不断提升。'),
Document(metadata={'source':'testfiles/测试文件.txt'},page_content='1.机器翻译\n描述:大语言模型通过训练可以学习不同语言之间的语法和语义规则,实现自动翻译。这种技术已广泛应用于跨国企业沟通、国际合作等领域,如谷歌翻译等产品。尽管在处理长句子和歧义消解等方面仍面临挑战,但随着技术的发展,其准确性和流畅度不断提升。')]

使用QianfanEmbeddings

由于Qwen的API有样本为6个的限制,所以此处试用百度千帆大模型的向量化API。

#util.py
defget_ernie_models():
"""
加载文心系列大模型
"""
#LLM大语言模型(单轮对话版)
fromlangchain_community.llmsimportQianfanLLMEndpoint

#Chat聊天版大模型(支持多轮对话)
fromlangchain_community.chat_modelsimportQianfanChatEndpoint

#Embeddings嵌入模型
fromlangchain_community.embeddingsimportQianfanEmbeddingsEndpoint

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")

returnllm,chat,embed
fromlangchain_community.document_loadersimportTextLoader
fromlangchain_text_splittersimportRecursiveCharacterTextSplitter
fromlangchain_chromaimportChroma
fromutilsimportget_ernie_models

#连接大模型
llm_ernie,chat_ernie,embed_ernie=get_ernie_models()

#加载文本
text_loader=TextLoader(file_path="testfiles/测试文件.txt",encoding="utf8")
docs=text_loader.load()

#切分文本
spliter=RecursiveCharacterTextSplitter(chunk_size=128,chunk_overlap=64)
docs=spliter.split_documents(documents=docs)

#使用ernie模型创建向量数据库
store=Chroma.from_documents(documents=docs,
embedding=embed_ernie,
persist_directory="chroma_data2")


store.similarity_search(query="小米估值多少?",k=2)

运行结果:

[Document(metadata={'source':'testfiles/测试文件.txt'},page_content='2.智能客服与聊天机器人'),
Document(metadata={'source':'testfiles/测试文件.txt'},page_content='大语言模型作为人工智能领域的重要技术之一,具有广泛的应用场景。以下是十个方面的应用场景及其详细描述:')]

通过对比

原理探寻

importnumpyasnp
fromutilsimportget_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.智能客服与聊天机器人"))
doc2=np.array(embed_ernie.embed_query(text="大语言模型作为人工智能领域的重要技术之一,具有广泛的应用场景。以下是十个方面的应用场景及其详细描述:"))


#欧式距离
result1=((query-doc1)**2).sum()
print(f'query和doc1的欧式距离为:{result1}')

result2=((query-doc2)**2).sum()
print(f'query和doc2的欧式距离为:{result2}')

#相关系数
corr1=1-result1/2**0.5
print(f'query和doc1的相关系数为:{corr1}')

corr2=1-result2/2**0.5
print(f'query和doc2的相关系数为:{corr2}')

运行结果:

#query和doc1的欧式距离为:0.6204636182956037
#query和doc2的欧式距离为:0.8112505547683875
#query和doc1的相关系数为:0.561265968023637
#query和doc2的相关系数为:0.42635923148192456

对比如下代码执行结果:

#相关性转换
store.similarity_search_with_relevance_scores(query="小米估值多少?",k=2)

运行结果:

[(Document(metadata={'source':'testfiles/测试文件.txt'},page_content='2.智能客服与聊天机器人'),
0.5612658250623314),
(Document(metadata={'source':'testfiles/测试文件.txt'},page_content='大语言模型作为人工智能领域的重要技术之一,具有广泛的应用场景。以下是十个方面的应用场景及其详细描述:'),
0.4263594055624078)]

由上可以看到:

存储(STORE)

如上述示例,我们对数据进行向量化之后,下一步需要存储至向量数据库。目前市面上的向量数据库众多,主流的向量数据库对比如下所示:

向量数据库URLGitHub StarLanguageCloud
chromachroma7.4KPython
milvusmilvus21.5KGo/Python/C++
pineconepinecone
qdrantqdrant11.8KRust
typesensetypesense12.9KC++
weaviateweaviate6.9KGo

本例中,我们主要了解Chroma的使用。

Chroma简介

介绍:Chroma 是一个开源的向量数据库,专为处理和存储高维向量而设计,特别适用于机器学习和深度学习应用。

特性:

资料:

Chroma使用的几种方式

初次了解Chroma的使用时,我被五花八门的API搞得云里雾里,一会是Chromadb,一会是langchain_chroma..... 因此,查询了部分资料之后,总结Chroma的使用方式大致是以下三种方式:

通过Chromadb的源生接口使用Chroma

Chroma 可以以多种形式进行使用:

本次实践中,主要尝试持久化模式Client/Server模式

持久化模式

第一步:安装chroma库

pipinstallchromadb-ihttps://pypi.tuna.tsinghua.edu.cn/simple

第二步:创建Chromadb实例

importchromadb
fromchromadbimportSettings

chroma_client=chromadb.PersistentClient(path="chroma_db")

第三步:创建或获取被查询集合

#方式一:创建一个新的集合
#collection=chroma_client.create_collection(name="my_collection")

#方式二:对于已存在的集合,可以直接通过名称获取,如果集合不存在会报错。
#collection=chroma_client.get_collection(name="my_collection")

#方式三:如果给定名称的集合已经存在则直接获取,否则创建。
collection=chroma_client.get_or_create_collection(name="my_collection")

第四步:添加数据到集合中

collection.add(
ids=["id1","id2","id3","id4","id5"],
documents=["浙江的省会是杭州","河北的省会是石家庄","山东的省会是济南","杭州是个美丽的城市","杭州位于浙江省"],
metadatas=[{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"}],
)

第五步:查询集合中的数据


results=collection.query(
query_texts=["西湖在哪个省?"],
n_results=2,
)

说明:

运行结果:

{'ids':[['id5','id1']],
'distances':[[0.669669112082433,0.6793151914879495]],
'metadatas':[[{'source':'myDoc'},{'source':'myDoc'}]],
'embeddings':None,
'documents':[['杭州位于浙江省','浙江的省会是杭州']],
'uris':None,
'data':None,
'included':['metadatas','documents','distances']}

Client/Server模式

第一步:启动Chroma服务端

chromarun--pathmy_chroma

说明:

第二步:创建Chromadb实例

importchromadb
fromchromadbimportClient
fromchromadbimportSettings

#配置连接信息
setting=Settings(chroma_server_host="localhost",
chroma_server_http_port=8000)

chroma_client=Client(settings=setting)

第三步:创建或获取被查询集合

collection=chroma_client.get_or_create_collection(name="my_collection")

第四步:添加数据到集合中

collection.add(
ids=["id1","id2","id3","id4","id5"],
documents=["浙江的省会是杭州","河北的省会是石家庄","山东的省会是济南","杭州是个美丽的城市","杭州位于浙江省"],
metadatas=[{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"}],
)

第五步:查询集合中的数据

results=collection.query(
query_texts=["西湖在哪个省?"],
n_results=2,
)
results

运行结果:

{'ids':[['id5','id1']],
'distances':[[0.6696690917015076,0.6793153882026672]],
'metadatas':[[{'source':'myDoc'},{'source':'myDoc'}]],
'embeddings':None,
'documents':[['杭州位于浙江省','浙江的省会是杭州']],
'uris':None,
'data':None,
'included':['metadatas','documents','distances']}

对比 本地持久化 和 Client/Server模式,两者的使用过程基本一致,只是在Client实例化时略有不同。

查看chromadb的源码,可以看到其内部实现了DB常见的各类增删改查操作:

备注:实际项目产品开发中,知识库需要通过上述的chromadb实现知识库的管理(增删改查)。

通过Langchain的组合包使用Chroma

除了上述chromadb的方式,也可以使用Langchain_chroma的方式使用Chroma,两者的使用场景区别是:

chromadb

langchain_chroma

具体使用方法:

fromlangchain.text_splitterimportCharacterTextSplitter
fromlangchain_chromaimportChroma
fromlangchain.document_loadersimportPyMuPDFLoader
fromchromadbimportSettings
fromutilsimportget_ernie_models
fromutilsimportget_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_function=embed_qwen,
client=client
)

batch_size=6#每次处理的样本数量

#分批入库
foriinrange(0,len(docs),batch_size):
batch=docs[i:i+batch_size]#获取当前批次的样本
chroma_db.add_documents(documents=batch)#入库

#查询
query="白骨精被打死几次?"
docs=chroma_db.similarity_search(query,k=3)

print(len(docs))

#打印结果
fordocindocs:
print("="*100)
print(doc.page_content)

运行结果:

说明:

西游记可以从夸克网盘:西游记下载

通过Retriever检索器的方式使用Chroma

在实际项目开发中,一般需要将Chroma的向量库作为检索器(Retriever)与模型组成chain链,以实现问答系统的问答能力。

使用方法

在上述Langchain_chroma的代码基础上,增加以下代码:

retriever=chroma_db.as_retriever(search_type="similarity_score_threshold",
search_kwargs={"k":4,"score_threshold":0.1})

retriever.invoke(input="白骨精被打死几次?")

运行结果:

函数说明:

1、as_retriever:功能:as_retriever 方法将 Chroma 数据库转换为一个检索器(retriever),使其能够根据给定的查询进行文档检索。这个检索器可以使用不同的搜索类型和参数来优化检索结果。

参数

2、invoke:功能:invoke 方法用于执行实际的检索操作,根据提供的输入查询返回相关的文档。参数

内容小结






欢迎光临 链载Ai (https://www.lianzai.com/) Powered by Discuz! X3.5