当前位置: 首页 > news >正文

Datawhale AI夏令营第三期多模态RAG方向 Task3

1.baseline优化路径

  1. 升级数据解析核心 :放弃 PyMuPDF, 切换到 MinerU 。
  2. 优化分块与索引策略 :有了 MinerU 精细化的解析结果,我们可以进行对 图片进行进一步的内容解释,添加图片的描述信息。

  3. 引入重排(Re-ranking)

  4. 实施模型微调 :让模型更适应财报问答的场景。

    1. 微调Embedding模型 :利用 train.json 中的问答对构造训练数据,让模型学习财报领域的语义关系,提升检索召回的准确率。

具体步骤可能包括:

  1. 数据预处理
    • 从 train.json 中提取问答对。
    • 构造正样本(匹配的问答对)和负样本(不匹配的问答对)。
    • 如果数据量不足,可能需要数据增强(比如同义句改写)。
  2. 选择损失函数
    • 常用的损失函数包括:
      • 余弦相似度损失:让正样本的向量更接近,负样本的向量更远。
      • 对比损失(Contrastive Loss):强化正负样本的区分。
      • 三元组损失(Triplet Loss):使用锚点、正样本、负样本三元组,确保正样本比负样本更接近锚点。
  3. 微调模型
    • 使用预训练的 Embedding 模型(如 Sentence-BERT、MiniLM)。
    • 在财报领域的问答对上进行微调,调整模型参数。
  4. 评估效果
    • 在验证集上测试模型的检索性能,比如计算召回率(Recall@K)、准确率(Precision@K)或平均倒数排名(MRR)。
  5. 应用到检索任务:将微调后的模型用于财报领域的语义搜索或问答系统,输入问题,输出与问题语义最匹配的答案。

        2. 微调LLM :利用 train.json 构造“指令-上下文-回答”格式的数据,对LLM进行指令微调。主要目的是让LLM更“听话”,能更忠实地根据我们提供的上下文作答,并严格按照要求的格式输出答案和来源。

5.运行全量测试数据:修改rag_from_page_chunks.py文件里面的变量TEST_SAMPLE_NUM,将原来的10改成None

运行过程中遇到了遇到了 RateLimitError(错误代码 429),提示达到了 API 的速率限制(TPM limit reached,可能是每分钟 token 限制)

