RAG基建之PDF解析的“无OCR”魔法之旅

PDF文件转换成其他格式常常是个大难题,大量的信息被锁在PDF里,AI应用无法直接访问。如果能把PDF文件或其对应的图像转换成结构化或半结构化的机器可读格式,那就能大大缓解这个问题,同时也能显著增强人工智能应用的知识库。

嘿,各位AI探险家们!今天我们将踏上了一段奇妙的PDF解析之旅,探索了那些不用OCR(光学字符识别)也能搞定PDF的神奇小模型。就像哈利·波特不用魔杖也能施法一样,这些小模型用神经网络直接“读懂”PDF,省去了繁琐的OCR步骤,简直是AI界的“无杖魔法”!

RAG(Retrieval-Augmented Generation)基建之PDF解析的“魔法”与“陷阱”

文章目录

    • 概述
  • 详细介绍
    • Donut
      • 编码器
      • 训练
      • 微调
    • Nougat
      • 模型架构
      • 训练数据集的构建
    • Pix2Struct
      • 模型架构
      • 预训练任务
      • 预训练数据集
      • 微调
    • 一丝感悟
      • 关于预训练任务
      • 关于预训练数据
      • 关于性能
      • 基于流水线 vs. OCR-Free
      • OCR-Free小型模型方法的局限性
    • 结论

概述

之前介绍的基于流水线的PDF解析方法主要使用OCR引擎进行文本识别。然而,这种方法计算成本高,对语言和文档类型的灵活性较差,且OCR错误可能影响后续任务。

因此,应该开发OCR-Free方法,如图1所示。这些方法不显式使用OCR来识别文本,而是使用神经网络隐式完成任务。本质上,这些方法采用端到端的方式,直接输出PDF解析结果。在这里插入图片描述
OCR-Free vs. 流水线:谁更香?
从结构上看,OCR-Free方法比基于流水线的方法更简单。OCR-Free方法主要需要注意的方面是模型结构的设计和训练数据的构建。OCR-Free方法虽然一步到位,避免了中间步骤的“损耗”,但它的训练和推理速度有点慢,像是一辆豪华跑车,虽然性能强大,但油耗高。而基于流水线的方法则像是一辆经济型小车,虽然步骤多,但每个模块都很轻量,适合大规模部署。

接下来,我们将介绍几种具有代表性的OCR-Free小型模型PDF解析框架:

    1. Donut:PDF解析界的“甜甜圈”
      Donut这个小家伙,别看它名字甜,干起活来可是一点都不含糊。它用Swin Transformer当“眼睛”,BART当“嘴巴”,直接把PDF图像“吃”进去,吐出一串JSON格式的“甜点”。不用OCR,全靠神经网络,简直是PDF解析界的“甜品大师”!
    1. Nougat:PDF解析界的“牛轧糖”
      Nougat,名字听起来就很有嚼劲,它的绝活是把PDF图像变成Markdown。它特别擅长处理复杂的公式和表格,简直是PDF解析界的“糖果工匠”。不过,它的生成速度有点慢,像牛轧糖一样,嚼起来需要点耐心。
    1. ** Pix2Struct:PDF解析界的“像素魔法师”**
      Pix2Struct是个视觉语言理解的高手,它的任务是从屏蔽的网页截图中预测HTML解析。它不仅能处理PDF,还能搞定网页截图,简直是多才多艺的“像素魔法师”。不过,它的训练数据来自网页,可能会带来一些“有害内容”,使用时得小心点。

详细介绍

Donut

如图2所示,Donut是一个端到端模型,旨在全面理解文档图像。其架构简单,由基于Transformer的视觉编码器和文本解码器模块组成。在这里插入图片描述

Donut不依赖任何与OCR相关的模块,而是使用视觉编码器从文档图像中提取特征,并直接使用文本解码器生成token序列。输出序列可以转换为JSON等结构化格式。

代码如下:

class DonutModel(PreTrainedModel):r"""Donut: 一个端到端的OCR-Free文档理解Transformer。编码器将输入的文档图像映射为一组嵌入,解码器预测所需的token序列,可以将其转换为结构化格式,给定提示和编码器输出的嵌入"""config_class = DonutConfigbase_model_prefix = "donut"def __init__(self, config: DonutConfig):super().__init__(config)self.config = configself.encoder = SwinEncoder(input_size=self.config.input_size,align_long_axis=self.config.align_long_axis,window_size=self.config.window_size,encoder_layer=self.config.encoder_layer,name_or_path=self.config.name_or_path,)self.decoder = BARTDecoder(max_position_embeddings=self.config.max_position_embeddings,decoder_layer=self.config.decoder_layer,name_or_path=self.config.name_or_path,)def forward(self, image_tensors: torch.Tensor, decoder_input_ids: torch.Tensor, decoder_labels: torch.Tensor):"""给定输入图像和所需的token序列计算损失,模型将以教师强制的方式进行训练参数:image_tensors: (batch_size, num_channels, height, width)decoder_input_ids: (batch_size, sequence_length, embedding_dim)decode_labels: (batch_size, sequence_length)"""encoder_outputs = self.encoder(image_tensors)decoder_outputs = self.decoder(input_ids=decoder_input_ids,encoder_hidden_states=encoder_outputs,labels=decoder_labels,)return decoder_outputs......

