• 📖 简介 • 🎉 最新动态 • ✨ VisRAG 流程 • ⚙️ 环境配置 • ⚡️ 训练
• 📃 评估 • 🔧 使用 • 📄 许可证 • 📧 联系我们 • 📈 Star 历史
EVisRAG (VisRAG 2.0) 是一个证据引导的视觉检索增强生成框架,旨在让视觉语言模型(VLM)能够处理多图像问题。其方法是先对检索到的图像进行语言层面的观察,收集每张图像的证据,然后基于这些线索进行推理以得出答案。EVisRAG 采用奖励范围分组相对策略优化(Reward-Scoped GRPO)进行训练,应用细粒度的令牌级奖励来联合优化视觉感知和推理能力。

VisRAG 是一个基于视觉语言模型(VLM)的新型 RAG 流程。在此流程中,文档无需先解析为文本,而是直接使用 VLM 将其作为图像进行嵌入,然后检索出来以增强 VLM 的生成。与传统的基于文本的 RAG 相比,VisRAG 最大限度地保留和利用了原始文档中的数据信息,消除了解析过程中引入的信息损失。

visrag_scripts/file2img 中找到。EVisRAG 是一个端到端框架,旨在让 VLM 在多图像场景的推理过程中具备精确的视觉感知能力。我们基于 Qwen2.5-VL-7B-Instruct 和 Qwen2.5-VL-3B-Instruct 训练并发布了内置 EVisRAG 的 VLRM。
VisRAG-Ret 是一个基于 MiniCPM-V 2.0 构建的文档嵌入模型,该视觉语言模型集成了 SigLIP 作为视觉编码器和 MiniCPM-2B 作为语言模型。
在论文中,我们使用 MiniCPM-V 2.0、MiniCPM-V 2.6 和 GPT-4o 作为生成器。实际上,你可以使用任何你喜欢的 VLM!
git clone https://github.com/OpenBMB/VisRAG.git
conda create --name EVisRAG python==3.10
conda activate EVisRAG
cd EVisRAG
pip install -r EVisRAG_requirements.txt
git clone https://github.com/OpenBMB/VisRAG.git
conda create --name VisRAG python==3.10.8
conda activate VisRAG
conda install nvidia/label/cuda-11.8.0::cuda-toolkit
cd VisRAG
pip install -r requirements.txt
pip install -e .
cd timm_modified
pip install -e .
cd ..
注意:
1. timm_modified 是 timm 库的增强版本,支持梯度检查点,我们在训练过程中使用它来减少内存占用。
为了有效训练 EVisRAG,我们引入了奖励范围分组相对策略优化(RS-GRPO),它将细粒度奖励绑定到特定范围的令牌上,以联合优化 VLM 的视觉感知和推理能力。

