首先,结合本次比赛的需求以及RAG本身,
找到主要任务
什么是RAG?
RAG 的全称是Retrieval-Augmented Generation,即检索增强生成。
这是一种结合了信息检索与生成式人工智能的技术框架。其核心逻辑是:在生成回答之前,先从大规模的知识库(如文档、数据库等)中检索出与当前问题相关的信息,然后将这些检索到的信息作为辅助材料,输入到生成模型中,让模型基于这些具体信息生成更准确、更具针对性的回答。
在本次算法比赛中,主办方的具体要求如下:
比赛将提供一个包含多个图文混排PDF文档的知识库,以及一系列包含文本和图像依赖性问题的测试查询。评估指标将侧重于答案的准确性、完整性、信息关联性以及可解释性(即是否能指明信息来源)。
参赛系统需要完成以下任务:
1)多模态信息理解:能够同时理解用户提出的自然语言问题以及知识库中的图像和文本内容。
2)跨模态检索:从给定的多个PDF文档中,高效地检索与用户查询相关的图像、图表、文本段落或它们的组合。
3)图文关联推理:将检索到的图像信息与文本信息进行有效关联和融合,进行深层次的逻辑推理,以回答需要多模态理解的问题。
4)答案生成:基于检索和推理的结果,生成准确、简洁、符合上下文的答案。答案中应清晰指出信息来源(例如,来自哪个PDF的哪一页,甚至哪个图表)。
评审规则:
该评分函数主要从三个方面对每个问题的回答进行评估,每个提问并计算一个综合分数:
- a.页面匹配度(满分0.25 分)
- b.文件名匹配度(满分0.25 分)
- c.答案内容相似度(满分0.5 分):将字符交集大小除以并集大小,得到 Jaccard 相似系数,范围在 0 到 1 之间。
因此,最终我们要完成的任务是:
- 将图文混合的PDF进行处理,使得模型可以更快地处理数据,而且能够输出答案来自哪个PDF的哪一页,甚至哪个图表。
- 训练模型,输入处理后的数据,得到输出。
Baseline具体做法与分析
1. 预处理(离线完成) (对应任务一):
- 使用pymupdf批量解析所有PDF文档,得到结构化的JSON数据。
- 将原始的文本块,以及图片的描述文本,附带上它们的元数据(
filename,page),构造成我们第一步设计的核心数据结构。 - 调用
Xinference部署的Embedding模型服务,将所有内容的文本部分转换为向量。 - 将最终的
{ "id":"……","content": "...", "vector": [...], "metadata": ... }存入向量数据库,完成知识库构建。
2. 在线推理 (对应任务二):
- 接收测试集的json文件中的一个
question。 - 调用
Xinference服务,将question向量化。 - 在向量数据库中进行相似度搜索,召回Top-K个最相关的内容块。
- 将召回的内容块及其元数据,与
question一同填入设计好的Prompt模板中。 - 将完整的Prompt交给一个大语言模型(LLM),生成最终的答案和来源信息。
3. 图解:
4. 缺点:
- 信息损失 :没有提取图片里面的内容。
- 上下文割裂 :将文档按照页面切分成独立的块进行检索,可能会破坏原文中段落与段落、段落与图表之间的上下文关联。检索出的知识块可能是孤立的,缺乏上下文。
- 检索策略单一 :仅基于语义相似度的检索,对于一些包含特定关键词或需要大范围信息整合的问题,可能不是最优解。
5. 未来方向:
- 能否用更精细的方式分隔页面?如何得到跨越了多个块的信息?
- 仅仅将图片用文本描述是否不够精确?能否用更好的方式处理图片?
- 在找回Top-k个内容块后,能否进行二次筛选,选出最接近的内容块?
- 能否写出更精确的prompt?
改进Baseline
本次夏令营中,主办方给出了对于Baseline的改进方案。列出来作为参考:
1. 用MinerU来处理PDF:
RAG的效果很大程度上依赖于知识库的质量。如果源头就是有信息损失的,后续再怎么处理效果也有限。
像 MinerU 这样的工具能帮助我们进行版面分析,区分出标题、段落、表格和图片,并且能把表格转换成 Markdown 这种结构化格式。
这样处理后,知识库的内容就比纯文本丰富多了。
加入mineru进行解析,我们的项目流程图就会变成这样:
但是由于MinerU太过于耗时间,所以我在这一步就止步不前了
2. 召回-重排:
当知识库内容更丰富后,如何精确查找就变得更重要。
我们可以采用一个两步走的检索策略,也就是先“召回”再“重排”。
- 第一步“召回” ,用向量检索或者关键词检索(比如BM25算法),快速地找到一个比较大的候选范围,目的是把相关的都找出来。
- 第二步“重排” ,用一个更精准的重排模型,比如 FlagEmbedding 仓库里的 BGE-ReRanker 模型,来给这些候选项和问题的相关性打分,然后选出分数最高的几个。
这种方式能有效地提升检索结果的信噪比。
其中rerank的模型可以使用FlagEmbedding进行推理:
from FlagEmbedding import FlagReranker
model = FlagReranker(
'BAAI/bge-reranker-large',
use_fp16=True,
devices=["cuda:0"], # 如果没有 GPU,可以使用 "cpu"
)
pairs = [
["法国的首都是什么?", "巴黎是法国的首都。"],
["法国的首都是什么?", "中国的人口超过14亿人。"],
["中国的人口是多少?", "巴黎是法国的首都。"],
["中国的人口是多少?", "中国的人口超过14亿人。"]
]
scores = model.compute_score(pairs)
scores
3. 对模型进行Lora微调:
有了标准格式的训练数据,我们就可以开始进行模型的有监督微调(Supervised Fine-Tuning, SFT),使模型对本次任务具备更强的针对性。