从零开始搭建基于Langchain以及开源LLM的RAG 系统

一、RAG基础了解

欢迎大家微信搜索“AIGCmagic”关注公众号,回复“大模型”,加入大模型&GPT技术交流群,一起交流学习。

1.1、什么是RAG?

RAG (Retrieval-Augmented Generation) 是一种结合了检索和生成两种方法的自然语言处理(NLP)技术。它通过先检索相关的文档或信息,再使用生成模型(如GPT-3)生成答案。这种方法在处理需要丰富背景信息的问题时特别有效。

RAG不仅仅面向文本,它还可以面向语音、视频和图像等多模态场景,只要可以embedding的内容就可以。

RAG的主要流程如下:

  1. 检索(Retrieval):首先从一个大型文本数据库中检索出与问题相关的文档。这一步通常使用一种检索模型,如BM25或DPR(Dense Passage Retrieval)。

  2. 生成(Generation):接下来,将检索到的文档与问题一起输入到生成模型中,生成最终的答案。生成模型会根据检索到的文档内容生成一个连贯且有意义的回答。

这种方法的优点是它结合了检索和生成的优势,使得生成的答案不仅有语言上的流畅性,还能够基于实际的文档内容提供更准确和具体的信息。这在处理复杂的问答任务时特别有用,例如需要引用具体事实或数据的情况。
在这里插入图片描述

1.2、RAG文档召回率是什么?

RAG(Retrieval-Augmented Generation)中的文档召回率(Document Recall)是指在检索阶段,模型能够成功找到与用户查询相关的所有文档的比例。具体来说,它衡量的是在所有相关文档中,有多少被成功检索到了。

文档召回率是评估检索系统性能的重要指标。它可以用以下公式计算:
在这里插入图片描述

在RAG中,文档召回率的高低直接影响生成模型的表现。如果召回率低,生成模型可能会缺乏足够的背景信息,从而影响答案的准确性和相关性。

要提高文档召回率,可以采取以下措施:

  1. 改进检索模型:使用更先进的检索模型,如Dense Passage Retrieval (DPR) 或改进BM25算法,来提高相关文档的检索效果。

  2. 扩展检索范围:增加知识库的规模和多样性,以确保包含更多潜在相关文档。

  3. 优化检索策略:调整检索策略,使用多轮检索或结合多个检索模型的结果,来提高召回率。

高召回率可以确保生成模型有更丰富的信息源,从而提高最终生成答案的准确性和可靠性。

1.3、RAG在各行业业务场景中的需求分析

目前能涉及到RAG的行业有:金融、法律、生产型工厂、贸易公司、电商、餐饮、知识产权和文旅政务、医疗、通信、能源、教育(非义务教育)和交通等行业。

初期大部分还是根据已有文档,建立知识对话系统。也有一些企业让大模型参与到决策系统中来。
在这里插入图片描述

1.4、RAG技术的难点

(1)数据处理

目前的数据文档种类多,包括doc、ppt、excel、pdf扫描版和文字版。ppt和pdf中包含大量架构图、流程图、展示图片等都比较难提取。而且抽取出来的文字信息,不完整,碎片化程度比较严重。

而且在很多时候流程图,架构图多以形状元素在PPT中呈现,光提取文字,大量潜藏的信息就完全丢失了。

(2)数据切片方式

不同文档结构影响,需要不同的切片方式,切片太大,查询精准度会降低,切片太小一段话可能被切成好几块,每一段文本包含的语义信息是不完整的。

(3)内部知识专有名词不好查询

目前较多的方式是向量查询,对于专有名词非常不友好;影响了生成向量的精准度,以及大模型输出的效果。

(4)新旧版本文档同时存在

一些技术报告可能是周期更新的,召回的文档如下就会出现前后版本。

(5)复杂逻辑推理

对于无法在某一段落中直接找到答案的,需要深层次推理的问题难度较大。

(6)金融行业公式计算

