多模态RAG:结合ColPali、Llava和Qwen2-VL

2024年09月25日 由 alex 发表 63 0

简介

在标准 RAG 中,输入文档由文本数据组成。LLM 利用上下文内学习的优势,通过检索与所问查询的上下文相匹配的文本文档块来提供更相关、更准确的答案。


如果文档中除了文本数据还包含图片、表格、图表等,该怎么办呢?


不同的文档格式

  • PDF(便携式文档格式): 常用于跨平台共享保留格式的文档,但由于其非结构化布局,很难从中提取数据。
  • Microsoft Word 文档(.doc、.docx): 灵活且使用广泛,但可能包含表格、图像、页眉和页脚,因此提取数据具有挑战性。
  • Excel 电子表格(.xls、.xlsx): Excel 文件的结构性更强,但可能包含复杂的多表数据、合并单元格和公式。
  • 扫描图像(.jpg、.png、.tiff): 扫描文件增加了另一层复杂性,因为它们需要光学字符识别 (OCR) 功能,在提取数据前首先将图像转换为文本。
  • HTML 和纯文本文件: 虽然提取起来比较简单,但这些格式中可能存在的布局多样性使得提取工作并非易事。


每种格式都有自己的结构和难题,但真正的困难来自于这些格式中的各种变化。例如,PDF 可以是单栏或多栏,可以包含表格或图表,可以有页眉、页脚、图像或图表。这种广泛的可能性使得创建一个通用的解决方案变得不切实际。


处理此类文档的主要挑战:

  • 格式多变: 不同的格式具有不同的特征,使数据提取变得复杂。例如,PDF 文件可能包含图像或表格,而扫描文件可能质量不佳或存在手写痕迹。
  • 数据完整性: 确保提取数据的准确性和完整性至关重要。不准确的数据会导致决策失误和运行效率低下。
  • 数量管理: 文件量的不断增加会使传统的提取方法不堪重负,因此需要先进的解决方案来有效处理大型数据集。


标准的 LLM 会忽略这些附加信息。在这里,RAG 系统必须依靠 OCR 工具从表格、图像等中提取信息。虽然近年来 OCR 技术有了很大的进步,并被普遍用于从扫描图像中提取文本。然而,它仍然会产生错误,尤其是在扫描质量较差的情况下,而且在处理复杂布局(如多列 PDF 或包含文本和图像的混合文档)时也很吃力。这将导致不相关或信息错误的文本块被索引,当检索这些文本块并将其添加到 LLM 的上下文中时,会对 LLM 合成答案的质量产生负面影响。


随着大型语言模型及其理解文本和图像能力的快速发展,我们可以利用它们的能力从图像、图表中推断信息。


在这里,我们将使用多模态 LLM ColPali 从复杂的 PDF 文档中推断信息。


什么是 ColPali?

ColPali 是一种基于视觉语言模型(VLMs)的新颖模型架构和训练策略,可有效地从视觉特征中为文档编制索引。它是 PaliGemma-3B 的扩展,可生成 ColBERT 风格的文本和图像多向量表示。


在 RAG 系统中,它被用作视觉检索器。


15


ColPali 的一项关键创新是将图像补丁映射到与文本相似的潜在空间中,并利用 COLBERT 策略实现文本与图像之间的高效交互。


ColPali 基于两个观察结果:

  • 多向量表示法和后期交互评分可提高检索性能。
  • 视觉语言模型在理解视觉内容方面表现出了非凡的能力。


ColPali 用于将多模态文档转换为图像表示法,然后计算其多向量表示法,并将其存储为索引。VLM 可以进一步利用它来回答问题。


什么是 COLBERT?

ColBERT是Contextualized Late Interaction over BERT的缩写,是一种为高效信息检索而设计的创新模型。


