【论文阅读】Dolphin: Document Image Parsing via Heterogeneous Anchor Prompting

article/2025/6/6 3:05:55

Paper:https://arxiv.org/abs/2505.14059
Source code: https://github.com/bytedance/Dolphin
作者机构:字节跳动

背景

业务场景

企业数据大多数都以文本、图片、扫描件、电子表格、在线文档、邮件等文档的形式存在,例如:PDF文档(论文、财报等)、发票、收据等等,难以流通和处理,大量有价值的信息都被锁定在非结构化的文档中,无法充分发挥出数据价值,此外不同类型的文档包含的内容,以及内容展示形式也千差万别,这为非结构数据结构化进程增加了更多的不确定性和挑战。

相关工作

当前主流的文档解析主要是两个大的方向,

  1. Integration-based Document Parsing,这种解决方案整合了多个特有的模型于整个处理的pipeline中,例如:通过版面分析去识别表格,公式等,然后再使用对应的模型做相关的处理,主要的缺陷是:在系统复杂性、跨模型协调和对复杂文档布局的理解有限。
  2. Autoregressive Document Parsing,这种方案利用视觉语言模型通过自回归解码直接生成结构化的结果。其分为两种类型:
  3. General VLMs,这些模型受益于对不同视觉数据的大规模预训练,表现出强大的零样本能力。然而,它们在处理效率、专门的元素识别和布局结构保存方面经常面临挑战,特别是在处理具有复杂布局的长文档时。
  4. Expert VLMs,这些模型是专门为文档解析或理解任务设计和训练的。Dolphin就是这种类型。

方法论

该模型的处理范围是两阶段文档图像解析,如下图:
在这里插入图片描述

推理样例:
在这里插入图片描述

总得来说:主要分为两个阶段,在给定处理的文档图片后,首先(第一阶段)做page级的处理,采用的是版面分析的思想但与之不同的是其获取的是具有阅读顺序的各种类型元素结果,然后(第二阶段)做元素级的处理,并行地使用特定元素类型的prompt进行提取,由于已经得到了第一阶段的阅读顺序以及位置信息(bbox)就很容易将第二阶段的结果进行整合了。
可见思路是比较清晰的,那么需要探索的是这两个阶段的效果是否符合预期,或者是work的比较good。

Page-level layout analysis

页面级别的版面分析是如何做的?
对于输入的图片,作者使用的是Swin Transformer作为整个模型的视觉编码器。注:输入图像会被调整大小并填充到固定的 H × W,保留其纵横比以避免文本失真。
版面分析结果的生成。使用版面分析的prompt,然后解码器输出目标结果。这里会涉及视觉特征和文本特征之间的对齐。作者使用的是mBart作为解码器。最后输出的就结果就是Bounding box + element type。
附录中给出里支持的元素种类,如下:
在这里插入图片描述

Element-level Content Parsing

元素级别的内容分析又是如何做的呢?
结合各元素的类型使用各自的prompt并行地处理(这里很显然会带来更多资源的消耗,小心OOM)。使用的是各自bbox截取出当前类型的图片。
附录中也给出了对应元素类型的prompt,如下:

在这里插入图片描述

对应表格图片,模型的结果是html形式的。段落中如果包含公式,输出的结果是使用LaTeX进行表示的。

效果比对

Dolphin模型参数量在322M,并不是很大,相比于其他VLMs在体积上优势很大(就是快)。文中使用的评判指标是ED(edit distances)和FPS(frames per second)。也分别在页面级和元素级分别做了比较。
页面级的对比如下:

元素级的对比如下:

从罗列的指标上来看,在相关的测试数据指标是不错的。根据工作经验来说,在具体业务中最好还是需要做进一步测试和实验。
好了,模型的推理到此结束。下面该看看如何训这个模型的,也就是(1)如何构建训练预料;(2)如何提高小模型的指令跟随能力。

模型训练

训练数据

收集了超过3kw覆盖page-level,element-level的样本。可参见如下表格:

其在Mixed Documents中进行了具有阅读顺序的版面分析标注,即有元素类型、bbox以及阅读顺序。其它的数据主要是用于构建元素级别的提取训练语料。更多训练数据形式可参见原论文。

实验