如果需要计算行业内一些专业的数据,套用公式,对RAG有很大的难度。

(7)向量检索的局限性

向量检索是基于词向量的相似度计算,如果查询语句太短词向量可能无法反映出它们的真实含义,也无法和其他相关的文档进行有效的匹配。这样就会导致向量检索的结果不准确,甚至出现一些完全不相关的内容。

(8)长文本

(9)多轮问答

1.5、RAG的架构

https://pub.towardsai.net/advanced-rag-techniques-an-illustrated-overview-04d193d8fec6?gi=0eea544f219a

在这里插入图片描述
在这里插入图片描述

1.6、RAG存在的一些问题和避免方式

(1)分块(Chunking)策略以及Top-k算法

一个成熟的RAG应该支持灵活的分块,并且可以添加一点重叠以防止信息丢失。用固定的、不适合的分块策略会造成相关度下降。最好是根据文本情况去适应。或者是在定位到关键语句以后进行上下文进行扩充,然后进行重排序。

在大多数设计中,top_k是一个固定的数字。因此,如果块大小太小或块中的信息不够密集,我们可能无法从向量数据库中提取所有必要的信息。

(2)世界知识缺失

比如我们正在构建一个《西游记》的问答系统。我们已经把所有的《西游记》的故事导入到一个向量数据库中。现在,我们问它:人有几个头?

最有可能的是,系统会回答3个,因为里面提到了哪吒有“三头六臂”,也有可能会说很多个,因为孙悟空在车迟国的时候砍了很多次头。而问题的关键是小说里面不会正儿八经地去描述人有多少个头,所以RAG的数据有可能会和真实世界知识脱离。

(3)多跳问题(推理能力)

让我们考虑另一个场景:我们建立了一个基于社交媒体的RAG系统。那么我们的问题是:谁知道埃隆·马斯克?然后,系统将遍历向量数据库,提取埃隆·马斯克的联系人列表。由于chunk大小和top_k的限制,我们可以预期列表是不完整的;然而,从功能上讲,它是有效的。

现在,如果我们重新思考这个问题:除了艾梅柏·希尔德,谁能把约翰尼·德普介绍给伊隆·马斯克?单次信息检索无法回答这类问题。这种类型的问题被称为多跳问答。解决这个问题的一个方法是:

找回埃隆·马斯克的所有联系人

找回约翰尼·德普的所有联系人

看看这两个结果之间是否有交集,除了艾梅柏·希尔德

如果有交集,返回结果,或者将埃隆·马斯克和约翰尼·德普的联系方式扩展到他们朋友的联系方式并再次检查。

有几种架构来适应这种复杂的算法,其中一个使用像ReACT这样复杂的prompt工程,另一个使用外部图形数据库来辅助推理。我们只需要知道这是RAG系统的限制之一。

(4)信息丢失

RAG系统中的流程链:

将文本分块(chunking)并生成块(chunk)的Embedding
通过语义相似度搜索检索数据块
根据top-k块的文本生成响应

二、版面分析方法介绍

2.1、基于yolov5的版面结构检测

AG系统搭建过程中,版面分析是不可缺少的一个步骤,本文介绍用yolov5进行版面结构信息识别,后续再搭配表格识别、公式识别、文字识别等模块进行版面还原,完成PDF结构化输出。

添加图片注释,不超过 140 字(可选)

2.1.1、环境搭建

conda create -n yolov5-pdf python=3.10
conda activate yolov5-pdf
git clone https://github.com/ultralytics/yolov5.git
cd yolov5
pip   install  -r requirements.txt

等待安装完毕。

2.1.2、下载yolov5预训练权重放在根目录下。

添加图片注释,不超过 140 字(可选)

2.1.3、准备数据集

