RAG基建之PDF解析的“流水线”魔法之旅

将PDF文件和扫描图像等非结构化文档转换为结构化或半结构化格式是人工智能的关键部分。然而,由于PDF的复杂性和PDF解析任务的复杂性,这一过程显得神秘莫测。
在RAG(Retrieval-Augmented Generation)基建之PDF解析的“魔法”与“陷阱”中,我们介绍了PDF解析的主要任务,对现有方法进行了分类,并简要介绍了每种方法。RAG基建之PDF解析的“无OCR”魔法之旅中介绍了端到端方法。

本篇咱们来聊聊PDF解析的“流水线”大冒险!想象一下,PDF文件就像一座神秘的迷宫,里面藏着各种文字、表格、公式和图片。我们的任务就是把这些乱七八糟的东西整理得井井有条,变成结构化的数据。听起来是不是有点像在迷宫里找宝藏?

基于流水线的方法将PDF解析任务视为一系列模型或算法的流水线,如下所示。在这里插入图片描述

基于流水线的方法可以分为以下五个步骤:

  1. 预处理原始PDF文件:修复模糊或倾斜等问题。此步骤包括图像增强、图像方向校正等。
  2. 进行布局分析:主要包括视觉结构分析和语义结构分析。前者识别文档的结构并勾勒出相似区域,后者为这些区域标注特定的文档类型,如文本、标题、列表、表格、图表等。此步骤还涉及分析页面的阅读顺序。
  3. 分别处理布局分析中识别的不同区域:此过程包括理解表格、识别文本以及识别公式、流程图和特殊符号等其他组件。
  4. 整合之前的结果:恢复页面结构。
  5. 输出结构化或半结构化信息:如Markdown、JSON或HTML。

PDF解析的“流水线”方法四大天王:

    1. Marker:轻量级“宝藏猎人”
      Marker是个轻量级的工具,速度快得像闪电侠,但它也有点小毛病。比如,它不太擅长处理表格,尤其是表格标题,简直像是迷路的小羊羔。不过,它对付公式倒是有一套,尤其是那些复杂的数学公式,Marker能用Texify模型把它们变成漂亮的LaTeX格式。可惜的是,它只懂英语,日语和印地语对它来说就像外星语。
    1. Papermage:科学文档的“多面手”
      Papermage是个专门对付科学文档的“多面手”。它不仅能把文档拆分成各种元素(文字、图表、表格等),还能灵活处理跨页、跨列的复杂内容。它的设计非常模块化,开发者可以轻松添加新功能,就像给乐高积木加新零件一样简单。不过,它目前还没有并行处理的能力,解析速度有点慢,像是在用老式打字机敲代码。
    1. Unstructured:全能型“迷宫大师”
      Unstructured是个全能型选手,布局分析做得非常细致。它不仅能识别文字和表格,还能处理复杂的文档结构。它的自定义能力也很强,开发者可以根据需要调整中间结果,就像在迷宫里随时调整路线一样灵活。不过,它在公式识别上表现一般,像是迷宫里的一块“绊脚石”。

接下来,本文将讨论几种具有代表性的基于流水线的PDF解析框架,并分享从中获得的见解。

文章目录

    • Marker
      • 整体流程
      • 从Marker中获得的见解
      • Marker的缺点
    • PaperMage
      • 组件
      • 基础数据类
      • 整体流程和代码分析
      • 句子分割
      • 布局结构分析
      • 逻辑结构分析
      • 关于Papermage的见解和讨论
    • Unstructured
      • 关于布局分析
      • 关于自定义
      • 关于表格检测和识别
      • 关于公式检测和识别
    • MinerU:基于管道的开源文档解析框架
      • MinerU 工作流程:
      • MinerU所使用的主要模型和算法
      • 评论
    • 结论

Marker

Marker 是一个用于深度学习模型的流水线。它能够将PDF、EPUB和MOBI文档转换为Markdown格式。

整体流程

Marker的整体流程分为以下四个步骤:
在这里插入图片描述

步骤1:使用PyMuPDF和OCR将页面划分为块并提取文本。对应代码如下:

def convert_single_pdf(fname: str,model_lst: List,max_pages=None,metadata: Optional[Dict]=None,parallel_factor: int = 1
) -> Tuple[str, Dict]:......doc = pymupdf.open(fname, filetype=filetype)if filetype != "pdf":conv = doc.convert_to_pdf()doc = pymupdf.open("pdf", conv)blocks, toc, ocr_stats = get_text_blocks(doc,tess_lang,spell_lang,max_pages=max_pages,parallel=int(parallel_factor * settings.OCR_PARALLEL_WORKERS))

步骤2:使用布局分割器对块进行分类,并使用列检测器对块进行排序。对应代码如下:

def convert_single_pdf(fname: str,model_lst: List,max_pages=None,metadata: Optional[Dict]=None,parallel_factor: int = 1
) -> Tuple[str, Dict]:......# 从列表中解包模型texify_model, layoutlm_model, order_model, edit_model = model_lstblock_types = detect_document_block_types(doc,blocks,layoutlm_model,batch_size=int(settings.LAYOUT_BATCH_SIZE * parallel_factor))# 查找页眉和页脚bad_span_ids = filter_header_footer(blocks)out_meta["block_stats"] = {"header_footer": len(bad_span_ids)}annotate_spans(blocks, block_types)# 如果设置了调试标志,则转储调试数据dump_bbox_debug_data(doc, blocks)blocks = order_blocks(doc,blocks,order_model,batch_size=int(settings.ORDERER_BATCH_SIZE * parallel_factor))......

步骤3:过滤页眉和页脚,修复代码和表格块,并应用Texify模型处理公式。对应代码如下:

def convert_single_pdf(fname: str,model_lst: List,max_pages=None,metadata: Optional[Dict]=None,parallel_factor: int = 1
) -> Tuple[str, Dict]:......# 修复代码块code_block_count = identify_code_blocks(blocks)out_meta["block_stats"]["code"] = code_block_countindent_blocks(blocks)# 修复表格块merge_table_blocks(blocks)table_count = create_new_tables(blocks)out_meta["block_stats"]["table"] = table_countfor page in blocks:for block in page.blocks:block.filter_spans(bad_span_ids)block.filter_bad_span_types()filtered, eq_stats = replace_equations(doc,blocks,block_types,texify_model,batch_size=int(settings.TEXIFY_BATCH_SIZE * parallel_factor))out_meta["block_stats"]["equations"] = eq_stats......

步骤4:使用编辑器模型对文本进行后处理。对应代码如下:

def convert_single_pdf(fname: str,model_lst: List,max_pages=None,metadata: Optional[Dict]=None,parallel_factor: int = 1
) -> Tuple[str, Dict]:......# 复制以避免更改原始数据merged_lines = merge_spans(filtered)text_blocks = merge_lines(merged_lines, filtered)text_blocks = filter_common_titles(text_blocks)full_text = get_full_text(text_blocks)# 处理空块的连接full_text = re.sub(r'\n{3,}', '\n\n', full_text)full_text = re.sub(r'(\n\s){3,}', '\n\n', full_text)# 将项目符号字符替换为 -full_text = replace_bullets(full_text)# 使用编辑器模型对文本进行后处理full_text, edit_stats = edit_full_text(full_text,edit_model,batch_size=settings.EDITOR_BATCH_SIZE * parallel_factor)out_meta["postprocess_stats"] = {"edit": edit_stats}return full_text, out_meta

从Marker中获得的见解

到目前为止,我们已经介绍了Marker的整体流程。现在,让我们讨论从Marker中获得的见解。

见解1:布局分析可以分为多个子任务。第一个子任务涉及调用PyMuPDF API获取页面块。

