亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

使用PyMuPDF4LLM構建多模態大模型應用

本尼托·马丁写的。

从PDF中提取文本是许多AI和LLM(大型语言模型)应用中的一个关键且常常具有挑战性的步骤。高质量的文本提取在改进下游流程(如分词、创建嵌入或在向量数据库中进行索引)方面起着重要作用,从而提升应用的整体性能。PyMuPDF 是一个流行的库,因其简单、快速且高质量的文本提取功能而广受欢迎。

在这篇博客中,我们将探讨由Artifex(PyMuPDF的创建者)最近推出的免费库PyMuPDF4LLM。这个名为PyMuPDF4LLM的新库旨在简化从PDF中提取文本的工作,特别是为大型语言模型(LLM)和检索增强生成(RAG)的应用提供支持。它提供了两种关键的格式。

  • pymupdf4llm.to_markdown() :提取为 Markdown 格式的内容:
  • pymupdf4llm.LlamaMarkdownReader() :提取内容并转换为 LlamaIndex 文档对象:

我们将重点关注 _tomarkdown,因为它包含了多个可以让它实现功能的超参数,比如图像提取,使其既适用于文本处理,也适用于多模态应用。

让我们来深入吧!

主要特点

所有的超参数(超参数是指在模型训练过程中需要调整的参数)可以在API文档中找到。虽然我们会详细讲解几个参数,但PyMuPDF4LLM的关键特性可以总结如下:

  • 文本提取:提取Markdown格式的内容。
  • 内容拆分:支持将元数据、表格和图片列表添加到提取的内容中。
  • 图片提取:定义图片的尺寸、分辨率和格式。
  • 嵌入图片:图片直接嵌入Markdown输出中。
  • 文本单词提取:精确提取PDF中的单词。
提取文字

这是第一步,如下所示,文本将被提取为Markdown格式,可以选择要提取文档的哪些页面。

    !pip install -qq pymupdf4llm  # 安装pymupdf4llm库
import pymupdf4llm  

# 将 PDF 文档转换为 Markdown 格式
md_text = pymupdf4llm.to_markdown(doc="/content/document.pdf",  # PDF 文件路径
                                  pages = [0, 1, 2])

输出内容


    #### 在提供适当引用的前提下,谷歌特此授予许可,仅用于新闻报道或学术作品中复制本文档中的表格和图表。\n\n## 注意力,这就是你需要的\n\n\n**
    阿什什瓦尼[∗]**
    谷歌大脑
[email protected]\n\n```\n**
    利奥恩·琼斯[∗]**
    谷歌研究院
[email protected]\n\n```\n\n**
    诺姆·沙泽尔[∗]**
    谷歌大脑
