探索 mcdse-2b-v1:全新高效的多语言文档检索模型

文摘   2024-11-12 21:58   福建  

.01

概述
在信息时代的浪潮中,各类数据以惊人的速度不断产生,涵盖文档、演示文稿、图像等多种格式。这些信息的多样性为有效检索带来了巨大的挑战。传统的检索模型在处理纯文本查询时表现良好,但面对复杂的多模态内容(如截图或幻灯片)时,却往往力不从心。这对于需要从包含文本和视觉元素的文档中提取信息的企业、研究人员和教育工作者来说,尤为棘手。因此,迫切需要一种能够高效处理这些多样化内容的模型。

.02

引入 mcdse-2b-v1:文档检索的新方法
今天,我们要向大家介绍 mcdse-2b-v1,这是一款全新的人工智能模型,能够嵌入页面或幻灯片截图,并通过自然语言进行查询。与依赖文本进行索引和搜索的传统检索系统不同,mcdse-2b-v1 让用户可以处理包含文字、图片和图表的截图或幻灯片,这为经常处理非纯文本文档的用户打开了新的可能性。用户只需截取一张演示文稿的截图或信息图文档,将其嵌入模型中,就能通过自然语言搜索获得相关信息。
mcdse-2b-v1 架起了传统文本查询与更复杂视觉数据之间的桥梁,非常适合那些需要频繁分析演示文稿、报告或其他视觉文档内容的行业。这一能力使得该模型在信息丰富的环境中显得尤为重要,因为手动浏览这些视觉密集的文档往往耗时且效率低下。与其费力寻找那一张特定的幻灯片,或是逐页翻阅密集的报告,不如利用自然语言直接搜索嵌入内容,既节省了时间,又提升了工作效率。

.03

技术细节与优势
mcdse-2b-v1(🤗)基于 MrLight/dse-qwen2-2b-mrl-v1,并采用 DSE 方法进行训练。它是一款高效、可扩展且多语言的文档检索模型,能够无缝处理混合内容源。该模型提供了一种嵌入机制,有效捕捉文本与视觉成分,使得在多模态数据类型之间进行强大的检索操作成为可能。
mcdse-2b-v1 最显著的特点之一是其资源效率。例如,它可以在仅 10 GB 的空间内嵌入 1 亿个页面。这种优化水平使其非常适合数据存储紧张的应用场景,如本地解决方案或边缘计算部署。此外,该模型的体积可以缩小至原来的六分之一,且性能损失极小,这使其能够在资源有限的设备上运行,同时保持高检索准确性。

另一个优势是 mcdse-2b-v1 与常用框架如 Transformers 或 vLLM 的兼容性,这使得其对广泛用户而言变得更加可及。这种灵活性使得开发者和数据科学家可以轻松将该模型集成到现有的机器学习工作流中,无需进行大幅修改,极大地方便了使用。


#如何使用

初始化模型和处理器

from transformers import AutoProcessor, Qwen2VLForConditionalGeneration
from PIL import Image
import torch
import math

model = Qwen2VLForConditionalGeneration.from_pretrained(
    'marco/mcdse-2b-v1',
    attn_implementation="flash_attention_2",
    torch_dtype=torch.bfloat16,
    device_map="cuda:0"
).eval()

min_pixels = 1 * 28 * 28
max_pixels = 960 * 28 * 28

processor = AutoProcessor.from_pretrained(
    'marco/mcdse-2b-v1',
    min_pixels=min_pixels,
    max_pixels=max_pixels
)

model.padding_side = "left"
processor.tokenizer.padding_side = "left"

document_prompt = "<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\n<|vision_start|><|image_pad|><|vision_end|>What is shown in this image?<|im_end|>\n<|endoftext|>"

query_prompt = "<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\n<|vision_start|><|image_pad|><|vision_end|>Query: %s<|im_end|>\n<|endoftext|>"


对查询进行编码