模型层面:

  1. 视觉encoder使用的是Swin Transformer,window size:7, hierarchical structure([2, 2, 14, 2] encoder layers with [4, 8, 16, 32] attention heads),tips: 常见的通用VLM的视觉编码器通常使用的是基于vit的处理,后面对比一下其与Swin Transformer的差异;
  2. decoder使用的是mBart,包含了10个hidden dimension的Transformer layer;
  3. 使用Donut的预训练权重进行初始化。

训练:

  1. 优化器AdamW;
  2. Learning rate 5e-5 cosine decay schedule;
  3. 机器:40张A100;
  4. 2 epochs with a batch size of 16 per device (gradient accumulation)
  5. 训练Loss:cross-entripy loss。

其他:

  1. 图片进行归一化操作,将图片保留纵横比(aspect ratio),将最长的边放大或缩小到896个pixels,然后进一步padding以达到896x896 pixels 的尺寸。

总结

从文中可以看出,尽管Dolphin表现出了出色的性能,但仍有一些限制需要进一步改进。首先,Dolphin主要支持标准水平文本布局,对于垂直文本如古代手稿等的支持有限。其次,虽然Dolphin能够有效地处理中英双语文档,但其多语言能力仍需扩展。此外,虽然Dolphin通过并行元素解析实现了效率提升,但在文本行和表格单元格的并行处理方面仍有优化空间。最后,Dolphin的手写识别能力还需要进一步增强。
此外,由于文档的多样性和复杂性,还需要在工业界进行考验。项目也提供了在线试用的地址:http://115.190.42.15:8888/dolphin/。

对于类似的端到端的文档智能多模态模型还有如:GOT、SmolDocling等专门处理文档的多模态(大)语言模型。这些模型和方法为端到端的文档智能智能提供了很多解决思路,为后续的发展奠定了基础,但个人试用起来,感觉整体效果还需有进一步提升。


http://www.hkcw.cn/article/ZccQjpoiDd.shtml

相关文章

WPS 利用 宏 脚本拆分 Excel 多行文本到多行