[email protected]\n\n```\n
分块处理

注:此处“分块处理”指的是将数据或文本分割成较小的管理单元,以便于处理。

这里就有趣了。纯Markdown文本对于LLM应用来说并不理想——元数据在提高模型准确性和性能方面起着关键作用。如下面的例子所示,可以从中提取大量信息,包括文档的创建日期、文件路径、图像坐标以及目录(TOC),所有这些都可以丰富应用的上下文信息。

    md文本 = pymupdf4llm.转换为Markdown(doc="/content/document.pdf",  # 文件路径,指向PDF文档
                                      pages = [0, 1, 2],  # 指定要转换的页面
                                      page_chunks = True)  # 指定是否将页面分割成片段
    # 将PDF文件转换为Markdown文本,并指定要转换的页面及其片段

注释:

  • pymupdf4llm 是一个库或模块名称,用于将PDF文件转换为Markdown文本。
  • 转换为Markdown 表示将文件转换为Markdown格式。
  • doc="/content/document.pdf" 指定PDF文件路径。
  • pages=[0, 1, 2] 指定要转换的页面。
  • page_chunks=True 表示是否将页面分割成片段。

下面的输出结果是通过添加了page_chunks选项得到的多个片段其中之一。

输出片段

    {'metadata': {'format': 'PDF 1.5',  
       'title': '',  
       'author': '',  
       'subject': '',  
       'keywords': '',  
       'creator': 'LaTeX with hyperref',  
       'producer': 'pdfTeX-1.40.25',  
       'creationDate': 'D:20240410211143Z',  
       'modDate': 'D:20240410211143Z',  
       'trapped': '',  
       'encryption': None,  
       'file_path': '/content/document.pdf',  
       'page_count': 15,  
       'page': 3},  
      'toc_items': [[2, '编码器和解码器栈', 3], [2, '注意力机制', 3]],  
      'tables': [],  
      'images': [{'number': 0,  
        'bbox': (196.5590057373047,  
         72.00198364257812,  
         415.43902587890625,  
         394.4179992675781),  
        'transform': (218.8800048828125,  
         0.0,  
         -0.0,  
         322.416015625,  
         196.5590057373047,  
         72.00198364257812),  
        'width': 1520,  
        'height': 2239,  
        'colorspace': 3,  
        'cs-name': 'DeviceRGB',  
        'xres': 96,  
        'yres': 96,  
        'bpc': 8,  
        'size': 264957}],  
      'graphics': [],  
      'text': '![](/content/images/document.pdf-2-0.jpg)\n\n图 1 中:Transformer 模型架构。\n\nTransformer 使用堆叠的自注意力和逐点全连接层来组成编码器和解码器,如图 1 中的左半部分和右半部分所示。\n\n**3.1 编码器和解码器栈。**\n\n**编码器:** 编码器由 N = 6 层相同的层组成。'
      'words': []}] 

目录项(toc_items)以格式 [层级, 标题, 页码] 提取为,其中 层级 是层级级别(一级为 1,二级为 2,三级为 3 等,以此类推)。

图片提取

在之前的例子中,并没有从 images 字段中提取图片,尽管我们可以看到相关的 images 字段。需要将 write_images 参数设置为 True。此外,还可以选择其他参数,例如图片格式、dpi(分辨率),或者保存提取图片的文件路径。

    # 将PDF文件转换为Markdown格式,并将图片保存到指定路径
    md_text = pymupdf4llm.to_markdown(doc="/content/document.pdf",  
                                      pages = [0, 1, 2],  
                                      page_chunks = True,  
                                      write_images = True,  
                                      image_path = "/content/images",  
                                      image_format = "jpg",  
                                      dpi = 200)

通过这样做,图像将保存在指定的文件夹中,并在相应代码块的 Markdown 文本中的相应字段中添加一个占位符。该占位符将包含文档名称、页码和图像编号。

输出图片

    'graphics': [],  
     'text': '![](/content/images/document.pdf-2-0.jpg)\n\n图1:\n\nTransformer模型采用了这种整体架构,使用堆叠的自注意力机制和点对点的前馈网络。\n\n'

如上所示,提取的图像如下所示。从文件中提取图像的能力使得它们可用于多模态LLM应用(多模态大语言模型应用),增加了额外的功能和灵活性层。

来源自Arxiv网站(https://arxiv.org/abs/1706.03762)

此外,你可以通过使用embed_images参数将图片以base64编码直接嵌入Markdown文本中。这种方法会把图片嵌入到Markdown文件里,但会增加文件的大小,并且无法单独保存图片。

表格提取

就像识别图像并将它们的坐标包含在 JSON 字典中一样,每个识别出的表格也会将其坐标添加到相应的部分中。

生成的表格

     'toc_items': [[2, '英语句法解析', 9]],  
      'tables': [{'bbox': (108.0,  
         129.87200927734375,  
         508.73699951171875,  
         384.1730041503906),  
        'rows': 8,  
        'columns': 3}],  
      'images': [],  
      'graphics': [],  
      'text': '表3:Transformer架构的变种。未列出的参数与基础模型中的保持一致。所有指标均基于德英翻译测试集newstest2013。列出的困惑度是根据我们的字节对编码计算出的每个词元的困惑度,不应与按单词计算的困惑度相比较
单词抽取

现在我们已经提取了文本、表格和图片中的内容,这使得我们的LLM应用有了更多的元数据。为了进一步丰富元数据,我们可以通过设置extract_words参数。这将生成一个按阅读顺序排列的词汇列表,与每个特定片段关联,并包含相应的坐标信息,就像处理表格和图片一样。这包括表格单元格内的文字以及页面上的多列文字,类似下图所示。

作者:阿提法克斯

    md_text = pymupdf4llm.to_markdown(doc="/content/document.pdf",  
                                      pages = [5, 6, 7],  
                                      page_chunks = True,  
                                      write_images = True,  
                                      image_path = "/content/images",  
                                      image_format = "jpg",  
                                      dpi = 200,  
                                      extract_words = True)

和之前的输出一样,我们可以在相应的字段中看到单词序列。

单词序列输出

     'graphics': [],  
      'text': '表1:最长路径长度表',  
      'words': [(107.69100189208984,  
        71.19241333007812,  
        129.12155151367188,  
        81.05488586425781,  
        '表',  
        0,  
        0,  
        0),  
       (131.31829833984375,  
        71.19241333007812,  
        138.9141845703125,  
        81.05488586425781,  
        '1:',  
        0,  
        0,  
        1),  
       (144.78195190429688,  
        71.19241333007812,  
        185.4658203125,  
        81.05488586425781,  
        '最大',  
        0,  
        0,  
        2),  
       (187.65281677246094,  
        71.19241333007812,  
        204.46530151367188,  
        81.05488586425781,  
        '路径长度',  
        0,  
        0,  
        3),

有了这样的文档结构,我们不仅可以丰富我们的向量数据库,还可以添加纯文本 Markdown、图像、表格及其相应的坐标,还能控制一些图像参数,比如分辨率或格式。这种方法极大地增强了任何需要从 PDF 中获取信息的应用程序,特别是那些需要高精度响应的应用程序。

技术笔记:多模态应用(多种模态的集成)

作者名:Benito Martin (由AI生成)

所以,当我们能够从文本中提取出带有元数据和图片的丰富内容后,我们能用 PyMuPDF4LLM 做什么呢?LLM 应用程序可以完成各种任务,但是能够包含文本和图片则可以让多模态模型的应用成为可能,从而提升应用程序的表现。

让我们创建一个笔记本(点击链接查看),来展示如何使用PyMuPDF4LLM构建一个结合了Llama Index框架和Qdrant向量存储的多模态应用。

该应用程序遵循这些步骤。这是基于RAG(检索增强生成)架构的一个简单工作流程,增加了在向量数据库中收集图像(除了文本外)的能力,从而可以检索图像。需要熟悉此工作流程及其常用库的使用。

  • 安装库和依赖项:pymupdf4llm、llamaindex 和 openai 的 clip 嵌入
  • 使用 pymupdf4llm 加载文档
  • 文档对象定制:根据 pymupdf4llm 提取的信息选择元数据
  • 向量存储中的集合创建:文本应用通常只有一个文本集合,但在这种情况下,我们将添加一个包含图像嵌入的第二个集合
  • 索引:这一步是将我们的文本和图像索引到向量存储中的必要步骤
  • 内容检索:根据用户的查询,我们将检索到最相似的文本片段和图像

步骤 1:安装库和设置环境变量

首先,我们需要安装几个库,比如pymupdf4llm,llama index,qdrant和clip embeddings,以便为我们的图像生成嵌入向量。此外,我们还需要一个OPENAI_KEY来为LLM模型提供支持。

# 安装必要的Python包
!pip install -qq, pymupdf4llm   # 用于处理PDF文档的库
!pip install -qq, llama-index   # llama-index相关的核心库
!pip install -qq, llama-index-vector-stores-qdrant   # llama-index与Qdrant向量存储的集成
!pip install -qq, git+https://github.com/openai/CLIP.git  # 安装CLIP库,CLIP是一个开源项目
!pip install -qq, llama-index-embeddings-clip   # llama-index与CLIP嵌入的集成
!pip install -qq, llama-index qdrant-client   # llama-index与Qdrant客户端的集成
# 将用户数据中获取的OPENAI_API_KEY设置到环境变量中
os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY')

步骤2:加载文件

然后我们加载文档,将文档分割成小块并提取jpg格式的图片以便进一步处理。为了简化,我们不会选择所有上述选项,但这可以根据应用程序的具体需求进行进一步的定制。

    # 进行 Markdown 转换
    docs = pymupdf4llm.to_markdown(doc="/content/document.pdf",  
                                      page_chunks = True,  
                                      write_images = True,  
                                      image_path = "/content/images",  
                                      image_format = "jpg")

步骤3:调整文档设置

Llama Index 需要一个 Document 对象。这些 Document 可以包含有用的 元数据,并且会在每个片段上创建一个索引,这将有助于检索步骤。

因此,我们将根据从pymupdf4llm提取的数据进行定制。文本将是主要内容,而作为元数据我们选择toc_itemsimagespagefile_path。这一设置可以根据具体应用进一步扩展和调整,但拥有如我们所见的丰富内容,使我们能够从一开始就增强过程,这对于高效利用LLM应用来说至关重要。

    llama_documents = []  

    for document in docs:  
        # 提取 'metadata' 字段并将某些元素转换为所需格式  
        metadata = {  
            "file_path": document["metadata"].get("file_path"),  
            "page": str(document["metadata"].get("page")),  
            "images": str(document.get("images")),  
            "toc_items": str(document.get("toc_items")),  

        }  

        # 使用仅包含文本和已清理的元数据来创建 Document 对象  
        llama_document = Document(  
            text=document["text"],  
            metadata=metadata,    
            text_template="文本模板: Metadata: {metadata_str}\n-----\nContent: {content}",    
        )  

        llama_documents.append(llama_document)

第四步:创建向量数据库

一旦我们的文档符合所需的格式,并且图片已提取出来,我们就能使用Qdrant创建两个集合,一个用于图片,另一个用于文本。

正如之前提到的,这些集合将分别存储文本和图像的嵌入表示,当用户进行查询时,系统会一起检索这两个部分。

    # 创建Qdrant客户端  
    client = qdrant_client.QdrantClient(location=":memory:")  

    # 创建文本数据集合  
    client.create_collection(  
        collection_name="text_collection",  
        vectors_config=VectorParams(size=1536, distance=Distance.COSINE)  # 余弦距离  
    )  

    # 创建图像数据集合  
    client.create_collection(  
        collection_name="image_collection",  
        vectors_config=VectorParams(size=512, distance=Distance.COSINE)  # 余弦距离  
    )  

    # 文本存储初始化  
    text_store = QdrantVectorStore(  
        client=client, collection_name="text_collection"  
    )  

    # 图像存储初始化  
    image_store = QdrantVectorStore(  
        client=client, collection_name="image_collection"  
    )

第五步:创建一个多媒体索引

既然我们的向量存储已经准备好了,我们可以将这些图像和文本分别存储在对应的集合中,文本集合会生成文本节点,而图像集合会生成图像节点。为此,Llama Index 提供了多模态向量存储索引(MultiModalVectorStoreIndex),我们需要指定文本和图像的路径。

    storage_context = StorageContext.from_defaults(  
        vector_store=text_store, image_store=image_store  
    )  

    ## 上下文图片  
    image_path = "/content/images"  
    ## 读取指定路径下的图片文件  
    image_documents = SimpleDirectoryReader(image_path).load_data()  

    index = MultiModalVectorStoreIndex.from_documents(  
        llama_documents + image_documents,  
        storage_context=storage_context)

这些块代表我们预先定义的块。如果需要将块进一步细分,LlamaIndex 同样支持这种细分。为了简化,我们将保持 pymupdf4llm 提取的块大小不变。

步骤6:取内容

最后一步是提出一个问题并检查我们的流程效率如何。如下代码将检索1个文本节点和1个图像节点。

    # 设置查询和检索器
    query = "你能提供一张多头注意力的图片吗?"

    retriever = index.as_retriever(similarity_top_k=1, image_similarity_top_k=1)  # 检索器用于从索引中检索信息

    retrieval_results = 检索结果 = retriever.retrieve(query)

以下代码段可以帮助我们可视化图像和文本的得分最高的节点。

import matplotlib.pyplot as plt  
from PIL import Image  

def plot_images(image_paths):  
    images_shown = 0  
    plt.figure(figsize=(16, 9))  
    for img_path in image_paths:  
        if os.path.isfile(img_path):  
            image = Image.open(img_path)  

            plt.subplot(2, 3, images_shown + 1)  
            plt.imshow(image)  
            plt.xticks([])  
            plt.yticks([])  

            images_shown += 1  
            if images_shown >= 9:  
                break  

retrieved_image = []  

for res_node in retrieval_results:  
    if isinstance(res_node.node, ImageNode):  
        print("找到了得分最高的图片节点")  
        print("-----------------------")  
        retrieved_image.append(res_node.node.metadata["file_path"])  
    else:  
        print("找到了得分最高的文本节点")  
        print("-----------------------")  

        display_source_node(res_node, source_length=200)

我们看到结果相当满意,因为文本部分引用了图2,这与图像部分中的内容相符。

作者是 Benito Martin

总结

在这篇文章里,我们使用 pymupdf4llm 强大的功能构建了一个简单的RAG流程,用于从文档中提取元数据和图片资料,从而提升了应用的功能。只需要一行代码,即可提取所有相关数据,大大加速了管道创建过程。

Artifex的这个新LLM工具的独特功能,结合其他集成工具,例如与LlamaIndex集成的LlamaMarkdownReader,为改进LLM应用程序并减少开发时间提供了新的可能性。

如果你喜欢看这些内容,你可以通过以下方式,比如,帮助我:

  • 拍手 并在 Medium 上 关注 我!👏 👏 👏
  • 关注 我的 GitHub 🎶 🎷 🎶
  • 星标我的 项目 ⭐⭐⭐
  • 在 LinkedIn 上分享我的内容吧! 💯💯💯
  • 请我喝杯 咖啡,或者在 GitHub Sponsors 支持我 🚀🚀🚀
  • 我合作吗? 👨‍💻👨‍💻👨‍💻

祝你编程愉快!

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消