ColBERT 的主要特点:

  • 标记级表示: 与将标记表示压缩成单一向量的传统模型不同,ColBERT 为每个标记保留了单独的嵌入。这使得查询术语和文档术语之间的相似性计算更加细致入微。
  • 后期交互机制 ColBERT 采用后期交互策略,在检索的最后阶段才分别处理查询和文档。这种机制可以进行详细的比较,而无需在前期进行详尽的计算,从而提高了效率。
  • 提高检索性能: ColBERT 在各种基准测试中表现出卓越的性能,在某些任务中甚至超过了大型模型。它的设计使其能够有效处理复杂的查询和文档结构。
  • 版本:ColBERTv2 继承了最初的 ColBERT 模型,并加入了去噪监督和残差压缩等增强功能,进一步提高了其在检索任务中的有效性和效率。


ColBERT 特别适用于对搜索任务的精确度要求较高的应用,是自然语言处理和信息检索等领域的重要工具。


16


早期交互会增加计算复杂度,因为它需要考虑所有可能的查询-文档配对,从而降低了大规模应用的效率。


ColBERT 等后期交互模型允许预先计算文档表示法,并在最后采用更轻量级的交互步骤,将重点放在已编码的表示法上,从而优化了效率和可扩展性。这种设计选择可以加快检索速度,降低计算需求,使其更适合处理大型文档集。


什么是视觉语言模型?

视觉语言模型(VLM)是一种先进的人工智能系统,它集成了视觉信息和文本信息,能够执行各种需要根据图像理解和生成文本的任务。下面将概述它们的主要特点和应用:


定义和功能

  • 多模态学习: VLM 同时从图像和相应的文本描述中学习。这样,它们就能将视觉特征与语言表达联系起来,从而增强了在两种模式下理解上下文和语义的能力。
  • 生成能力: 这些模型可以根据图像输入生成文本输出,因此在图像字幕等任务中非常有用,它们可以为给定的图像创建描述性文本。


主要功能

  • 图像和文本编码: VLM 通常由独立的图像和文本编码器组成。它们融合来自这些编码器的信息,以实现对输入数据的全面理解。
  • 零点学习: 许多 VLM 都具有很强的零点学习能力,这意味着它们可以很好地泛化到新任务中,而无需额外的训练数据。
  • 空间意识: 一些模型可以捕捉图像中的空间关系,从而在识别图像中的特定对象或区域时输出边界框或分割掩码。


17


多模态 RAG 实现步骤:

  1. 使用 ColPali 对所需的输入文档进行编码,然后将生成的嵌入结果编入索引并存储在 VectorStore 中。
  2. 然后使用 ColPali 对用户查询进行编码,并使用由此产生的嵌入从 VectorStore 中检索可能包含文本和图像的类似文档块。
  3. 然后,RAG 系统将检索到的文档块作为输入,用用户查询来增强上下文,以方便 VLM 响应用户查询。


有几种矢量数据库支持多矢量架构或 ColBERT 风格的表示法,可以高效地索引和检索高维矢量数据。下面是一些值得注意的选择:

  1. Vespa: Vespa 引入了多向量支持,允许为每个文档建立多个向量索引。这一功能可根据每个向量中最接近的向量检索文档,使其适用于复杂的数据表示和语义搜索应用。
  2. Pinecone:Pinecone 专为管理向量嵌入而设计,支持高级查询功能,包括处理多个向量表示。它针对人工智能应用进行了优化,因此非常适合需要细致入微的数据表示的任务。
  3. Qdrant:Qdrant 是一种专门的向量数据库,可高效地索引和检索高维向量数据。虽然它主要侧重于单矢量嵌入,但也适用于各种架构,包括可能需要多矢量设置的架构。


所需技术栈

  1. 运行 Qwen2-VL-7b-Instruct VLM 的 Transformers 库。
  2. 如果我们想在消费级 GPU(24 GB VRAM)上运行 VLM (Qwen2-VL),则需要 Flash Attention。
  3. Byaldi 是 ColPali Repository 的封装器,可让 RAG 更轻松地使用 ColPali
  4. qwen_vl_utils 用于促进 Qwen-VL 的输入处理。
  5. pdf2image 用于将 PDF 页面转换为图像。这是必要的,因为 Qwen2-VL 无法对 PDF 文件进行编码。
  6. popller-utils 是 byaldi 索引 PDF 页面所必需的。
  7. Groq 将 Llava 模型用作 VLM 并检查响应质量