文章目录 WPS 利用 宏 脚本拆分 Excel 多行文本到多行效果需求背景🛠 操作步骤代码实现代码详解使用场景注意事项总结 WPS 利用 宏 脚本拆分 Excel 多行文本到多行 在 Excel 工作表中,我们经常遇到一列中包含多行文本(用换行符分隔&#xff…

STM32外部中断(EXTI)以及旋转编码器的简介

一、外部中断机制概述 中断是指当主程序执行期间出现特定触发条件(即中断源)时,CPU将暂停当前任务,转而执行相应的中断服务程序(ISR),待处理完成后恢复原程序的运行流程。该机制通过事件驱动…

【Unity开发】控制手机移动端的震动

🐾 个人主页 🐾 阿松爱睡觉,横竖醒不来 🏅你可以不屠龙,但不能不磨剑🗡 目录 一、前言二、Unity的Handheld.Vibrate()三、调用Android原生代码四、NiceVibrations插件五、DeviceVibration插件六、控制游戏手…

ES101系列07 | 分布式系统和分页

本篇文章主要讲解 ElasticSearch 中分布式系统的概念,包括节点、分片和并发控制等,同时还会提到分页遍历和深度遍历问题的解决方案。 节点 节点是一个 ElasticSearch 示例 其本质就是一个 Java 进程一个机器上可以运行多个示例但生产环境推荐只运行一个…

RabbitMQ在SpringBoot中的应用

1.简单模式 P:生产者,要发送消息的程序. C:消费者,消息的接收者. Queue:消息队列,类似于一个邮箱,生产者向其中投递消息,消费者从其中取出消息. 特点:一个生产者P,一个消费者C,消息只能被消费一次,也成为点对点模式. 适用场景:消息只能被单个消费者处理. 设置队列的名称为…

基于python写的目录/文件递归检索工具

核心功能 1. 目录结构检索 递归扫描 :深度遍历指定目录及其所有子目录 多种检索模式 : 仅文件夹模式:只显示目录结构仅文件模式:只显示文件列表文件文件夹模式:完整显示目录树结构(默认模式) …

Qwen3高效微调

高效微调 场景、模型、数据、算力 高效微调的应用场景 对话风格微调:高效微调可以用于根据特定需求调整模型的对话风格。例如,针对客服系统、虚拟助理等场景,模型可以通过微调来适应不同的 语气、礼貌程度 或 回答方式,从而在与…

不动产登记区块链系统(Vue3 + Go + Gin + Hyperledger Fabric)

好久没有介绍过新项目的制作了,之前做的一直都是Fisco Bcos的项目,没有介绍过Hyperledger Fabric的项目,这次来给大家分享下。 系统概述 不动产登记与交易平台是一个基于Hyperledger Fabric的综合性管理系统,旨在实现不动产登记…

深度学习学习率调度器指南:PyTorch 四大 scheduler 对决

在深度学习模型训练中,学习率调度器(Learning Rate Scheduler)是影响模型收敛效果和训练稳定性的关键因素。选择合适的学习率调度策略,往往能让模型性能产生质的飞跃。本文将深入对比PyTorch中最常用的四种学习率调度器&#xff0…

ERP学习-AP

业务需要。持续更新学习进度 借助网上零搭建平台上手实操 这个是简道云平台页面链接,登录的化去手机号登录 目前开始对应付模块进行学习

基于 ZYNQ UltraScale+ OV5640的高速图像传输系统设计,支持国产替代

引 言 随着电子信息技术的不断进步,人工智能、医 疗器械、机器视觉等领域都在高速发展 [1] ,工业相机 是机器视觉系统中的一部分 [2] ,对工业相机而言,传 输图像的速率、传输过程的抗干扰能力是其关键, 工业相…

smartGit 试用突破30天

1 下载 选择19.1版本 2 运行 我是linux环境 解压后, cd bin ./smartgit.sh 选择使用30天. 然后退出 3 绿色软件 破解步骤 下载破解文件:访问 Gitee 链接 goto下载下载破解文件 解压文件:下载后解压得到 crackSmartGit.jar 和 license.zip 用编辑…

一、基础环境配置

一、虚拟机 主:192.168.200.200 从:192.168.200.201 从:192.168.200.202 二、docker docker基础搭建,有不会的自行百度。 1.目录结构 /opt/software:软件包/opt/module:解压包,自定义脚本…

Java面试八股--08-数据结构和算法篇

1、怎么理解时间复杂度和空间复杂度 时间复杂度和空间复杂度一般是针对算法而言,是衡量一个算法是否高效的重要标准。先纠正一个误区,时间复杂度并不是算法执行的时间,在纠正一个误区,算法不单单指冒泡排序之类的,一个…

Oracle中的循环——FOR循环、WHILE循环和LOOP循环

目录 一、FOR循环 1.FOR循环语法结构 二、WHILE循环 1.WHILE循环语法结构 三、LOOP循环 1.LOOP循环语法结构 四、三个循环的区别(重要) Oracle中的循环常用的有:FOR循环、WHILE循环和LOOP循环 一、FOR循环 1.FOR循环语法结构 DECLARE --不声明变量&…

ubuntu 20.04挂载固态硬盘

我们有个工控机,可以接入一个固态硬盘。将固态硬盘插好后,就要进行挂载。在AI的指导下,过程并不顺利。记录如下: 1、检查硬盘是否被识别 安装好硬盘后,运行以下命令来检查Linux系统是否已识别新硬盘: …

SAP 自动编号的使用

1、NUMBER_RANGE_ENQUEUE用于锁定编号范围对象,防止多用户并发访问冲突 2、NUMBER_RANGE_DEQUEUE用于解锁已维护的编号范围对象。 3、此外,还提到了NUMBER_GET_NEXT函数模块,用于获取编号范围内的下一个号码。 文章目录 创建编号范围程序实现…

Python趣学篇:从零打造智能AI井字棋游戏(Python + Tkinter + Minimax算法)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《Python星球日记》 目录 🎮 前言一、项目概述与技术…

[定昌linux开发板]设置密码策略

找到etc/pam.d/目录下的common-password 2.先把common-password给复制一份,避免改错了 可以看到新增了一个common-password.bak文件 3.打开common-password,增加密码策略 输入: sudo vi /etc/pam.d/common-passwod 打开common-password文件 点击&…

Godot 敌人生成半径和围墙不匹配,导致敌人错误的生成在围墙外的解决代码

一、原视频 3. Preventing Invalid Spawning 二、原代码 func get_spawn_position():var player get_tree().get_first_node_in_group("player") as Node2Dif player null:return Vector2.ZEROvar spawn_position Vector2.ZEROvar random_direction Vector2.RIG…