使用 ColPali 和视觉语言模型 Groq(Llava) 和 Qwen2-VL 实现多模态 RAG

多模态 RAG 管道

介绍

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

但是如果文档除了文本数据之外还包含图像、表格、图表等怎么办?

不同的文档格式

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

每种格式都有自己的结构和挑战,但真正的困难来自于这些格式之间的差异。例如,PDF 可以是单列或多列,可能包含表格或图表,并且可以包含页眉、页脚、图像或图表。由于可能性范围如此广泛,因此创建通用解决方案并不切实际。

处理此类文件的关键挑战:

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

标准 LLM 会忽略这些附加信息。此时,RAG 系统必须依赖 OCR 工具从表格、图像等中提取信息。但对于具有复杂格式、表格或图像的文档,OCR 准确度通常较低。尽管 OCR 技术近年来有了显着改进,并且通常用于从扫描图像中提取文本。但是,它仍然会产生错误,尤其是在扫描质量较差的情况下,并且难以处理复杂的布局,例如多列 PDF 或包含文本和图像混合的文档。这将导致不相关或误导性的文本块被编入索引,当检索和扩充到 LLM 上下文中时,可能会对 LLM 合成的答案的质量产生负面影响。

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

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

什么是 ColPali?

ColPali 是一种基于视觉语言模型 (VLM) 的新型模型架构和训练策略的模型,可有效地根据文档的视觉特征对其进行索引。它是PaliGemma-3B 的扩展,可生成文本和图像的ColBERT风格的多向量表示。它在论文《ColPali:使用视觉语言模型进行高效文档检索》中进行了介绍

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

来自源头

ColPali 的一个关键创新是将图像块映射到与文本类似的潜在空间。它使用 COLBERT 策略实现文本和图像之间的有效交互。

ColPali 基于两点观察:

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

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

什么是 COLBERT?

ColBERT 是 BERT 上的语境化后期交互的缩写,是一种为高效信息检索而设计的创新模型。该模型在论文“ColBERT :通过 BERT 上的语境化后期交互实现高效且有效的段落搜索”中进行了介绍

ColBERT 的主要特点:

  • 标记级表示:与将标记表示压缩为单个向量的传统模型不同,ColBERT 为每个标记保留单独的嵌入。这允许在查询词和文档词之间进行更细致的相似度计算。
  • 后期交互机制: ColBERT 采用后期交互策略,查询和文档在检索的最后阶段之前分开处理。此机制允许进行详细比较,而无需事先进行详尽的计算,从而提高了效率。
  • 改进的检索性能: ColBERT 在各种基准测试中都表现出色,甚至在某些任务中超越了更大的模型。其设计使其能够有效地处理复杂的查询和文档结构。
  • 版本:原始 ColBERT 模型已被ColBERTv2 所取代,它结合了去噪监督和残差压缩等增强功能,进一步提高了其在检索任务中的有效性和效率。

ColBERT 特别适合需要高精度搜索任务的应用,使其成为自然语言处理和信息检索等领域的宝贵工具。

早期交互会增加计算复杂性,因为它需要考虑所有可能的查询-文档对,这使得其对于大规模应用来说效率较低。

后期交互模型(如 ColBERT)通过允许预先计算文档表示并在最后采用更轻量级的交互步骤(重点关注已编码的表示)来优化效率和可扩展性。这种设计选择可以缩短检索时间并减少计算需求,使其更适合处理大型文档集。

什么是视觉语言模型?

视觉语言模型 (VLM) 是集成视觉和文本信息的高级 AI 系统,使其能够执行各种需要理解和基于图像生成文本的任务。以下是其主要特征和应用的概述:

定义和功能

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

主要特点

  • 图像和文本编码: VLM 通常由图像和文本的单独编码器组成。它们融合来自这些编码器的信息,以全面理解输入数据。
  • 零样本学习:许多 VLM 表现出强大的零样本能力,这意味着它们可以很好地推广到新任务而不需要额外的训练数据。
  • 空间感知:某些模型可以捕捉图像内的空间关系,从而允许它们在识别图像中的特定对象或区域时输出边界框或分割蒙版

来自来源

多模式 RAG 实施步骤:

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

多个向量数据库支持多向量架构或 ColBERT 样式表示,从而能够高效地索引和检索高维向量数据。以下是一些值得注意的选项:

  1. Vespa:Vespa 引入了多向量支持,允许每个文档索引多个向量。此功能允许根据每个文档中最接近的向量检索文档,使其适用于复杂的数据表示和语义搜索应用程序。
  2. Pinecone:Pinecone 专为管理向量嵌入而设计,并支持高级查询功能,包括处理多个向量表示。它针对 AI 应用进行了优化,使其成为需要细致入微的数据表示任务的有力候选者。
  3. Qdrant:Qdrant 是一个专门的矢量数据库,可以高效地索引和检索高维矢量数据。虽然它主要关注单矢量嵌入,但它适用于各种架构,包括可能需要多矢量设置的架构

所需技术堆栈

  1. 用于运行 Qwen2-VL-7b-Instruct VLM 的 Transformers library 
  2. 如果我们想在消费者 GPU(24 GB VRAM)上运行 VLM(Qwen2-VL),则需要 Flash Attention。
  3. Byaldi 是 ColPali 存储库的包装器,可以非常轻松地将 ColPali 用于 RAG
  4. qwen_vl_utils 促进 Qwen-VL 的输入处理。
  5. pdf2image 用于将 PDF 页面转换为图像。这是必需的,因为 Qwen2-VL 无法编码 PDF 文件。
  6. byaldi 需要 popller-utils 来索引 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
  • 从 byaldi 使用 RAGMultiModal 加载 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])

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

  • 保存图片
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(大型语言和视觉助手)是一个开源的、经过微调的多模态模型,可以生成图像的文本描述,在多模态指令跟踪任务上取得了令人印象深刻的性能,并在某些基准测试中优于 GPT-4。
  • 上下文窗口:4,096 个 token

限制

  • 预览模型: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 的优势与创新的架构选择相结合。它能够高效地处理和检索复杂文档中的信息,使其成为不断发展的 AI 驱动数据分析和检索系统领域的宝贵工具。

在这里,我们使用 ColPali 作为视觉检索器,Qwen2-VL 作为视觉语言模型,构建了一个多模态 RAG 管道。我们还使用 Llava 模型测量了性能。

原文见:https://medium.com/the-ai-forum/implement-multimodal-rag-with-colpali-and-vision-language-model-groq-llava-and-qwen2-vl-5c113b8c08fd