def ocr_entire_page(page, lang: str, spellchecker: Optional[SpellChecker] = None) -> List[Block]:if settings.OCR_ENGINE == "tesseract":return ocr_entire_page_tess(page, lang, spellchecker)elif settings.OCR_ENGINE == "ocrmypdf":return ocr_entire_page_ocrmp(page, lang, spellchecker)else:raise ValueError(f"未知的OCR引擎 {settings.OCR_ENGINE}")def ocr_entire_page_tess(page, lang: str, spellchecker: Optional[SpellChecker] = None) -> List[Block]:try:full_tp = page.get_textpage_ocr(flags=settings.TEXT_FLAGS, dpi=settings.OCR_DPI, full=True, language=lang)blocks = page.get_text("dict", sort=True, flags=settings.TEXT_FLAGS

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/75996.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】GDB调试指南

一、GDB基础 1. 启动调试 gdb ./your_program # 启动调试 gdb --args ./prog arg1 # 带参数启动 gdb -p <pid> # 附加到正在运行的进程 2. 断点管理 b main # 在main函数设断点 b file.c:20 # 在file.c第20行设断点 b *0x4005a…

Android面试总结之Glide源码级理解

当你的图片列表在低端机上白屏3秒、高端机因内存浪费导致FPS腰斩时&#xff0c;根源往往藏在Glide的内存分配僵化、磁盘混存、网络加载无优先级三大致命缺陷中。 本文从阿里P8级缓存改造方案出发&#xff0c;结合Glide源码实现动态内存扩容、磁盘冷热分区、智能预加载等黑科技&…

驱动开发系列49 - 搭建 Vulkan 驱动调试环境(编译 mesa 3D)- Ubuntu24.04

一:搭建Vulkan运行环境 安装vulkan依赖包: 1. sudo apt install vulkan-tools 2. sudo apt install libvulkan-dev 3. sudo apt install vulkan-utility-libraries-dev spirv-tools 4. sudo apt install libglfw3-dev libglm-dev 5. sudo apt install libxxf86vm-dev libxi-…

深度学习——图像余弦相似度

计算机视觉是研究图像的学问&#xff0c;在图像的最终评价时&#xff0c;往往需要用到一些图像相似度的度量指标&#xff0c;因此&#xff0c;在本文中我们将详细地介绍原生和调用第三方库的计算图像余弦相似度的方法。 使用原生numpy实现 import numpy as npdef image_cosin…

项目代码第8讲【数据库基础知识】:SQL(DDL、DML、DQL、DCL);函数(聚合、字符串、数值、日期、流程);约束;多表查询;事务

黑马程序员 MySQL数据库入门到精通&#xff0c;从mysql安装到mysql高级、mysql优化全囊括_哔哩哔哩_bilibili 一、数据库相关概念 1、主流的关系型数据库都支持SQL语言——SQL语言可以操作所有的关系型数据库 像MySQL、Oracle Database、Microsoft SQL Server、IBM Db2等主流的…

如何在阿里云linux主机上部署Node.Js

在阿里云的Linux服务器上搭建Node.js编程环境可以通过以下步骤完成。这里以常见的 Ubuntu/CentOS 系统为例&#xff0c;提供两种安装方式&#xff08;包管理器、NVM多版本管理&#xff09;&#xff1a; 一、通过包管理器安装&#xff08;适合快速安装指定版本&#xff09; 1. …

Python爬虫:开启数据抓取的奇幻之旅(一)

目录 一、爬虫初印象&#xff1a;揭开神秘面纱​ 二、工欲善其事&#xff1a;前期准备​ &#xff08;一&#xff09;Python 环境搭建​ 1.下载 Python 安装包&#xff1a;​ 2.运行安装程序&#xff1a;​ 3.配置环境变量&#xff08;若自动添加失败&#xff09;&#x…

机器学习——集成学习框架(GBDT、XGBoost、LightGBM、CatBoost)、调参方法

一、集成学习框架 对训练样本较少的结构化数据领域&#xff0c;Boosting算法仍然是常用项 XGBoost、CatBoost和LightGBM都是以决策树为基础的集成学习框架 三个学习框架的发展是&#xff1a;XGBoost是在GBDT的基础上优化而来&#xff0c;CatBoost和LightGBM是在XGBoost的基础上…

第十五章:Python的Pandas库详解及常见用法

在数据分析领域&#xff0c;Python的Pandas库是一个不可或缺的工具。它提供了高效的数据结构和数据分析工具&#xff0c;使得数据处理变得简单而直观。本文将详细介绍Pandas库的基本功能、常见用法&#xff0c;并通过示例代码演示如何使用Pandas进行数据处理。最后&#xff0c;…

【Python桌面应用】PySide6 界面开发完全指南

文章目录 1. 引言2. PySide6 简介与安装2.1 什么是PySide62.2 PySide6 vs. PyQt62.3 安装PySide62.4 开发环境配置建议 3. Qt 设计原理3.1 Qt对象模型3.2 信号与槽机制3.3 Qt坐标系统3.4 Qt样式表(QSS) 4. 创建第一个应用4.1 基本应用结构4.2 主窗口与应用生命周期4.3 使用面向…

用 pytorch 从零开始创建大语言模型(三):编码注意力机制

从零开始创建大语言模型&#xff08;Python/pytorch &#xff09;&#xff08;三&#xff09;&#xff1a;编码注意力机制 3 编码注意力机制3.1 建模长序列的问题3.2 使用注意力机制捕捉数据依赖关系3.3 通过自注意力关注输入的不同部分3.3.1 一个没有可训练权重的简化自注意力…

Spring中的IOC及AOP概述

前言 Spring 框架的两大核心设计思想是 IOC&#xff08;控制反转&#xff09; 和 AOP&#xff08;面向切面编程&#xff09;。它们共同解决了代码耦合度高、重复逻辑冗余等问题。 IOC&#xff08;控制反转&#xff09; 1.核心概念 控制反转&#xff08;Inversion of Control…

STM32_HAL开发环境搭建【Keil(MDK-ARM)、STM32F1xx_DFP、 ST-Link、STM32CubeMX】

安装Keil(MDK-ARM)【集成开发环境IDE】 我们会在Keil(MDK-ARM)上去编写代码、编译代码、烧写代码、调试代码。 Keil(MDK-ARM)的安装方法&#xff1a; 教学视频的第02分03秒开始看。 安装过程中请修改一下下面两个路径&#xff0c;避免占用C盘空间。 Core就是Keil(MDK-ARM)的…

python 第三方库 - dotenv读取配置文件

.env 文件是一种用于存储环境变量的配置文件&#xff0c;常用于项目的运行环境设置。环境变量是操作系统层面的一些变量&#xff0c;它们可以被应用程序访问和使用&#xff0c;通常包含敏感信息或特定于环境的配置&#xff0c;如数据库连接信息、API 密钥、调试模式等。 安装p…

用python压缩图片大小

下载库 cmd开命令或者PyCharm执行都行 pip install pillow2. 然后就是代码 from PIL import Imagedef compress_image(input_path, output_path, quality85, max_sizeNone):"""压缩图片大小。参数:- input_path: 输入图片路径- output_path: 输出图片路径- qu…

【自用记录】本地关联GitHub以及遇到的问题

最近终于又想起GitHub&#xff0c;想上传代码和项目到仓库里。 由于很早之前有在本地连接过GitHub&#xff08;但没怎么用&#xff09;&#xff0c;现在需要重新搞起&#xff08;操作忘得差不多&#xff09;。 在看教程实操的过程中遇到了一些小问题&#xff0c;遂记录一下。 前…

在一个scss文件中定义变量,在另一个scss文件中使用

_variables.scss文件 : $line-gradient-init-color: linear-gradient(90deg, #8057ff 0%, #936bff 50%, #b892ff 100%); $line-gradient-hover-color: linear-gradient(90deg, #936bff 0%, #b892ff 50%, #f781ce 100%); $line-gradient-active-color: linear-gradient(90deg, …

从零开始研发GPS接收机连载——19、自制GPS接收机的春运之旅

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 从零开始研发GPS接收机连载——19、自制GPS接收机的春运之旅 许久未曾更新这个系列&#xff0c;并非我平日里对这事儿没了兴致&#xff0c;不再愿意折腾。实则是受限于自身条…

智能驾驶功能LCC车道保持居中

画龙现象就是LCC常见bug LDW车道偏离预警 LKA车道保持 声音其实就是蜂鸣器 有些车是40 有些是60

Java全栈面试宝典:线程机制与Spring依赖注入深度解析

目录 一、Java线程核心机制 &#x1f525; 问题3&#xff1a;start()与run()的底层执行差异 线程启动流程图解 核心差异对照表 代码验证示例 &#x1f525; 问题4&#xff1a;Thread与Runnable的六大维度对比 类关系UML图 最佳实践代码 &#x1f525; 问题5&#xff1…