&amp 增强PDF解析并结构化技术路途打算及思绪 RAG增强之路 文档自动 RAG

  • 电脑网络维修
  • 2024-11-14

前言

现阶段,虽然大模型在生成式问答上取得了很大的成功,但因为大局部的数据都是私有数据,大模型的训练及微调老本十分高,RAG的方式逐渐成为落地运行的一种关键的选用方式。但是,如何准确的对文档启动划分chunks,成为一种应战,在事实中,大局部的专业文档都是以 PDF 格局存储,低精度的 PDF 解析会清楚影响专业常识问答的成果。因此,本文将引见针对pdf,引见一些pdf结构化技术链路供参考。

一、可编辑文档

1.1 语义分段

经pdf解析工具后,原始文档的段落消息所有失落,须要启动段落的划分和重组。上方引见一种语义分段模型的训练思绪和一种开源的分段模型。

from modelscope.outputs import OutputKeysfrom modelscope.pipelines import pipelinefrom modelscope.utils.constant import Tasksp = pipeline(task=Tasks.document_segmentation,model='damo/nlp_bert_document-segmentation_chinese-base')result = p(documents='移动端语音唤醒模型,检测关键词为“小云小云”。模型主体为4层FSMN结构,经常使用CTC训练准绳,参数量750K,实用于移动端设施运转。模型输入为Fbank特色,输入为基于char建模的中文选集token预测,测试工具依据每一帧的预测数据启动后处置获取输入音频的实时检测结果。模型训练驳回“basetrain + finetune”的形式,basetrain环节经常使用少量外部移动端数据,在此基础上,经常使用1万条设施端录制宁静场景“小云小云”数据启动微调,获取最终面向业务的模型。后续用户可在basetrain模型基础上,经常使用其余关键词数据启动微调,获取新的语音唤醒模型,但临时未开明模型finetune配置。')print(result[OutputKeys.TEXT])# 输入'''移动端语音唤醒模型,检测关键词为“小云小云”。模型主体为4层FSMN结构,经常使用CTC训练准绳,参数量750K,实用于移动端设施运转。模型输入为Fbank特色,输入为基于char建模的中文选集token预测,测试工具依据每一帧的预测数据启动后处置获取输入音频的实时检测结果。模型训练驳回“basetrain + finetune”的形式,basetrain环节经常使用少量外部移动端数据,在此基础上,经常使用1万条设施端录制宁静场景“小云小云”数据启动微调,获取最终面向业务的模型。后续用户可在basetrain模型基础上,经常使用其余关键词数据启动微调,获取新的语音唤醒模型,但临时未开明模型finetune配置。'''

二、可编辑文档(扫描件)

2.1 版面剖析

版面剖析指的是对图片方式的文档(扫描件)启动 区域划分 ,经过bounding box定位其中的关键区域,如: 文字、题目、表格、图片 等,通常驳回一些CV指标检测模型启动版式剖析,如:参数量大的有:DINO等基于transformer的指标检测模型;参数量小的有MaskRCNN、YOLO系列等。

版式剖析的长处,经过少量标注的数据,准确的划分出文档关键区域,如下:

2.2 文本识别

关于经由版式剖析划分进去的文本区域,通常驳回OCR启动相应区域的文字识别,经常出现的开源OCR识别工具备读光OCR、PaddleOCR等,以下是PaddleOCR的经常使用例子:

import cv2from paddleocr import PaddleOCRpaddleocr = PaddleOCR(lang='ch', show_log=False, enable_mkldnn=True)img = cv2.imread('1.jpg')result = paddleocr.ocr(img)for i in range(len(result[0])):print(result[0][i][1][0])# 输入识别结果

但是,像paddleOCR等开源ocr方式,在实践运行中还是存在很多的疑问,如:

2.3 表格解析

关于经由版式剖析划分进去的表格区域,通常驳回表格解析模型启动解析,并转化为特定的格局,如:csv、html、markdown格局等。经常出现的开源模型有ppstructure等,如下:

import osimport cv2from paddleocr import PPStructure,save_structure_restable_engine = PPStructure(layout=False, show_log=True)save_folder = './output'img_path = 'table.jpg'img = cv2.imread(img_path)result = table_engine(img)save_structure_res(result, save_folder, os.path.basename(img_path).split('.')[0])for line in result:line.pop('img')print(line)

在实践经常使用环节中,经常出现的开源方法经常遇到的疑问就是,无法准确的对表格启动解析,这种疑问经常出现与复杂表格,尤其是表格兼并单元格时,容易解析失误,行列不对齐等。

2.4 公式解析

关于经由版式剖析划分进去的公式区域,通常驳回公式解析模型启动解析,并转化为特定的格局,如:tex等。