编码器

Donut使用Swin-Transformer作为图像编码器,因为它在初步的文档解析研究中表现出色。该图像编码器将输入的文档图像转换为一组高维嵌入。这些嵌入将作为文本解码器的输入。

对应代码如下:

class SwinEncoder(nn.Module):r"""基于SwinTransformerDonut编码器使用预训练的SwinTransformer设置初始权重和配置,然后修改详细配置作为Donut编码器参数:input_size: 输入图像大小(宽度,高度)align_long_axis: 如果高度大于宽度,是否旋转图像window_size: SwinTransformer的窗口大小(=patch大小)encoder_layer: SwinTransformer编码器的层数name_or_path: 预训练模型名称,要么在huggingface.co.注册,要么保存在本地。否则,将设置为`swin_base_patch4_window12_384`(使用`timm`)。"""def __init__(self,input_size: List[int],align_long_axis: bool,window_size: int,encoder_layer: List[int],name_or_path: Union[str, bytes, os.PathLike] = None,):super().__init__()self.input_size = input_sizeself.align_long_axis = align_long_axisself.window_size = window_sizeself.encoder_layer = encoder_layerself.to_tensor = transforms.Compose([transforms.ToTensor(),transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD),])self.model = SwinTransformer(img_size=self.input_size,depths=self.encoder_layer,window_size=self.window_size,patch_size=4,embed_dim=128,num_heads=[4, 8, 16, 32],num_classes=0,)self.model.norm = None# 使用swin初始化权重if not name_or_path:swin_state_dict = timm.create_model("swin_base_patch4_window12_384", pretrained=True).state_dict()new_swin_state_dict = self.model.state_dict()for x in new_swin_state_dict:if x.endswith("relative_position_index") or x.endswith

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

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

相关文章

二层框架组合实验

实验要求: 1,内网IP地址使用172.16.0.0/16分配 2,SW1和sw2之间互为备份 3,VRRP/STP/VLAN/Eth-trunk均使用 4,所有PC均通过DHCP获取IP地址 5,ISP只能配置IP地址 6,所有电脑可以正常访问ISP路由器环回 实验思路顺序: 创建vlan eth-trunk 划分v…

光纤耦合器

以下是关于光纤耦合器的详细介绍: 定义与原理 - 定义:光纤耦合器是一种能使传输中的光信号在特殊结构的耦合区发生耦合,并进行再分配的器件,也叫分歧器、连接器、适配器、光纤法兰盘。 - 原理:利用不同光纤面紧邻光纤芯…

惠普(HP)和联想(Lenovo)作为全球两大电脑品牌,并不是简单的“拼接电脑”

惠普(HP)和联想(Lenovo)作为全球两大电脑品牌,并不是简单的“拼接电脑”,它们都有自己的核心技术、专利设计和生态体系。以下是它们“自己的”核心部分: 1. 关键自研技术 品牌自研技术/专利说明…

若依赖前端处理后端返回的错误状态码

【背景】 后端新增加了一个过滤器,用来处理前端请求中的session 若依赖存放过滤器的目录:RuoYi-Vue\ruoyi-framework\src\main\java\com\ruoyi\framework\security\filter\ 【问题】 后端返回了一个状态码为403的错误,现在前端需要处理这…

智能的数学公式:Intelligence = Priori knowledge * Reasoning ?

爱因斯坦的相对论公式大道至简, 假如智能有公式的话,会不会是: 其中,两个影响因子分别是先验知识 和 推理能力,推理能力的指数部分可以是整数也是小数,但是暂时还不好确定。 解析:&#xff08…

简单使用LlamaIndex实现RAG

简单使用LlamaIndex实现RAG 1 介绍 LlamaIndex是一个专门为大语言模型(LLM)设计的开源数据管理工具,旨在简化和优化LLM在外部数据源中的查询过程。适合在数据索引上构建RAG。 参考的地址 # 官网地址 https://docs.llamaindex.ai/en/stabl…

Redis延时队列在订单超时未报到场景的应用补充说明

一、工具类设计要点解析 连接保活机制 Scheduled(cron "0 */10 * * * ?") 定时任务每10分钟向所有队列发送心跳消息("keepAlive"),避免云Redis因空闲断开连接。这是针对云服务商自动回收空闲连接的通用解决方案1。 泛…

