简介
在不断发展的自然语言处理和人工智能领域中,从科学PDF等非结构化数据源中提取有价值的信息变得越来越重要。为了解决这个挑战,Meta AI推出了“Nougat”或称“学术文档的神经光学理解”,这是一种基于Transformer的先进模型,旨在将科学PDF转录成常见的Markdown格式。Nougat出现在Lukas Blecher、Guillem Cucurull、Thomas Scialom和Robert Stojnic的论文《Nougat:学术文档的神经光学理解》中。
这为光学字符识别(OCR)技术带来了开创性的转变,而Nougat是Meta AI强大的AI模型中的最新成员。在本文中,我们将探讨Nougat的能力,了解它的架构,并演示使用该模型转录科学文档的实际示例。
学习目标
- 了解Meta AI最新的科学文档Transformer模型Nougat。
- 了解Nougat如何借鉴其前身Donut,并引入先进的文档AI方法。
- 学习Nougat,包括其视觉编码器、文本解码器和端到端训练过程。
- 深入了解OCR技术的发展,从ConvNets的早期阶段到Swin架构和自回归解码器的革命性能量。
本文作为数据科学博文马拉松的一部分发表。
Nougat的诞生
Nougat并不是Meta AI家族中的第一个Transformer模型。它继承了它的前身“Donut”的理念,展示了以Transformer为基础的模型中视觉编码器和文本解码器的能力。这个概念很简单:将像素数据输入模型,获得文本输出。这种端到端方法消除了复杂的流水线,并证明了注意力就是所需的一切。
让我们简要讨论驱动Nougat等模型的“视觉编码器、文本解码器”范式的基本概念。作为Nougat的前身,Donut引入了在单个模型中结合视觉和文本处理的能力。与传统的文档处理流水线不同,这些模型在端到端操作,将原始像素数据转化为文本内容。这种方法利用了Transformer架构的注意力特性来产生结果。
Nougat接过火炬
在Donut取得成功的基础上,Meta AI推出了Nougat,将OCR技术推向了一个新的水平。与其前身一样,Nougat采用了基于Swin Transformer的视觉编码器和基于mBART的文本解码器。Nougat从科学PDF的原始像素中预测文本的Markdown形式。这代表了将科学知识转录成熟悉的Markdown格式的重大突破。
Meta AI将视觉-文本范式应用于解决科学文档的挑战。虽然PDF被广泛采用,但对于机器来准确理解和提取科学知识的意义信息,往往面临困难。
PDF可能阻碍有效的知识检索,因为它们丧失了语义信息,尤其是在处理数学结构时。为了弥合这个差距,Meta AI推出了Nougat。
为什么选择Nougat?
人们传统上将科学知识存储在书籍和期刊中,通常以PDF的形式。然而,PDF格式常常导致关键的语义信息丢失,特别是在涉及数学结构时。Nougat通过对科学文档进行OCR并将其转化为标记语言来填补这个差距。这一突破实现了科学知识的收获,并消除了人机之间可读文档和机器可读文本之间的差距。
Nougat成功逆向工程OCR引擎,并依赖Transformer架构来进行复杂科技文件的转录。这为文档人工智能打开了大门。科学知识现在可以被解放并用Nougat进行处理,而它们原本被封存在PDF文件中。
OCR的发展历程
Nougat的发展过程证明了OCR技术的重要性。在20世纪80年代末期,使用卷积神经网络(ConvNets)进行OCR领域的应用是开创性的。然而,在当时的限制下,训练一个能够读取整个页面的端到端系统的想法仅仅是一个梦想。
快进到今天,结合ConvNets、transformers和自回归解码器的Swin架构使得转录整个页面成为可能。和Donut一样,Nougat遵循视觉-文本范式,它包括基于Transformer的图像编码器和自回归文本解码器。
使用Nougat:实际示例
现在我们已经了解了Nougat,让我们深入了解如何使用这个强大的模型将科学PDF转录为标准的Markdown格式的实际示例。我们将逐步讲解代码,提供解释和见解。本文的完整代码可以在这里找到:https://github.com/inuwamobarak/nougat。
设置环境
我们将安装所需的库。这些库包括pymupdf用于将PDF转换为图像,以及其他库python-Levenshtein和NLTK用于后处理任务。
!pip install -q pymupdf python-Levenshtein nltk!pip install -q git+https://github.com/huggingface/transformers.git
加载模型和处理器
在这一步中,我们将加载Nougat模型及其关联的处理器,为将PDF转录准备模型。
from transformers import AutoProcessor, VisionEncoderDecoderModelimport torch# 从预置模型中加载Nougat模型和处理器processor = AutoProcessor.from_pretrained("facebook/nougat-small")model = VisionEncoderDecoderModel.from_pretrained("facebook/nougat-small")
让我们管理内存资源。
%%capturedevice = "cuda" if torch.cuda.is_available() else "cpu"model.to(device)
现在我们继续进行下一步,编写将PDF转换为光栅化的函数。
from typing import Optional, Listimport ioimport fitzfrom pathlib import Pathdef rasterize_paper( pdf: Path, outpath: Optional[Path] = None, dpi: int = 96, return_pil=False, pages=None,) -> Optional[List[io.BytesIO]]: """ 将PDF文件光栅化为PNG图像。 Args: pdf (Path): PDF文件的路径。 outpath (Optional[Path], optional): 输出目录。如果为None,则返回PIL图像。默认为None。 dpi (int, optional): 输出DPI。默认为96。 return_pil (bool, optional): 是否返回PIL图像而不是写入到磁盘。默认为False。 pages (Optional[List[int]], optional): 需要光栅化的页码。如果为None,则光栅化所有页。默认为None。 Returns: Optional[List[io.BytesIO]]: 如果return_pil为True,则返回PIL图像,否则返回None。 """ pillow_images = [] if outpath is None: return_pil = True try: if isinstance(pdf, (str, Path)): pdf = fitz.open(pdf) if pages is None: pages = range(len(pdf)) for i in pages: page_bytes: bytes = pdf[i].get_pixmap(dpi=dpi).pil_tobytes(format="PNG") if return_pil: pillow_images.append(io.BytesIO(page_bytes)) else: with (outpath / ("%02d.png" % (i + 1))).open("wb") as f: f.write(page_bytes) except Exception: pass if return_pil: return pillow_images
加载PDF
在这一步中,我们加载一个示例PDF并使用fitz模块将其转换为一系列的Pillow图像,每个图像代表PDF的一页。我们将使用Crouse et al. 2023的PDF。
from huggingface_hub import hf_hub_downloadfrom typing import Optional, Listimport ioimport fitzfrom pathlib import Pathfrom PIL import Imagefilepath = hf_hub_download(repo_id="inuwamobarak/random-files", filename="2310.08535.pdf", repo_type="dataset")images = rasterize_paper(pdf=filepath, return_pil=True)image = Image.open(images[0])image
生成转录
在这一步骤中,我们准备将图像输入到Nougat模型中。自定义停止标准以控制自回归生成过程。这些标准确定模型应何时停止生成文本。
pixel_values = processor(images=image, return_tensors="pt").pixel_values
from transformers import StoppingCriteria, StoppingCriteriaListfrom collections import defaultdictclass RunningVarTorch: def __init__(self, L=15, norm=False): self.values = None self.L = L self.norm = norm def push(self, x: torch.Tensor): assert x.dim() == 1 if self.values is None: self.values = x[:, None] elif self.values.shape[1] < self.L: self.values = torch.cat((self.values, x[:, None]), 1) else: self.values = torch.cat((self.values[:, 1:], x[:, None]), 1) def variance(self): if self.values is None: return if self.norm: return torch.var(self.values, 1) / self.values.shape[1] else: return torch.var(self.values, 1)class StoppingCriteriaScores(StoppingCriteria): def __init__(self, threshold: float = 0.015, window_size: int = 200): super().__init__() self.threshold = threshold self.vars = RunningVarTorch(norm=True) self.varvars = RunningVarTorch(L=window_size) self.stop_inds = defaultdict(int) self.stopped = defaultdict(bool) self.size = 0 self.window_size = window_size @torch.no_grad() def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor): last_scores = scores[-1] self.vars.push(last_scores.max(1)[0].float().cpu()) self.varvars.push(self.vars.variance()) self.size += 1 if self.size < self.window_size: return False varvar = self.varvars.variance() for b in range(len(last_scores)): if varvar[b] < self.threshold: if self.stop_inds[b] > 0 and not self.stopped[b]: self.stopped[b] = self.stop_inds[b] >= self.size else: self.stop_inds[b] = int( min(max(self.size, 1) * 1.15 + 150 + self.window_size, 4095) ) else: self.stop_inds[b] = 0 self.stopped[b] = False return all(self.stopped.values()) and len(self.stopped) > 0
outputs = model.generate( pixel_values.to(device), min_length=1, max_length=3584, bad_words_ids=[[processor.tokenizer.unk_token_id]], return_dict_in_generate=True, output_scores=True, stopping_criteria=StoppingCriteriaList([StoppingCriteriaScores()]),)
后处理
最后,我们将生成的标记ID解码为可读的人类文本,并应用后处理步骤来完善生成的Markdown内容。最终输出表示科学PDF的转录内容。
generated = processor.batch_decode(outputs[0], skip_special_tokens=True)[0]generated = processor.post_process_generation(generated, fix_markdown=False)print(generated)
生成的输出以Markdown形式呈现:
这就是如何使用Nougat进行推理的方式。将这些文本标记组合在一起非常容易。您可以在此处找到本文的完整代码:https://github.com/inuwamobarak/nougat。文章末尾还有其他链接可供参考。
绩效指标
一系列的指标被用来评估Nougat在测试集上的表现。这些指标提供了对Nougat在将科学PDF转录为Markdown格式方面能力的全面视角。
编辑距离
编辑距离(Levenshtein距离)量化将一个字符串改变为另一个字符串所需的字符数。它包括插入、删除和替换。使用归一化的编辑距离评估Nougat,将计算得到的距离除以字符总数。此指标提供了关于Nougat如何准确转录内容的洞察,考虑到科学文档的复杂性。
BLEU分数
这是一个最初用于评估机器翻译质量的指标,BLEU(双语评估替代方案)指标对齐了Nougat生成的候选文本与参考文本之间的内容。它根据两个文本之间匹配的n-gram数量计算得分。这显示了Nougat如何捕捉原始内容和n-gram相似性的本质。
METEOR分数
METEOR是另一个重要的机器翻译指标,它注重召回而非精确度。虽然它不是OCR评估的常规选择,但它提供了关于Nougat保留核心内容和源材料的独特视角。与BLEU一样,METEOR有助于评估转录文本的质量。
F-度量值
F1分数结合了Nougat转录的精确度和召回率。它是对模型性能的平衡观点,准确地衡量了其捕捉内容和保留有意义信息的能力。
Nougat在学术文件之外的潜在应用
虽然Nougat最初是用于转录学术文件的,但它的应用领域远不止于此。以下是Nougat可以产生重要影响的一些潜在领域:
医疗文件
Nougat可以用于转录医疗记录和临床笔记。这有助于数字化医疗信息和医务人员的信息检索。
法律文件
法律文件、合同和法庭文件通常以PDF格式存在。Nougat可以促进这些文件转换为可机器读取的文本,简化法律流程和研究。
特定领域
Nougat的适应性使其可以在工程、金融等专门领域中使用。它可以转换技术报告、财务报表和其他领域特定文档。
Nougat是文档AI的里程碑,是将科学PDF转录为可机器读取的Markdown格式的实用高效解决方案。它对文档AI的贡献展示了信息检索更高效的未来。
科学文本识别的未来
Nougat始终在VisionEncoderDecoder中使用,模仿Donut的架构。图片被输入模型,Nougat的VisionEncoderDecoder自动生成文本。NougatImageProcessor类处理图像预处理,NougatTokenizerFast将生成的目标标记解码为目标字符串。NougatProcessor结合这些类进行特征提取和标记解码。
这一能力是前沿的,很快将更加适应。Nougat代表文档AI。将科学PDF转录为可机器读取的Markdown格式的解决方案。随着这个模型的持续发展,它有潜力在研究人员和学术界与科学文献互动的方式上产生革命性的影响,使知识在数字时代更加方便获取和利用。
结论
Nougat不仅是Meta AI家族的甜美补充品,也是科学文件OCR领域的一次革命性进步。它将复杂的PDF转换为Markdown文本的能力对于获取科学知识来说是一个改变游戏规则的举措。随着技术的不断发展,Nougat的影响将在人工智能、文档处理等领域产生共鸣。
在一个获取知识至关重要的世界中,Nougat是一个强大的工具,用于解锁存储在科学PDF中的丰富信息,架起了人类可阅读文档和机器可读文本之间的桥梁。它对文档AI的贡献展示了一个信息检索更加高效的未来。
主要要点
- Nougat 是 Meta AI 的尖端 OCR 模型,可将科学 PDF 转录为用户友好的 Markdown 格式。
- 该模型结合了 Swin Transformer 视觉编码器和基于 mBART 的文本解码器,使其能够端到端地工作。
- 它展示了 Transformer 架构在简化复杂任务如科学文档转录方面的作用。
- OCR 技术的演变,从早期的 ConvNets 到现代的 Swin 架构和自回归解码器,为 Nougat 的功能铺平了道路。
常见问题
参考链接
- https://huggingface.co/facebook/nougat-base
- https://github.com/NielsRogge/Transformers-Tutorials/
- https://github.com/inuwamobarak/nougat
- https://arxiv.org/abs/2310.08535
- https://arxiv.org/abs/2308.13418
- https://huggingface.co/datasets/inuwamobarak/random-files
- https://huggingface.co/spaces/ysharma/nougat
此文章中显示的媒体不归 Analytics Vidhya 所有,由作者自行决定。