上方是一个经常使用LatexOCR启动公式解析的例子:

from PIL import Imagefrom pix2tex.cli import LatexOCRmodel = LatexOCR()img = Image.open('1.jpg')print(model(img))

三、阅读顺序

经上述解析后,须要依据boungding box启动排序,以便复原文档的格局消息。上方将引见一种基于规定的方法和一种基于Layoutreader模型的方法。

import numpy as npdef xy_cut(bboxes, directinotallow="x"):result = []K = len(bboxes)indexes = range(K)if len(bboxes) <= 0:return resultif direction == "x":# x firstsorted_ids = sorted(indexes, key=lambda k: (bboxes[k][0], bboxes[k][1]))sorted_boxes = sorted(bboxes, key=lambda x: (x[0], x[1]))next_dir = "y"else:sorted_ids = sorted(indexes, key=lambda k: (bboxes[k][1], bboxes[k][0]))sorted_boxes = sorted(bboxes, key=lambda x: (x[1], x[0]))next_dir = "x"curr = 0np_bboxes = np.array(sorted_boxes)for idx in range(len(sorted_boxes)):if direction == "x":# a new seg pathif idx != K - 1 and sorted_boxes[idx][2] < sorted_boxes[idx + 1][0]:rel_res = xy_cut(sorted_boxes[curr:idx + 1], next_dir)result += [sorted_ids[i + curr] for i in rel_res]curr = idx + 1else:# a new seg pathif idx != K - 1 and sorted_boxes[idx][3] < sorted_boxes[idx + 1][1]:rel_res = xy_cut(sorted_boxes[curr:idx + 1], next_dir)result += [sorted_ids[i + curr] for i in rel_res]curr = idx + 1result += sorted_ids[curr:idx + 1]return resultdef augment_xy_cut(bboxes,directinotallow="x",lambda_x=0.5,lambda_y=0.5,theta=5,aug=False):if aug is True:for idx in range(len(bboxes)):vx = np.random.normal(loc=0, scale=1)vy = np.random.normal(loc=0, scale=1)if np.abs(vx) >= lambda_x:bboxes[idx][0] += round(theta * vx)bboxes[idx][2] += round(theta * vx)if np.abs(vy) >= lambda_y:bboxes[idx][1] += round(theta * vy)bboxes[idx][3] += round(theta * vy)bboxes[idx] = [max(0, i) for i in bboxes[idx]]res_idx = xy_cut(bboxes, directinotallow=direction)res_bboxes = [bboxes[idx] for idx in res_idx]return res_idx, res_bboxesbboxes = [[58.54924774169922, 1379.6373291625, 1112.8863525390625, 1640.0870361328125],[60.1091423034668, 483.88677978515625, 1117.4927978515625, 586.197021484375],[57.687435150146484, 1098.1053466796875, 387.9796142578125, 1216.916625],[63.158992767333984, 311.2080993652344, 1116.2508544921875, 365.2145080566406],[138.85513305664062, 144.44039916992188, 845.18017578125, 198.04937744140625],[996.1032104492188, 1053.6279296875, 1126.1046142578125, 1071.3463134765625],[58.743492126464844, 634.3077392578125, 898.405029296875, 700.9544677734375],[61.35755920416, 750.6771240234375, 1051.1060791625, 850.3980712890625],[426.77691650390625, 70.69780731201172, 556.0884399414062, 109.58145141662],[997.040283203125, 903.5933227539062, 1129.2984619140625, 921.10595703125],[59.40523910522461, 1335.1563720703125, 329.7382507324219, 1357.46533203125],[568.9025268554688, 14.365530967712402, 1087.898193359375, 32.60292434692383],[998.1250610351562, 752.936279296875, 1128.435546875, 770.4116821289062],[59.6968879699707, 947.9129638671875, 601.4513549804688, 999.4548950195312],[58.91489028930664, 1049.8773193359375, 487.3372497558594, 1072.2935791625],[60.49456024169922, 902.8802490234375, 600.7571411132812, 1000.3502197265625],[60.188941955566406, 247.99755859375, 155.72970581054688, 272.1385192871094],[996.873291625, 637.3861694335938, 1128.3558349609375, 655.1572875976562],[59.74936294555664, 1272.98828125, 154.8768310546875, 1295.870361328125],[58.835716247558594, 1050.5926513671875, 481.59027099609375, 1071.966796875],[60.60163116455078, 750.1132202148438, 376.1781921386719, 771.8764038085938],[57.982513427734375, 419.16058349609375, 155.35882568359375, 444.25115966796875],[1017.0194091796875, 1336.21826171875, 1128.002197265625, 1355.67724609375],[1019.8740844726562, 486.90814208984375, 1127.482421875, 504.61767578125]]res_idx, res_bboxes = augment_xy_cut(bboxes, directinotallow="y")print(res_idx)# res_idx, res_bboxes = augment_xy_cut(bboxes, directinotallow="x")# print(res_idx)new_boxs = []for i in res_idx:# print(i)new_boxs.append(bboxes[i])print(new_boxs)
import torchfrom model import LayoutLMv3ForBboxClassificationfrom collections import defaultdictCLS_TOKEN_ID = 0UNK_TOKEN_ID = 3EOS_TOKEN_ID = 2def BboxesMasks(boxes):bbox = [[0, 0, 0, 0]] + boxes + [[0, 0, 0, 0]]input_ids = [CLS_TOKEN_ID] + [UNK_TOKEN_ID] * len(boxes) + [EOS_TOKEN_ID]attention_mask = [1] + [1] * len(boxes) + [1]return {"bbox": torch.tensor([bbox]),"attention_mask": torch.tensor([attention_mask]),"input_ids": torch.tensor([input_ids]),}def decode(logits, length):logits = logits[1: length + 1, :length]orders = logits.argsort(descending=False).tolist()ret = [o.pop() for o in orders]while True:order_to_idxes = defaultdict(list)for idx, order in enumerate(ret):order_to_idxes[order].append(idx)order_to_idxes = {k: v for k, v in order_to_idxes.items() if len(v) > 1}if not order_to_idxes:breakfor order, idxes in order_to_idxes.items():idxes_to_logit = {}for idx in idxes:idxes_to_logit[idx] = logits[idx, order]idxes_to_logit = sorted(idxes_to_logit.items(), key=lambda x: x[1], reverse=True)for idx, _ in idxes_to_logit[1:]:ret[idx] = orders[idx].pop()return retdef layoutreader(bboxes):inputs = BboxesMasks(bboxes)logits = model(**inputs).logits.cpu().squeeze(0)orders = decode(logits, len(bboxes))return ordersif __name__ == '__main__':bboxes = [[584, 0, 595, 1], [35, 120, 89, 133],[35, 140, 75, 152]]model_path = ""model = LayoutLMv3ForBboxClassification.from_pretrained()print(layoutreader(bboxes))# [1, 2, 0]