理解Kubernetes中CoreDNS域名解析与DNS策略

CoreDNS是什么 CoreDNS是一个灵活可扩展的DNS服务器,使用Go语言编写,旨在提供快速、灵活的DNS服务 为什么需要CoreDNS CoreDNS为Kubernetes集群内部的DNS解析提供服务,使得服务之间能够通过域名互相通信 Kubernetes集群中, CoreDNS是运行在…

日报日报流量分析

快捷键 CtrlK,选择需要抓包的网卡 CtrlF可以进行关键字搜索 CtrlM,标记数据包 CtrlShiftN跳到标记处 查看包有多少协议Protocol Hierarchy(协议分级) 搜了一下TCP协议,是互联网最基本的协议&#xff0…

docker-Dify外接Fastgpt知识库

参考地址:https://mp.weixin.qq.com/s/crQrneHZ0sT-c04YanofSw 总体步骤 部署fda(fastgpt-dify-adapter)docker 部署dify,fastgpt在fastgpt创建open apikey,复制知识库id;在dify外接fastgpt知识库; docker安装 下载…

蓝桥杯 之 图论基础+并查集

文章目录 习题联盟X蓝桥幼儿园 图论基础 并查集 并查集,总的来说,操作分为三步初始化(每一个节点的父亲是自己),定义union(index1,index2)函数,定义find(index)函数 并查集详细内容博客 习题 联盟X 联盟X 典型的求解连通分支…

JavaScript运算符与逻辑中断

目录 JavaScript运算符 一、运算符分类与优先级 1. 运算符优先级表 二、算术运算符 1. 基础算术运算 2. 自增/自减运算符 三、比较运算符 1. 基础比较 2. 相等性判断 四、逻辑运算符 1. 基础逻辑运算 2. 短路求值(Short-Circuiting) 3. 逻辑…

Unity顶点优化:UV Splits与Smoothing Splits消除技巧

一、顶点分裂问题概述 1. 什么是顶点分裂 顶点分裂(Vertex Splits)是3D渲染中常见的性能问题,当模型需要为同一顶点位置存储不同属性值时,会创建多个顶点副本。主要分为两类: UV Splits:由UV不连续引起 Smoothing Splits&#…

OpenCV、YOLO与大模型的区别与关系

OpenCV、YOLO 和大模型的区别与关系 1. OpenCV(Open Source Computer Vision Library) 定位:开源的计算机视觉基础库。功能:提供传统的图像处理算法(如图像滤波、边缘检测、特征提取)和基础工具&#xff…

CentOS 7 挂载与卸载文件系统笔记

挂载文件系统 挂载的基本概念 挂载是将存储设备(如硬盘分区、U 盘、光盘等)连接到 Linux 文件系统的特定目录(挂载点),使得系统能够访问存储设备上的数据。 查看已挂载的文件系统 命令:mount 或 df -h mo…

Git项目要改变仓库地址

去掉原仓库git地址和清除原项目的git版本信息的方法 场景需求: 如果是使用自己以前的项目、或者拉取了别人的项目到自己本地。想在此基础上重新开发、初始化项目的话,最好先删掉以前的git信息。 因为如果不删除的话: 1.看着不舒服。根本不需要保留原来的版本信息。 2.我们…

NC,GFS、ICON 数据气象信息可视化--降雨量的实现

随着气象数据的快速发展和应用,气象信息的可视化成为了一项不可或缺的技术手段。它不仅能帮助气象专家快速解读数据,还能为公众提供直观的天气预报信息。今天,我们将从降雨量的可视化出发,带大家一起了解如何实现气象数据的可视化…

质量工程师的2025:从“找bug“到“造质量“的职业进化

想象一下,2025年的某天:阅读原文 早晨,AI测试助手已经自动运行了夜间回归测试,并将可疑问题标记出来 你喝着咖啡,通过质量数据看板分析系统健康度 下午的会议上,你正用业务语言向产品经理解释&#xff1a…

Python实现将字典中键相同的值合并

在Python字典中键是唯一的,但是业务需求是将不同的数据传递到不同的接口,接口列表中存在3个相同的接口,需要将3个接口对应的数据合并一同发送,逻辑实现如下 merge_dict {}for file in files:path os.path.join(folder_path, fil…

数据大屏点亮工业互联网的智慧之眼

在当今数字化飞速发展的时代,数据已成为企业决策的核心依据,而数据大屏作为数据可视化的重要工具,正逐渐成为工业互联网领域不可或缺的一部分。通过直观、动态的可视化展示,数据大屏能够将复杂的数据转化为易于理解的图表和图形&a…