文章目录
Datawhale AI 夏令营 第四期 Task3:源大模型RAG实战
概要
在前面,我们成功搭建了一个源大模型智能对话Demo,亲身体验到了大模型出色的能力。然而,在实际业务场景中,通用的基础大模型可能存在无法满足我们需求的情况,主要有以下几方面原因:
- 知识局限性
- 数据安全性
- 大模型幻觉
为了上述这些问题,研究人员提出了检索增强生成(Retrieval Augmented Generation, RAG)的方法。这种方法通过引入外部知识,使大模型能够生成准确且符合上下文的答案,同时能够减少模型幻觉的出现。
本文章将以 Yuan2-2B-Mars 模型为基础,进行RAG实战。希望通过构建一个简化版的RAG系统,来帮助大家掌握RAG的核心技术,从而进一步了解一个完整的RAG链路。
RAG的整体架构
RAG通常包括以下三个基本步骤:
解释:
- 索引:将文档库分割成较短的 Chunk,即文本块或文档片段,然后构建成向量索引。
- 检索:计算问题和 Chunks 的相似度,检索出若干个相关的 Chunk。
- 生成:将检索到的Chunks作为背景信息,生成问题的回答。
技术名词解释
- Query:查询
- Retrieval:检索
- 离线计算
由于知识库中知识的数量和质量决定了RAG的效果,因此这是非常关键且必不可少的环节。
然后,我们会将知识库中的所有 Chunk 都转成向量,这一步也称为 向量化(Vectorization)或者 索引(Indexing)。
由于知识库中的所有 Chunk 都需要进行 向量化,这会使得计算量非常大,因此这一过程通常是离线完成的。 - 在线计算
在 检索 过程中,用户查询首先会经过向量模型得到相应的向量,然后与 数据库 中所有 Chunk 的向量计算相似度,最简单的例如 余弦相似度,然后得到最相近的一系列 Chunk 。
由于向量相似度的计算过程需要一定的时间,尤其是 数据库 非常大的时候。
这时,可以在检索之前进行 召回(Recall),即从 数据库 中快速获得大量大概率相关的 Chunk,然后只有这些 Chunk 会参与计算向量相似度。这样,计算的复杂度就从整个知识库降到了非常低。
召回 步骤不要求非常高的准确性,因此通常采用简单的基于字符串的匹配算法。由于这些算法不需要任何模型,速度会非常快, - 重排模型
随着知识库的增大,除了检索的速度变慢外,检索的效果也会出现退化,如下图中绿线所示:
这是由于 向量模型 能力有限,而随着知识库的增大,已经超出了其容量,因此准确性就会下降。在这种情况下,相似度最高的结果可能并不是最优的。
为了解决这一问题,提升RAG效果,研究者提出增加一个二阶段检索——重排 (Rerank),即利用 重排模型(Reranker),使得越相似的结果排名更靠前。这样就能实现准确率稳定增长,即数据越多,效果越好(如上图中紫线所示)。
源2.0-2B RAG实战
步骤一:2.0 PAI实例创建
实战之前,需要开通阿里云PAI-DSW试用,并在魔搭社区创建PAI实例。前面的文章已经介绍过了,如果不清楚可以参看下面这篇文章
开通阿里云PAI-DSW
步骤二:环境准备
需要先进入示例,并点击终端。如下图:
运行下面代码,下载文件,并将Task 3:源大模型RAG实战中内容拷贝到当前目录。
git lfs install
git clone https://www.modelscope.cn/datasets/Datawhale/AICamp_yuan_baseline.git
cp AICamp_yuan_baseline/Task\ 3:源大模型RAG实战/* .
双击打开Task 3:源大模型RAG实战.ipynb,然后运行所有单元格。
通过下面的命令,我们可以看到ModelScope已经提供了所需要的大部分依赖,如 torch,transformers 等。(这里就不展示图片了)
# 查看已安装依赖
pip list
但是为了进行模型微调以及Demo搭建,还需要在环境中安装streamlit。
# 安装 streamlit
pip install streamlit==1.24.0
安装成功后,我们的环境就准备好了。
步骤三:下载模型
我们需要构建一个向量模型。通常采用BERT架构。本文章中选用基于BERT架构的向量模型 bge-small-zh-v1.5,它是一个4层的BERT模型,最大输入长度512,输出的向量维度也为512。
不用担心,单元格2.2 模型下载 会自动执行向量模型和源大模型下载。
步骤四:RAG实战
运行代码在下面的Task 3:源大模型RAG实战.ipynb文件中,具体的代码不做过多解释。可以参看下面的链接:
RAG实战
修改代码,可以设置不同的问题。
运行代码,可以生成相应问题的回答。
步骤五:构建自己的知识库
在Task 3:源大模型RAG实战.ipynb文件中,代码调用了教程中给的知识库,即文本:
doecment_path = './knowledge.txt'
这个知识库的内容是:
现在我们要构建属于自己的知识库,需要换一个新的文本文件。
这里,建立了新的知识库文件myknowl.txt:
然后修改代码部分为:
print("> Create index...")
# doecment_path = './knowledge.txt'
doecment_path = './myknowl.txt'
index = VectorStoreIndex(doecment_path, embed_model)
运行发现模型能够读取我们自己创建的知识库中的内容。并根据问题生成回答。
在没有RAG时,如果模型只依赖自己的底层知识进行回答,就很容易出现幻觉,回答中会出现知识库中没有的知识,或者是出现明显的错误。如下图:
使用RAG之后,模型能够结果知识库中的知识,准确回答用户的提问。
小结
本文介绍了RAG的原理以及搭建流程,同时成功构建了自己需要的知识库。模型能够根据自己的知识库来回答问题。使用RAG后,能明显看出回答的准确性提高,幻觉减少。
本文章只是作为一个梳理,具体的教程可以参看下面的链接:
Task3 : RAG构建教程