【多模态&RAG】多模态RAG ColPali实践

关于【RAG&多模态】多模态RAG-ColPali:使用视觉语言模型实现高效的文档检索前面已经介绍了(供参考),这次来看看ColPali实践。

所需权重:

  1. 多模态问答模型:Qwen2-VL-72B-Instruct,https://modelscope.cn/models/Qwen/Qwen2-VL-72B-Instruct

  2. 基于 PaliGemma-3B 和 ColBERT 策略的视觉检索器:

    • ColPali(LoRA):https://huggingface.co/vidore/colpali

    • ColPali(基座):https://huggingface.co/vidore/colpaligemma-3b-mix-448-base

多模态检索问答实践

  • lora的adapter_config.json字段base_model_name_or_path修改地址:ColPali(基座)存储路径

  • qwen_vl_utils下载地址:https://github.com/QwenLM/Qwen2-VL/tree/main/qwen-vl-utils/src/qwen_vl_utils

  • byaldi安装方式:https://github.com/AnswerDotAI/byaldi

  • 完整代码


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

class DocumentQA:
    def __init__(self, rag_model_name: str, vlm_model_name: str, device: str = 'cuda', system_prompt: str = None):
        self.rag_engine = RAGMultiModalModel.from_pretrained(rag_model_name)
        self.vlm = Qwen2VLForConditionalGeneration.from_pretrained(
            vlm_model_name,
            torch_dtype=torch.bfloat16,
            attn_implementation="flash_attention_2",
            device_map=device
        )
        self.processor = AutoProcessor.from_pretrained(vlm_model_name, trust_remote_code=True)
        self.device = device
        if system_prompt is None:
            self.system_prompt = (
                "你是一位专精于计算机科学和机器学习的AI研究助理。"
                "你的任务是分析学术论文,尤其是关于文档检索和多模态模型的研究。"
                "请仔细分析提供的图像和文本,提供深入的见解和解释。"
            )
        else:
            self.system_prompt = system_prompt

    def index_document(self, pdf_path: str, index_name: str = 'index', overwrite: bool = True):
        self.pdf_path = pdf_path
        self.rag_engine.index(
            input_path=pdf_path,
            index_name=index_name,
            store_collection_with_index=False,
            overwrite=overwrite
        )
        self.images = convert_from_path(pdf_path)

    def query(self, text_query: str, k: int = 3) -> str:
        results = self.rag_engine.search(text_query, k=k)
        print("搜索结果:", results)

        if not results:
            print("未找到相关查询结果。")
            return None

        try:
            page_num = results[0]["page_num"]
            image_index = page_num - 1
            image = self.images[image_index]
        except (KeyError, IndexError) as e:
            print("获取页面图像时出错:", e)
            return None

        messages = [
            {
                "role": "system",
                "content": self.system_prompt
            },
            {
                "role": "user",
                "content": [
                    {"type": "image", "image": image},
                    {"type": "text", "text": text_query},
                ],
            }
        ]

        text = self.processor.apply_chat_template(
            messages, tokenize=False, add_generation_prompt=True
        )

        image_inputs, video_inputs = process_vision_info(messages)

        # 准备模型输入
        inputs = self.processor(
            text=[text],
            images=image_inputs,
            videos=video_inputs,
            padding=True,
            return_tensors="pt",
        )
        inputs = inputs.to(self.device)

        generated_ids = self.vlm.generate(**inputs, max_new_tokens=1024)

        generated_ids_trimmed = [
            out_ids[len(in_ids):] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)
        ]
        output_text = self.processor.batch_decode(
            generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
        )

        return output_text[0]

if __name__ == "__main__":
    # 初始化 DocumentQA 实例
    document_qa = DocumentQA(
        rag_model_name="./colpali",
        vlm_model_name="./Qwen2-VL-7B-Instruct",
        device='cuda'
    )

    # 索引 PDF 文档
    document_qa.index_document("test.pdf")

    # 定义查询
    text_query = (
        "文中模型在哪个数据集上相比其他模型有最大的优势?"
        "该优势的改进幅度是多少?"
    )

    # 执行查询并打印答案
    answer = document_qa.query(text_query)
    print("答案:", answer)
### 关于Llamaindex和Ollama在多模态RAG方面的实现与应用 #### Llamaindex中的多模态数据处理机制 Llamaindex提供了一种灵活的方式来处理多模态数据,特别是通过定义不同的节点类型来适应不同类型的数据输入。具体来说,该框架支持`BaseNode`作为基础类,派生出了用于存储文本的`TextNode`、用于存储图像的`ImageNode`以及其他类型的节点[^1]。 对于每一个创建出来的节点实例而言,除了基本的内容外还附带了一些元属性(metadata),比如唯一标识符(id_)、与其他节点之间的关系描述(relationship)等信息。这些特性使得开发者能够更加方便地管理和操作复杂结构化的数据集。 #### Ollama的角色及其集成方法 当涉及到实际项目部署时,则可能需要用到像Ollama这样的平台来进行模型服务化工作。以Qwen为例,在其API层面做出相应调整就可以轻松切换至其他视觉-语言预训练模型如Qwen-VL-MAX上运行[^2]。这意味着如果想要扩展一个多模态问答系统或搜索引擎的功能,只需按照目标模型的要求更改请求参数即可完成迁移过程而无需重写大量代码逻辑。 #### 应用案例分析 在一个典型的基于Llamaindex构建的应用程序中,文档会被分割成多个片段(chunk/node), 并且针对每一片段会记录下详细的上下文关联信息以便后续查询使用。这种做法不仅提高了检索效率同时也增强了结果的相关性和准确性[^3]。例如,在一个本地图片加文字混合搜索场景里,通过对上传资料做精细化切分并建立索引后,即使面对海量资源也能够在短时间内给出精准的回答或者推荐列表给用户。 ```python from llama_index import SimpleDirectoryReader, GPTListIndex, readers documents = SimpleDirectoryReader('data').load_data() index = GPTListIndex.from_documents(documents) def query_with_multimodal(index, text_query=None, image_query=None): """Query index with optional text and/or image input.""" response = "" if text_query is not None: response += f"Text Query Result:\n {index.query(text_query)}\n" if image_query is not None: # Assuming there's a method to handle image queries within the framework. img_response = process_image_query(image_query) response += f"\nImage Query Result:\n{img_response}" return response.strip() # Example usage of multimodal querying function print(query_with_multimodal(index, "What does this document say about llamas?", "./path_to_test_image.jpg")) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值