总结

本文具体引见了可编辑pdf和无法编辑pdf(扫描件)的一些开源技术打算和路途,整个技术链路是一个pipline的路途,每一个步骤都须要精细的优化。在RAG中,准确的划分chunks,须要依赖文档的版式剖析的精准性。因此,尤其是在对文档启动版面剖析时,指标检测的粒度及标签须要对落地场景启动特定的剖析,不要妄想着存在一个通用的版式剖析模型处置一切文档版式剖析疑问。

参考文献

原文链接:​ ​​ ​

  • 关注微信

本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载联系作者并注明出处:http://www.duobeib.com/diannaowangluoweixiu/5310.html

猜你喜欢

热门标签

洗手盆如何疏浚梗塞 洗手盆为何梗塞 iPhone提价霸占4G市场等于原价8折 明码箱怎样设置明码锁 苏泊尔电饭锅保修多久 长城画龙G8253YN彩电输入指令画面变暗疑问检修 彩星彩电解除童锁方法大全 三星笔记本培修点上海 液晶显示器花屏培修视频 燃气热水器不热水要素 热水器不上班经常出现3种处置方法 无氟空调跟有氟空调有什么区别 norltz燃气热水器售后电话 大连站和大连北站哪个离周水子机场近 热水器显示屏亮显示温度不加热 铁猫牌保险箱高效开锁技巧 科技助力安保无忧 创维8R80 汽修 a1265和c3182是什么管 为什么电热水器不能即热 标致空调为什么不冷 神舟培修笔记本培修 dell1420内存更新 青岛自来水公司培修热线电话 包头美的洗衣机全国各市售后服务预定热线号码2024年修缮点降级 创维42k08rd更新 空调为什么运转异响 热水器为何会漏水 该如何处置 什么是可以自己处置的 重庆华帝售后电话 波轮洗衣机荡涤价格 鼎新热水器 留意了!不是水平疑问! 马桶产生了这5个现象 方便 极速 邢台空调移机电话上门服务 扬子空调缺点代码e4是什么疑问 宏基4736zG可以装置W11吗 奥克斯空调培修官方 为什么突然空调滴水很多 乐视s40air刷机包 未联络视的提高方向 官网培修 格力空调售后电话 皇明太阳能电话 看尚X55液晶电视进入工厂形式和软件更新方法 燃气热水器缺点代码

热门资讯

关注我们

微信公众号