第一阶段:监督微调 (SFT) (基于 LLaMA-Factory)
git clone https://github.com/hiyouga/LLaMA-Factory.git
bash evisrag_scripts/full_sft.sh
第二阶段:RS-GRPO (基于 Easy-R1)
bash evisrag_scripts/run_rsgrpo.sh
注意事项:
EVisRAG-Train 中找到,本页开头已提供引用。LLaMA-Factory 并在 full_sft.sh 脚本中更新模型路径。第二阶段,我们基于 Easy-R1 构建了为 EVisRAG 定制的算法 RS-GRPO,其实现可在 src/RS-GRPO 中找到。我们用于训练 VisRAG-Ret 的数据集包含 362,110 个查询-文档(Q-D)对,由公开学术数据集的训练集(34%)和一个合成数据集(66%)组成。合成数据集由网络爬取的 PDF 文档页面构成,并使用 VLM(GPT-4o)生成的伪查询进行增强。
bash visrag_scripts/train_retriever/train.sh 2048 16 8 0.02 1 true false config/deepspeed.json 1e-5 false wmean causal 1 true 2 false <model_dir> <repo_name_or_path>
注意:
1. 我们的训练数据可在 Hugging Face 的 VisRAG 集合中找到,本页开头已提供引用。请注意,由于 In-domain-data 和 Synthetic-data 存在显著差异,我们已将其分开。如果你想使用完整数据集进行训练,需要手动合并并打乱它们。
2. 上面列出的参数是我们在论文中使用的,可用于复现结果。
3. <repo_name_or_path> 可以是以下任意一个:openbmb/VisRAG-Ret-Train-In-domain-data、openbmb/VisRAG-Ret-Train-Synthetic-data、从 Hugging Face 下载的仓库目录路径,或包含你自己训练数据的目录。
4. 如果你想使用自己的数据集进行训练,请从 train.sh 脚本中移除 --from_hf_repo 行。此外,确保你的数据集目录包含一个 metadata.json 文件,该文件必须包含一个 length 字段,用于指定数据集中的样本总数。
5. 我们的训练框架基于 OpenMatch 修改。
生成部分不使用任何微调,我们直接使用现成的 LLM/VLM 进行生成。
bash evisrag_scripts/predict.sh
bash evisrag_scripts/eval.sh
注意事项:
EVisRAG-Test-xxx 中找到,本页开头已提供引用。predict.sh 脚本。模型输出将保存在 preds 目录中。然后,使用 eval.sh 脚本评估预测结果。指标 EM、Accuracy 和 F1 将直接报告。bash visrag_scripts/eval_retriever/eval.sh 512 2048 16 8 wmean causal ArxivQA,ChartQA,MP-DocVQA,InfoVQA,PlotQA,SlideVQA <ckpt_path>
注意:
1. 我们的测试数据可在 Hugging Face 的 VisRAG 集合中找到,本页开头已提供引用。
2. 上面列出的参数是我们在论文中使用的,可用于复现结果。
3. 评估脚本默认配置为使用来自 Hugging Face 的数据集。如果你希望使用本地下载的数据集仓库进行评估,可以修改评估脚本中的 CORPUS_PATH、QUERY_PATH、QRELS_PATH 变量,使其指向本地仓库目录。
在我们的生成中有三种设置:基于文本的生成、基于单图像 VLM 的生成和基于多图像 VLM 的生成。在基于单图像 VLM 的生成下,还有两种附加设置:页面拼接和加权选择。有关这些设置的详细信息,请参阅我们的论文。
python visrag_scripts/generate/generate.py \
--model_name <model_name> \
--model_name_or_path <model_path> \
--dataset_name <dataset_name> \
--dataset_name_or_path <dataset_path> \
--rank <process_rank> \
--world_size <world_size> \
--topk <number of docs retrieved for generation> \
--results_root_dir <retrieval_results_dir> \
--task_type <task_type> \
--concatenate_type <image_concatenate_type> \
--output_dir <output_dir>
注意:
1. use_positive_sample 决定是否仅使用查询的正样本文档。启用此选项将排除检索到的文档,并省略 topk 和 results_root_dir。如果禁用,则必须指定 topk(检索文档数量)并按 results_root_dir/dataset_name/*.trec 的方式组织 results_root_dir。
2. concatenate_type 仅在 task_type 设置为 page_concatenation 时需要。如果不需要,请省略此参数。
3. 始终指定 model_name_or_path、dataset_name_or_path 和 output_dir。
4. 仅在需要基于 GPT 的评估时才使用 --openai_api_key。
Hugging Face 上的模型:https://huggingface.co/openbmb/EVisRAG-7B
```python
from transformers import AutoProcessor
from vllm import LLM, SamplingParams
from qwen_vl_utils import process_vision_info
def evidence_promot_grpo(query):
return f"""你是一个 AI 视觉问答助手。我将为你提供一个问题和几张图片。请遵循以下四个步骤:
步骤 1:观察图片
首先,分析问题并思考哪些类型的图片可能包含相关信息。然后,逐一检查每张图片,特别关注与问题相关的方面。判断每张图片是否包含任何潜在的相关信息。
将你的观察结果包裹在 标签内。
步骤 2:记录图片中的证据
检查完所有图片后,在 标签内记录你为每张图片找到的证据。
如果你确定某张图片不包含相关信息,请记录为:[i]: 无相关信息(其中 i 表示图片的索引)。
如果某张图片包含相关证据,请记录为:[j]: [你为问题找到的证据](其中 j 是图片的索引)。
步骤 3:基于问题和证据进行推理
根据记录的证据,推理问题的答案。
将你的逐步推理过程包含在 标签内。
步骤 4:回答问题
仅基于你在图片中找到的证据提供最终答案。
将你的答案包裹在 标签内。
避免在最终答案中添加不必要的内容,例如,如果问题是是非题,只需回答“是”或“否”。
如果没有任何图片包含足够的信息来回答问题,请回复 信息不足,无法回答。
格式要求:
使用确切的标签 、、 和 进行结构化输出。
可能没有、有一张或多张图片包含相关证据。
如果你没有找到证据或证据很少,不足以帮助你回答问题,请遵循上述关于信息不足的指示。
问题和图片如下所示。请按照指示的步骤操作。
问题:{query}
"""
model_path = "xxx"
processor = AutoProcessor.from_pretrained(model_path, trust_remote_code=True, padding_side='left')
imgs, query = ["imgpath1", "imgpath2", ..., "imgpathX"], "What xxx?"
input_prompt = evidence_promot_grpo(query)
content = [{"type": "text", "text": input_prompt}]
for imgP in imgs:
content.append({
"type": "image",
"image": imgP
})
msg = [{
"role": "user",
"content": content,
}]
llm = LLM(