【Datawhale夏令营】多模态RAG学习
目的
打造一个能看懂图片、读懂文字、并将两者关联起来思考的AI助手,构建一个先进的智能问答系统,以应对真实世界中复杂的、图文混排的信息环境。
- 让 AI模型能够阅读并理解包含大量图标、图像和文字的pdf文档 ,基于信息回答用户问题。
- 能找到答案的同时还需要标注出答案的出处,比如源自于哪一个文件的哪一页。
技术点
多模态检索增强生成 (Multimodal RAG),其中需要涉及到:
-
多模态信息处理 (Multimodal Information Processing)
-
向量化与检索技术 (Embeddings & Retrieval)
-
跨模态检索与关联 (Cross-Modal Retrieval)
-
大语言模型(LLM)的应用与推理 (LLM Application & Reasoning)
Baseline文件结构
-
fitz_pipeline_all, 数据处理脚本,自动完成PDF解析、内容结构化、分块合并
- process_pdfs_to_chunks函数, 使用PyMuPDF提取文本,生成JSON文件。
-
rag_from_page_chunks.py, RAG检索与问答脚本,支持向量检索与大模型生成式问答
- PageChunkLoader, 加载块数据
- EmbeddingModel,文本批量转换为向量
- SimpleVectorStore,一个简单的内存向量数据库
- SimpleRAG,RAG系统的初始化
-
get_text_embedding.py, 文本向量化,支持批量处理
- batch_get_embeddings 批量获取文本的嵌入向量函数
- get_text_embedding,获取文本的嵌入向量函数
-
extract_json_array.py, 从大模型输出中提取JSON结构,保证结果可解析
-
all_pdf_page_chunks.json 所有PDF分页内容合并结果,供RAG检索
-
.env 环境变量配置,存放API密钥、模型等参数
-
caches/ 预留目录
-
datas/ 原始PDF文件及测试集存放目录
-
data_base_json_content/ PDF解析后的内容列表(中间结果)
-
output/ 其他输出文件目录
Baseline方案思路
- 离线预处理(构建知识库)
- 文档解析(Parse)
- 知识库构建(Index)
- 在线推理(生成答案)
- 问题向量化(Query)
- 信息检索(Retrieve)
- 答案生成(Generate)
Baseline调整上分
-
分块策略
- 目前按“页”分块,简单粗糙。
-
检索优化
- 当前策略:Top-K检索策略,简单可用
-
Prompt工程: rag_from_page_chunks.py
- Prompt是整个生成环节的灵魂。
- 提升:设计更好的Prompt提示词,是的生成更加精确
-
多模态融合
- 当前是“图片”转为“文字描述”,信息有损失。
-
升级解析方案
- 当前解析是fitz
- 提升: 升级为MinerU
Baseline提分优化
1、提示词优化, rag_from_page_chunks.py
, 效果不明显:0.00346 -> 0.00369
# 压缩TOKEN、强化“命中率”,将「评分标准」写入提示词
prompt = ("任务:在三步内生成 40 字以内答案并精确定位。\n""步骤 1:在「检索内容」中找出与「问题」语义最贴合的 1 句话,标星*。\n""步骤 2:提取该句所在文件名与页码;无页码填 0。\n""步骤 3:用该句直接回答,禁止推理、禁止换行。\n""输出格式:{\"answer\":\"步骤3结果\",\"filename\":\"步骤2文件名\",\"page\":步骤2页码}\n\n"f"检索内容:\n{context}\n\n"f"问题:{question}\n"
)
2、输出格式优化,根据提交文件submit.json
示例。在rag_from_page_chunks.py
生成修改输出标准的提交格式, 将answer, filename, page
输出补全。评分变化:0.00369 -> 0.16001
# 只保留结果部分,并去除 retrieval_chunks 字段
idx2result = {idx: {k: v for k, v in r.items() if k != 'retrieval_chunks'} for idx, r in results}
filtered_results = []
for idx, item in enumerate(test_data):if idx in idx2result:filtered_results.append(idx2result[idx])elif FILL_UNANSWERED:# 未被回答的,补默认内容filtered_results.append({"question": item.get("question", ""),"answer": item.get("answer", ""),"filename": item.get("filename", ""),"page": item.get("page", ""),})
3、修改temparature参数: 0.2 -> 0.5。评分变化:0.16001->0.1611
completion = client.chat.completions.create(model=qwen_model,messages=[{"role": "system", "content": "你是一名专业的金融分析助手。"},{"role": "user", "content": prompt}],temperature=0.5,max_tokens=1024
)
参考
源码:AISumerCamp_multiModal_RAG