本次训练采用CDLA数据集来进行模型训练。
数据来源:https://github.com/buptlihang/CDLA
数据简介:CDLA数据集的训练集包含5000张图像,验证集包含1000张图像。该数据集包括10个类别,分别是:Text, Title, Figure, Figure caption, Table, Table caption, Header, Footer, Reference, Equation。
备注:基于PaddleDetection套件,在该数据集上训练目标检测模型时,在转换label时,需要将label.txt中的__ignore__与_background_去除。
原版数据百度云下载:https://pan.baidu.com/s/1449mhds2ze5JLk-88yKVAA, 提取码: tp0d
Google Drive Download:https://drive.google.com/file/d/14SUsp_TG8OPdK0VthRXBcAbYzIBjSNLm/view?usp=sharing
原版数据下载以后需要对格式进行转换,才能用yolov5进行训练,json转换代码如下:

import json 
import os 
import argparse
from tqdm import tqdm
import glob
import cv2 
import numpy as np
 
def convert_label_json(json_dir,save_dir,classes):
    files=os.listdir(json_dir)
    #删选出json文件
    jsonFiles=[]
    for file in files:
        if os.path.splitext(file)[1]==".json":
            jsonFiles.append(file)
    #获取类型        
    classes=classes.split(',')
 
    #获取json对应中对应元素
    for json_path in tqdm(jsonFiles):
        path=os.path.join(json_dir,json_path)
        with open(path,'r') as loadFile:
            print(loadFile)
            json_dict=json.load(loadFile)
        h,w=json_dict['imageHeight'],json_dict['imageWidth']
        txt_path=os.path.join(save_dir,json_path.replace('json','txt'))
        txt_file=open(txt_path,'w')
 
        for shape_dict in json_dict['shapes']:
            label=shape_dict['label'] 
            label_index=classes.index(label)
            points=shape_dict['points']
            points_nor_list=[]
            for point in points:
                points_nor_list.append(point[0]/w)
                points_nor_list.append(point[1]/h)
            points_nor_list=list(map(lambda x:str(x),points_nor_list))
            points_nor_str=' '.join(points_nor_list)
            label_str=str(label_index)+' '+points_nor_str+'\n'
            txt_file.writelines(label_str)
 
 
if __name__=="__main__":
    parser=argparse.ArgumentParser(description="json convert to txt params")
    #设json文件所在地址
    parser.add_argument('-json',type=str,default='/CDLA_DATASET/train',help='json path')
    #设置txt文件保存地址
    parser.add_argument('-save',type=str,default='/train/labels',help='save path')
    #设置label类型,用“,”分隔
    parser.add_argument('-classes',type=str,default='Text,Title,Figure,Figure caption,Table,Table caption,Header,Footer,Reference,Equation',help='classes')
    args=parser.parse_args()
    print(args.json,args.save,args.classes)
    convert_label_json(args.json,args.save,args.classes)

这里有我转换为yolov5的数据集可以直接下载使用
yolo数据下载链接: https://pan.baidu.com/s/1Du2_TifmUlwMkug8F3HUYA?pwd=pbyd 提取码: pbyd

2.1.4、训练参数修改

a、data里面.ymal文件修改

# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: /yolodata # dataset root dir
train: train/images # train images (relative to 'path') 118287 images
val: val/images # val images (relative to 'path') 5000 images
test: val/images # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794
# Classes
names:
   0: Text
   1: Title
   2: Figure
   3: Figure caption
   4: Table
   5: Table caption
   6: Header
   7: Footer
   8: Reference
   9: Equation

b、yolov5s.yaml文件修改(预训练模型选择s就改s,选哪个就改那个)
只需要将nc:80改成nc:10;
c、train.py文件修改
在这里插入图片描述
需要修改–weights、–cfg、–data、–epochs、–batch-size.

2.1.5、开始训练

python train.py

2.1.6、训练完毕

在这里插入图片描述
模型权重在weights文件夹内部,一般使用best.pt。

2.1.7、模型效果测试

使用detect.py进行测试。
在这里插入图片描述
需要修改–weights、–data。
结果如下:

在这里插入图片描述

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值