代码实现

  • 谷歌实验室 Nvidia A100
  • 安装所需的依赖项


!pip install -qU byaldi
!pip install -qU accelerate
!pip install -qU flash_attn
!pip install -qU qwen_vl_utils
!pip install -qU pdf2image
!pip install -qU groq
!python -m pip install git+https://github.com/huggingface/transformers


!sudo apt-get update
!apt-get install poppler-utils


  • 下载数据


!mkdir Data
!wget https://arxiv.org/pdf/2409.06697 -O Data/input.pdf


  • 导入所需依赖项


from byaldi import RAGMultiModalModel
from transformers import Qwen2VLForConditionalGeneration, AutoTokenizer, AutoProcessor
from qwen_vl_utils import process_vision_info
import torch
from pdf2image import convert_from_path
import groq


  • 用 RAGMultiModal 从 byaldi 加载 ColPali


RAG = RAGMultiModalModel.from_pretrained("vidore/colpali")


  • 加载视觉模型


model = Qwen2VLForConditionalGeneration.from_pretrained("Qwen/Qwen2-VL-7B-Instruct", 
                                                        torch_dtype=torch.bfloat16,
                                                        attn_implementation="flash_attention_2",
                                                        device_map="cuda")


  • 用 byaldi 索引 PDF 文件


RAG.index(input_path="Data/input.pdf",
          index_name="multimodal_rag",
          store_collection_with_index=False,
          overwrite=True,)


  • 根据用户查询从 Vectorstore 提取上下文


text_query = "What is the type of star hosting thge kepler-51 planetary system?"
results = RAG.search(text_query,k=3)
results
###### RESPOSNE #####
[{'doc_id': 1, 'page_num': 1, 'score': 25.125, 'metadata': {}, 'base64': None},
 {'doc_id': 1, 'page_num': 8, 'score': 24.875, 'metadata': {}, 'base64': None},
 {'doc_id': 1, 'page_num': 9, 'score': 24.125, 'metadata': {}, 'base64': None}]


  • 转换为实际图像数据


images = convert_from_path("Data/input.pdf")
image_index = results[0]["page_num"] -1


  • 显示所选文件图像


from IPython.display import Image,display
display(images[image_index])


18


from IPython.display import Image,display
display(images[1])


19


  • 保存图像


from PIL import Image
# Assuming 'img' is your image object
images[image_index].save('image1.jpg')


  • 设置 Groq Api 密钥


from google.colab import userdata
import os
os.environ["GROQ_API_KEY"] = userdata.get("GROQ_API_KEY")


  • 使用 GROQ 合成响应 - llava-v1.5-7b-4096-preview 模型


LLaVA V1.5 7B(预览版)-GROQ

  • 模型 ID:llava-v1.5-7b-4096-preview
  • 说明: LLaVA(大型语言和应用程序)是一种基于语言的应用程序: LLaVA(Large Language-and-Vision Assistant,大型语言与视觉助手)是一个开源的、经过微调的多模态模型,可生成图像的文本描述,在多模态指令跟随任务中表现出色,在某些基准测试中优于 GPT-4。
  • 上下文窗口 4,096 个标记


限制

  • 预览模型: Llava V1.5 7B 目前处于预览阶段,仅供实验使用。
  • 图片大小限制:输入图片 URL 请求的最大允许大小为 20MB。
  • 超过此限制的请求将返回 400 错误。
  • 请求大小限制(Base64 编码图像): 包含 base64 编码图像的请求允许的最大大小为 4MB。超过此限制的请求将返回 413 错误。
  • 每个请求只能处理一张图片: 每个请求只能处理一张图片。包含多个图像的请求将返回 400 错误。
  • 每个请求一条用户信息: 目前不支持多轮对话,每个请求只允许一条用户信息。多个用户信息的请求将返回 400 错误。
  • 无系统提示或助理信息: 目前不支持系统信息和助手信息。包含系统或助手信息的请求将返回 400 错误。
  • 无工具使用:目前不支持工具使用。包含工具使用或函数调用的请求将返回 400 错误。
  • 无 JSON 模式: 当前不支持 JSON 模式。启用 JSON 模式的请求将返回 400 错误。


