【Datawhale-tinyuniverse】TinyRAG学习


TinyRAG学习


根据Datawhale开源的Tiny-RAG1,通过调用学习RAG基本流程。

一、RAG是什么?

RAG(Retrieval-Augmented Generation),检索增强生成技术。在已有知识库上检索询问大模型问题的相关内容,构建上下文条件,引导大模型生成回答,以缓解因时效性和专业性导致的生成内容不准确问题。RAG关键在于Retrieval(检索)和Generation(引导生成)。

RAG的基本结构:

  • 文档加载和切分的模块,可以处理多种文件类型。
  • 向量化模块,将切分得到的文档片段向量化。
  • 向量数据库,存放文档片段和对应的向量表示,可降低成本。
  • 检索模块,用来根据 Query (问题)检索相关的文档片段。
  • 大模型模块,用来根据检索出来的文档回答用户的问题。

二、调用实现

在本地jupyter notebook中实现。

1.实现前准备

采用阿里云模型服务灵积dashscope作为API提供方,LLM采用qwen-turbo,embedding采用text-embedding-v1。知识库文档存放在’./data’路径下,向量数据库存放在’./storage’路径下。

  1. 安装必要的三方库

python-dotenv
PyPDF2
markdown
html2text
tiktoken
beautifulsoup4

  1. 在jupyter环境目录下创建.env文件,配置DASHSCOPE_API_KEY
  2. 准备知识库(节选了百度百科描述氨基酸的一段文字2,并存为txt)。

2.实现

  1. 导入必要的库
from RAG.VectorBase import VectorStore #向量操作
from RAG.utils import ReadFiles #文件操作
from RAG.LLM import DashscopeChat #大模型生成
from RAG.Embeddings import DashscopeEmbedding #嵌入方法
  1. 获取切分知识库内容
# 循环遍历data中文档,以600token为一段,其中包含上一段内容后150token内容
# enc = tiktoken.get_encoding("cl100k_base") token切分器,将输入文本切分
docs = ReadFiles('./data').get_content(max_token_len=600, cover_content=150)

共分割出两段文本:
[1.‘氨基酸,是一类含有碱性氨基和酸性羧基的两性有机化合物,是生物功能大分子蛋白质的基本组成单位。\n氨基酸大类可分为蛋白质氨基酸和非蛋白质氨基酸。其中蛋白质氨基酸又称标准氨基酸,直接参与蛋白质分子合成的氨基酸。依据氨基连在碳链上的不同位置,可将氨基酸分为α-,β-,γ-等氨基酸,但生物界中构成天然蛋白质的氨基酸均为α-氨基酸,共22种,包括20种常见氨基酸以及2种不常见氨基酸。非蛋白质氨基酸则不能直接参与蛋白质分子合成,需经过修饰才能参与蛋白质的合成,如瓜氨酸、鸟氨酸和羟脯氨酸。\n’,
2.‘蛋白质分子合成的氨基酸。依据氨基连在碳链上的不同位置,可将氨基酸分为α-,β-,γ-等氨基酸,但生物界中构成天然蛋白质的氨基酸均为α-氨基酸,共22种,包括20种常见氨基酸以及2种不常见氨基酸。非蛋白质氨基酸则不能直接参与蛋白质分子合成,需经过修饰才能参与蛋白质的合成,如瓜氨酸、鸟氨酸和羟脯氨酸。\n氨基酸因其结构、R基团等不同而具有不同的性质,如等电点、旋光性等。氨基酸的检测也可以根据这些性质的不同进行筛选和鉴定。目前发展起来的检测方法有分光光度法、液相色谱、气相色谱、红外检测等多种方法。氨基酸在生物体是用于制造抗体蛋白、血红蛋白、酶蛋白、激素蛋白、神经递质物质的等原材料,甚至可以用来为生物体提供能量来源。可以说氨基酸是一切生命之源。\n’]

  1. 建立vector数据库(首次)