def encode_queries(queries: list[str], dimension: int):
    dummy_image = Image.new('RGB', (5656))
    inputs = processor(
        text=[query_prompt % x for x in queries],
        images=[dummy_image for _ in queries],
        videos=None,
        padding='longest',
        return_tensors='pt'
    ).to('cuda:0')

    cache_position = torch.arange(0, len(queries))
    inputs = model.prepare_inputs_for_generation(
        **inputs, cache_position=cache_position, use_cache=False)

    with torch.no_grad():
        output = self.model(
            **inputs,
            return_dict=True,
            output_hidden_states=True
        )
    
    embeddings = output.hidden_states[-1][:, -1]
    return torch.nn.functional.normalize(embeddings[:, :dimension], p=2, dim=-1


对文档进行编码

def round_by_factor(number: float, factor: int) -> int:
    return round(number / factor) * factor

def ceil_by_factor(number: float, factor: int) -> int:
    return math.ceil(number / factor) * factor

def floor_by_factor(number: float, factor: int) -> int:
    return math.floor(number / factor) * factor

def smart_resize(height: int, width: int) -> tuple[int, int]:
        h_bar = max(28, round_by_factor(height, 28))
        w_bar = max(28, round_by_factor(width, 28))
        if h_bar * w_bar > max_pixels:
            beta = math.sqrt((height * width) / max_pixels)
            h_bar = floor_by_factor(height / beta, 28)
            w_bar = floor_by_factor(width / beta, 28)
        elif h_bar * w_bar < min_pixels:
            beta = math.sqrt(min_pixels / (height * width))
            h_bar = ceil_by_factor(height * beta, 28)
            w_bar = ceil_by_factor(width * beta, 28)
        return h_bar, w_bar

def resize(image: Image.Image):
    new_size = smart_resize(image.height, image.width)
    return image.resize(new_size)

def encode_documents(documents: list[Image.Image], dimension: int):
    inputs = processor(
        text=[document_prompt] * len(documents),
        images=[resize(x) for x in documents],
        videos=None,
        padding='longest',
        return_tensors='pt'
    ).to('cuda:0')

    cache_position = torch.arange(0, len(queries))
    inputs = model.prepare_inputs_for_generation(
        **inputs, cache_position=cache_position, use_cache=False)

    with torch.no_grad():
        output = self.model(
            **inputs,
            return_dict=True,
            output_hidden_states=True
        )
    
    embeddings = output.hidden_states[-1][:, -1]
    return torch.nn.functional.normalize(embeddings[:, :dimension], p=2, dim=-1


对比结果


.04

mcdse-2b-v1 的重要性

mcdse-2b-v1 的意义不仅在于其高效的信息检索能力,更在于它如何使复杂文档分析变得更加平易近人。传统的文档检索方法往往需要精确的结构化,并且常常忽视现代文档中丰富的视觉元素。而 mcdse-2b-v1 的出现,让用户可以像进行文本查询一样,轻松访问嵌入在图表、图示及其他非文本组件中的信息。
初步结果显示,即使在压缩至原始大小的六分之一时,mcdse-2b-v1 依然能够持续提供高检索准确率。这种性能使其适合于大规模部署,而不必担心典型的计算开销。此外,其多语言能力意味着它可以为全球范围内的用户提供服务,对于在多个语言环境中运作的跨国组织或学术机构而言,尤其宝贵。
对于那些从事多模态检索增强生成(RAG)工作的人员来说,mcdse-2b-v1 提供了一种可扩展的解决方案,能够为包含文本和视觉内容的文档提供高性能的嵌入。这种结合增强了下游任务的能力,如回答复杂用户查询或从多模态输入中生成详细报告。

.05

结语
mcdse-2b-v1 通过嵌入页面和幻灯片截图,具备了可扩展性、效率和多语言能力,从而解决了多模态文档检索的挑战。它简化了与复杂文档的互动,使用户免于繁琐的手动搜索过程。用户将获得一种强大的检索模型,有效处理多模态内容,认识到现实数据的复杂性。这一模型重新定义了我们如何访问和与嵌入文本和视觉知识互动,为文档检索设定了新的标准。
通过以上的介绍,相信大家对 mcdse-2b-v1 有了更深入的了解。这一模型不仅将推动文档检索技术的发展,也将改变我们处理信息的方式,让知识获取变得更加高效和便捷。欢迎大家继续关注这一领域的最新动态!
 

参考:

  1. https://huggingface.co/marco/mcdse-2b-v1





Halo咯咯
专注于技术知识整理,包含人工智能、大模型、机器学习、深度学习、大数据等多个领域的技术知识,以及各种开源的内容~
 最新文章