[515/806] 正在处理: 千味央厨公司在2022年的盈利预测与评级如何?...                                      
[516/806] 正在处理: 广联达(002410)公司点评报告中,新成本平台的市场空间如...                               
[517/806] 正在处理: 根据《伊利专业乳品2022中国现制茶饮渠道消费者与行业趋势报...                               
[518/806] 正在处理: 根据《2022中国现制茶饮渠道消费者与行业趋势报告》中的内容...                               
并发批量生成:  58%|███████████████▌           | 465/806 [38:34<28:17,  4.98s/it]
Traceback (most recent call last):File "/mnt/workspace/AISumerCamp_multiModal_RAG/rag_from_page_chunks.py", line 191, in <module>results = list(tqdm(executor.map(process_one, selected_indices), total=len(selected_indices), desc='并发批量生成'))^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/usr/local/lib/python3.11/site-packages/tqdm/std.py", line 1181, in __iter__for obj in iterable:File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 619, in result_iteratoryield _result_or_cancel(fs.pop())^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 317, in _result_or_cancelreturn fut.result(timeout)^^^^^^^^^^^^^^^^^^^File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 449, in resultreturn self.__get_result()^^^^^^^^^^^^^^^^^^^File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_resultraise self._exceptionFile "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in runresult = self.fn(*self.args, **self.kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/mnt/workspace/AISumerCamp_multiModal_RAG/rag_from_page_chunks.py", line 185, in process_oneresult = rag.generate_answer(question, top_k=5)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/mnt/workspace/AISumerCamp_multiModal_RAG/rag_from_page_chunks.py", line 112, in generate_answercompletion = client.chat.completions.create(^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/usr/local/lib/python3.11/site-packages/openai/_utils/_utils.py", line 287, in wrapperreturn func(*args, **kwargs)^^^^^^^^^^^^^^^^^^^^^File "/usr/local/lib/python3.11/site-packages/openai/resources/chat/completions/completions.py", line 1087, in createreturn self._post(^^^^^^^^^^^File "/usr/local/lib/python3.11/site-packages/openai/_base_client.py", line 1249, in postreturn cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/usr/local/lib/python3.11/site-packages/openai/_base_client.py", line 1037, in requestraise self._make_status_error_from_response(err.response) from None
openai.RateLimitError: Error code: 429 - {'message': 'Request was rejected due to rate limiting. Details: TPM limit reached.', 'data': None}

2.进阶要点

进阶要点1:提取文档的多模态内容

像 MinerU 这样的工具能帮助我们进行版面分析,区分出标题、段落、表格和图片,并且能把表格转换成 Markdown 这种结构化格式。

这样处理后,知识库的内容就比纯文本丰富多了。

对于解析出来的图片,我们可以用多模态大模型,比如 Qwen-VL,来生成文字描述,把图片信息也文本化,方便后续的检索。

其中使用mineru进行解析内容的版本在我们的github仓库内是有提供的,文件名字叫做mineru_pipeline_all.py

将 baseline 中运行 fitz_pipeline_all.py 的命令( !python fitz_pipeline_all.py)替换为 !python mineru_pipeline_all.py,可以切换到使用 MinerU 解析 PDF 并生成 all_pdf_page_chunks.json

在requirement.txt中将mineru解除注释

在GPU环境下运行mineru_pipeline_all.py

运行时出现报错:

Traceback (most recent call last):File "/mnt/workspace/AISumerCamp_multiModal_RAG/mineru_pipeline_all.py", line 7, in <module>from image_utils.async_image_analysis import AsyncImageAnalysis
ModuleNotFoundError: No module named 'image_utils'

requirements.txt文件中加入image_utils

代码详解:

第一步:用 MinerU 解析 PDF ( parse_all_pdfs 函数)

这是所有工作的起点。这个函数会遍历指定的文件夹,找到所有 PDF 文件。

对于每一个 PDF,它会调用 mineru_parse_pdf.do_parse 这个核心功能。

do_parse 是 MinerU 发挥作用的地方,它会去分析 PDF 的版面布局,识别出里面的文本、标题、表格和图片,然后把这些识别出的所有内容元素,连同它们的类型、位置、层级等信息,都存进一个名为 _content_list.json 的文件里。

可以把它看作是 MinerU 对整个 PDF 进行的一次精细化扫描和内容提取,产出的是最原始、最详细的结构化数据。

第二步:将解析结果整理成 Markdown 格式 ( process_all_pdfs_to_page_json 函数)

拿到第一步的原始数据后,这一步的目标是把它整理成对后续模型更友好的格式。它会读取 _content_list.json ,先按页码把内容分好组,然后逐个处理每一页里的内容项。

这里面最关键的逻辑在 item_to_markdown 函数里。这个函数是一个转换器,它根据内容项的类型( type )来决定如何转换:

  • 如果是 text ,它会根据文本的层级( text_level )加上 Markdown 的标题符号,比如一级标题就变成 # 标题

  • 如果是 table ,它会把表格的 HTML 代码直接拿过来用,并附上表格的标题。

  • 如果是 image ,它会生成 Markdown 的图片语法 ![图片描述](图片路径)

代码会检查图片本身有没有自带的文字描述( caption )。

如果没有,并且我们允许进行视觉分析( enable_image_caption=True ),

它就会调用一个多模态大模型(代码里指定的是 Qwen/Qwen2.5-VL-32B-Instruct )来给这张图片生成一段描述。

这就把图片这种非文本信息,也转化成了可以被检索的文本,极大地丰富了知识库的内容,当然,你也可以强制要求使用多模态模型直接生成图片的描述信息。

这一步完成之后,我们会为每个 PDF 生成一个 _page_content.json 文件,里面记录了每一页转换成的完整 Markdown 文本。

第三步:汇总所有内容,生成最终的知识库文件 ( process_page_content_to_chunks 函数)

这是最后一步的整合工作。

它会遍历第二步生成的所有 _page_content.json 文件,把每一页的内容都封装成一个标准的“知识块”(chunk)。

每个 chunk 都是一个字典,包含三个关键信息:一个唯一的 id ,页面转换后的 content (也就是那段 Markdown 文本),以及包含来源页码和文件名的 metadata

最后,它把所有 PDF 的所有页面对应的 chunk 合并到一个大的列表里,并存成 all_pdf_page_chunks.json 文件。

这个文件就是我们整个流程的最终产物,可以直接拿去给 Embedding 模型做向量化,然后构建我们的向量数据库了。

进阶要点2:“粗召回”与“精召回”的检索策略

我们可以采用一个两步走的检索策略,也就是先“召回”再“重排”。

  • 第一步“召回”,用向量检索或者关键词检索(比如BM25算法),快速地找到一个比较大的候选范围,目的是把相关的都找出来。

  • 第二步“重排”,用一个更精准的重排模型,比如 FlagEmbedding 仓库里的 BGE-ReRanker 模型,来给这些候选项和问题的相关性打分,然后选出分数最高的几个。

3.其他进阶方法和思路

进阶思路1:多路召回与融合

比如,我们可以并行运行两种检索:一种是基于关键词的检索,像 BM25 算法,它擅长匹配问题中出现的具体词语;另一种是基于向量的语义检索,使用 embedding 模型来查找意思相近但用词可能不同的内容。这样,两条通路可以形成优势互补。

在从不同通路拿到各自的召回结果列表后,接下来的问题就是如何把它们融合成一个更高质量的排序。

这里通常有两种处理思路:

  • 第一种是使用重排模型(Re-ranker)

    我们可以把所有通路召回的结果汇总到一起,然后用一个重排模型,比如基于 FlagEmbedding 的模型,来对这个大集合进行统一的、更精细的相关性打分,最后选出分数最高的几个结果。

  • 第二种是使用无需训练模型的融合算法

    一个常见的例子是倒数排名融合(Reciprocal Rank Fusion, RRF)。

    这种方法会根据每个文档在不同召回列表中的排名位置,来计算出一个综合分数,然后根据这个综合分数生成一个新的排序。

进阶思路2:构建知识图谱

什么是知识图谱?

知识图谱(Knowledge Graph)是一种结构化的知识表示形式,用于存储和组织复杂的关系数据。它以图的形式表示实体(Entity)、属性(Attribute)和它们之间的关系(Relation),通常以节点(表示实体)和边(表示关系)的形式构建。知识图谱的目标是将分散的知识整合成一个结构化的网络,便于机器理解、推理和查询。

还有一个方向是构建知识图谱。现在我们的知识库里的知识块是相互独立的,但原文中它们是有结构联系的。

我们可以把一份文档表示成一个知识图谱,里面的节点可以是段落、表格、图表、公司名等实体,边则表示它们之间的关系,比如“位于”、“描述”或者“属于”。

进阶思路3:让RAG系统拥有自我修正的能力

具体来说,就是让系统在检索一次之后,能自己判断一下找到的上下文够不够回答问题。

如果不够,它可以自己生成一个新的、更具体的查询语句,再次进行检索,把两次的结果合在一起再生成答案。

进阶思路4:模型微调

整个微调流程可以分为两大步: 数据准备模型训练 。主要涉及到 spark_data_process.ipynbspark_model_finetune.ipynb 两个文件。

4.1数据准备 (spark_data_process.ipynb)

我们的目标是利用官方提供的 train.json ,将其转换为模型能够理解的“指令-输入-输出”格式。

核心目标 :将原始的问答数据,转换为符合Alpaca指令格式的 qa_train.json 文件。

什么是Alpaca

Alpaca 数据集通常以 JSON 格式存储,每个样本包含以下三个字段:

  1. instruction:用户提供的指令或问题,描述任务或需要模型完成的工作。
  2. input:(可选)额外的上下文或输入信息,为指令提供更多背景。如果没有额外上下文,这个字段可以为空。
  3. output:模型应该生成的回答或结果。

spark_data_process.ipynb 的核心逻辑是将每个问答对(Q&A pair)包装成一个结构化的字典。

  • 输入与输出input 字段对应原始问题,output 字段对应标准答案。模型在训练时会学习到,在收到这样的 instructioninput 后,应该生成类似 output 的回答。

  • 最终产物 :执行该脚本后,我们会得到 qa_train.json 文件,这是下一步模型训练的直接输入。

我们通过提供一个固定的 instruction (指令),作为学习材料,通过微调教会模型在我们这个财报任务下的“角色”和“任务”。

这使得模型在面对新的问题时,能更好地按照我们期望的身份和方式来回答。

4.2 模型训练 (spark_model_finetune.ipynb)

有了标准格式的训练数据,我们就可以开始进行模型的有监督微调(Supervised Fine-Tuning, SFT)。

我们在参考代码中使用了 unsloth 框架高效微调 Qwen2.5-7B

1. 环境配置与模型加载

首先,我们加载必要的库和预训练模型。 unsloth 框架通过优化,可以显著降低显存占用并提升训练速度。

2. 添加LoRA适配器

我们不训练模型的全部参数,而是采用LoRA(Low-Rank Adaptation)技术,只插入并训练少量“适配器”参数。这极大地节约了计算资源。

LoRA(Low-Rank Adaptation)是一种高效的微调(Fine-tuning)技术,用于在不大幅修改预训练模型的情况下,适应特定任务或领域。它通过在模型的权重矩阵中引入低秩更新(low-rank updates),大幅减少需要训练的参数量,从而降低计算成本和内存需求,同时保持模型性能。LoRA 最初由微软研究院提出,广泛应用于大语言模型(如 LLaMA、BERT)和视觉模型的微调。

3. 加载并格式化数据

加载上一步生成的 qa_train.json ,并将其转换为训练所需的最终文本格式。

4. 配置并启动训练

使用HuggingFace的 trl 库中的 SFTTrainer 来配置训练参数并启动训练。

5. 推理验证与模型保存

训练完成后,我们可以立即进行一个简单的推理测试,看看模型是否学会了按照我们的要求回答问题。最后,将训练好的LoRA适配器保存下来,以便后续在RAG系统中使用。

通过以上步骤,我们就完成了一次完整的模型微调。得到的 lora_model 文件夹包含了微调后的模型权重,可以在RAG的生成环节加载它。

通过系统的模型微调,我们可以显著提升RAG系统在财报问答任务上的表现。

http://www.lryc.cn/news/619772.html

相关文章:

  • 算法详细讲解 - 离散化/区间合并
  • 【慕伏白】Kali 系统下安装 docker
  • 弹性扩展新范式:分布式LLM计算的FastMCP解决方案
  • Python(二):MacBook安装 Python并运行第一个 Python 程序
  • 【QT】QT实现鼠标左右滑动切换图片
  • MySQL中的缓存机制
  • 如何在VS里使用MySQL提供的mysql Connector/C++的debug版本
  • 如何把ubuntu 22.04下安装的mysql 8 的 数据目录迁移到另一个磁盘目录
  • 设计模式笔记_行为型_策略模式
  • OpenJDK 17 源码 安全点轮询的信号处理流程
  • 资源查看-lspci命令
  • 如何准备一场技术演讲
  • 各种排序算法(二)
  • 磁悬浮轴承转子设计避坑指南:深度解析核心要点与高可靠性策略
  • 基于js和html的点名应用
  • 【电气】NPN与PNP
  • B系列树详细讲解
  • 16-docker的容器监控方案-prometheus实战篇
  • Python 类元编程(导入时和运行时比较)
  • Windows也能用!Claude Code硬核指南
  • [激光原理与应用-259]:理论 - 几何光学 - 平面镜的反射、平面透镜的折射、平面镜的反射成像、平面透镜的成像的规律
  • 网刻软件iVentoy软件使用方法
  • @进程管理工具 - Glances工具详细指南
  • Django REST Framework视图
  • Java 大视界 -- Java 大数据机器学习模型在金融资产配置优化与风险收益平衡中的应用(395)
  • 解惑rust中的 Send/Sync(译)
  • 基于Java的Markdown转Word工具(标题、段落、表格、Echarts图等)
  • 18.10 SQuAD数据集实战:5步高效获取与预处理,BERT微调避坑指南
  • 实战多屏Wallpaper壁纸显示及出现黑屏问题bug分析-学员作业
  • HTML <iframe> 标签 如何把html写入iframe标签