from groq import Groq
import base64

# Function to encode the image
def encode_image(image_path):
  with open(image_path, "rb") as image_file:
    return base64.b64encode(image_file.read()).decode('utf-8')
# Path to your image
image_path = "/content/image1.jpg"
# Getting the base64 string
base64_image = encode_image(image_path)
client = Groq()
chat_completion = client.chat.completions.create(
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": text_query},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f_"data:image/jpeg;base64,{base64_image}",
                    },
                },
            ],
        }
    ],
    model="llava-v1.5-7b-4096-preview",
)
print(chat_completion.choices[0].message.content)
## Response ##
The type of star hosting the Kepler-51 planetary system is a F-type main-sequence star, known as Fp Lacertae. This star is located at roughly 3,090 light-years from Earth. Fp Lacertae is considered a B-type dwarf star, meaning it emits a relatively larger amount of intense light, and the planet Kepler 51i is seen orbitsing the star.


  • 使用 QWEN2-VL-7B-INSTRUCT 视觉语言模型进行响应合成


messages = [
    {"role":"user",
     "content":[{"type":"image",
                 "image":images[image_index]
                 },
                {"type":"text","text":text_query}
              ]
    }
            ]
#
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
#
image_inputs,video_inputs = process_vision_info(messages)
#
inputs = processor(text=[text],
                   images=image_inputs,
                   videos=video_inputs,
                   padding=True,
                   return_tensors="pt")
inputs = inputs.to("cuda")
#
generate_ids = model.generate(**inputs, 
                              max_new_tokens=256)
#
generated_ids_trimmed = [out_ids[len(in_ids):] for in_ids, out_ids in zip(inputs.input_ids, generate_ids)]
#
output_text = processor.batch_decode(generated_ids_trimmed, 
                                     skip_special_tokens=True,
                                     clean_up_tokenization_spaces=False)
#
print(output_text[0])
#### RESPONSE ####
'The host star of the Kepler-51 planetary system is a G-type star.'


在这里,我们看到 Qwen2-VL 提供了更准确、更好的结果。


  • 再问一个问题


text_query  = "What is the age of the star hosting the kepler-51 planetary system?"
#
messages = [
    {"role":"user",
     "content":[{"type":"image",
                 "image":images[image_index]
                 },
                {"type":"text","text":text_query}
              ]
    }
            ]
#
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
#
image_inputs,video_inputs = process_vision_info(messages)
#
inputs = processor(text=[text],
                   images=image_inputs,
                   videos=video_inputs,
                   padding=True,
                   return_tensors="pt")
inputs = inputs.to("cuda")
#
generate_ids = model.generate(**inputs, 
                              max_new_tokens=256)
#
generated_ids_trimmed = [out_ids[len(in_ids):] for in_ids, out_ids in zip(inputs.input_ids, generate_ids)]
#
output_text = processor.batch_decode(generated_ids_trimmed, 
                                     skip_special_tokens=True,
                                     clean_up_tokenization_spaces=False)
#
print(output_text[0])
#
################  RESPONSE ##################################
The host star is a G-type star of age ~500 Myr.


结论

ColPali 是多模式文档检索领域的一大进步,它将 VLM 的优势与创新的架构选择相结合。它能够高效地处理和检索复杂文档中的信息,在不断发展的人工智能驱动的数据分析和检索系统中,它被定位为一种有价值的工具。



文章来源:https://medium.com/the-ai-forum/implement-multimodal-rag-with-colpali-and-vision-language-model-groq-llava-and-qwen2-vl-5c113b8c08fd
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消