vector = VectorStore(docs) # 传入分割好的文本数组,初始化vector对象
embedding = DashscopeEmbedding() #初始化embedding model
vector.get_vector(EmbeddingModel=embedding) #通过model向量化文本
vector.persist(path='storage') # 将向量和文档内容保存到storage目录下,存为json文件
  1. 加载vector数据库内容(非首次)
vector = VectorStore() # 初始化vector对象
embedding = DashscopeEmbedding() #初始化embedding model
vector.load_vector('./storage') # 加载本地数据库
  1. 提问编码&内容检索
question = '给出氨基酸的定义'
# embedding问题并检索出与数据库文本中相似度最高的一条内容
# 通过计算向量间余弦相似度(cosine_similarity)来确定
content = vector.query(question, EmbeddingModel=embedding, k=1)[0]

问题与向量数据库文本段的余弦相似度
[0.733718 0.66391132]
返回第一段文本
氨基酸,是一类含有碱性氨基和酸性羧基的两性有机化合物,是生物功能大分子蛋白质的基本组成单位。
氨基酸大类可分为蛋白质氨基酸和非蛋白质氨基酸。其中蛋白质氨基酸又称标准氨基酸,直接参与蛋白质分子合成的氨基酸。依据氨基连在碳链上的不同位置,可将氨基酸分为α-,β-,γ-等氨基酸,但生物界中构成天然蛋白质的氨基酸均为α-氨基酸,共22种,包括20种常见氨基酸以及2种不常见氨基酸。非蛋白质氨基酸则不能直接参与蛋白质分子合成,需经过修饰才能参与蛋白质的合成,如瓜氨酸、鸟氨酸和羟脯氨酸。

# 使用的prompt,只回答与知识库相关问题
PROMPT_TEMPLATE = dict(
    RAG_PROMPT_TEMPALTE="""使用以上下文来回答用户的问题。如果你不知道答案,就说你不知道。总是使用中文回答。
        问题: {question}
        可参考的上下文:
        ···
        {context}
        ···
        如果给定的上下文无法让你做出回答,请回答数据库中没有这个内容,你不知道。
        有用的回答:""")
model.chat(question, [], content)

模型生成内容
氨基酸是一种含碱性氨基和酸性羧基的两性有机化合物,它是生物功能大分子蛋白质的基本组成单位。在生物界,构成天然蛋白质的氨基酸都是α-氨基酸,一共有22种,其中20种是常见的,另外两种是不常见的。蛋白质氨基酸可以直接参与蛋白质的合成,而非蛋白质氨基酸则需要经过修饰才能参与。

# 提问与知识库不相关问题
question1 = '你了解Datawhale吗?'

相似度
[0.02817204 0.03030824]
模型生成内容
我不了解Datawhale。

# 提问多样
question2 = '氨基酸的作用有哪些'

相似度
[0.65997077 0.62575936]
模型生成内容
氨基酸的主要作用有:

  1. 蛋白质合成:氨基酸是蛋白质的基本组成单位,通过脱水缩合反应,形成肽键,进而构建出各种类型的蛋白质,这些蛋白质承担了生命体中的众多功能,如结构支撑、酶催化、免疫反应等。
  2. 代谢调节:部分氨基酸还参与代谢途径,例如作为氮源,参与体内氨基酸代谢和氨的代谢。
  3. 信号传递:一些氨基酸衍生物,如神经递质(如谷氨酸、多巴胺),在神经传递过程中起到关键作用。
  4. 能量供应:在糖分解不足时,氨基酸可以通过转氨基作用产生能量。
  5. 抗氧化:某些氨基酸如色氨酸和半胱氨酸具有抗氧化作用。
  6. 营养素:对于某些营养不良的情况,补充特定的氨基酸可以提供必要的营养。
    这些都是氨基酸在生物体内的主要功能。

三、总结

  1. 仅简单调用实现整个流程,可自己部署开源LLM。
  2. 在最后一个问题中,通过余弦相似度未选择出合适的文本段,可采用bert等方法实现语义相似度的比较。

  1. TinyRAG链接 ↩︎

  2. 百度百科-氨基酸描述 ↩︎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值