落地方案:Cursor的代码库索引及文档解析中的跨页表/段落合并实现思路


落地方案:Cursor的代码库索引及文档解析中的跨页表/段落合并实现思路

仅用于站内搜索,没有排版格式,具体信息请跳转上方微信公众号内链接

今天是2025年6月29日,星期日,北京,晴
我们继续来看文档解析进展,2025年上半年已经出了很多个文档解析模型方案了,这个在专题中有介绍过许多。
那么,还可以继续做什么差异性?
那就是往后面做,考虑跨页表/段落合并问题差异性,也就是做下合并场景,这个在文档恢复场景中先的更为重要,当前的开源方案比较简单,都是逐页处理,并将各个页面的结果连接起来,而不考虑其逻辑连续性,或者写一些规则。
例如这个图里面的多列合并问题、跨页表格等。
所以可以往后走一下,做成模型,分成检测和合并两个子任务,看下具体怎么做。
另一个是,还是看代码RAG,看看Cursor的代码库索引思路,其中提到的Merkle树。
文档解析方向目前逐步走向差异化,在完成每个部件之间的拆解(检测)和解析之后,还需要进行拼接操作。
所以,也可以看看这方面的新工作,看看文档文档智能进展,PDF转markdown新轮子,ocrflux,为什么要说这个,这个有点差异性,模型支持跨页表合并和跨页段落合并
1、ocrflux方案介绍
ocrflux,3B参数,基于的QWEN2. 5-VL-3B-Instruct微调,目前这类工作很多,所以还是要看差异性,根据官方描述,模型亮点是原生支持多页文档解析,自动检测和合并跨页面元素以生成连贯文档结构,可以从跨页面的拆分对应物中重建完整的表格。
也就是在这个prompt的结果后面,再进行段落合并和表格合并。
在训练数据上,训练数据包括110万页金融和学术文件,以及25w的OLMOCR-MIX-0225数据,在效果上,与7B基线模型相比,在GTX3090GPU中可实现约3倍的吞吐量。在训练架构上,仅使用页面图像作为输入。
看下详细的介绍地址,相关信息如下:
技术博客在https ://ocrflux. pdfparser.io/#/blog;
项目主页在https ://github. com/chatdoc-com/OCRFlux;
模型权重在https ://huggingface. co/ChatDOC/OCRFlux-3B;
2、跨页段落及表格的合并问题?
为什么要做这个,因为PDF文档通常带有分页,这常常导致表格或段落被拆分到连续的页面中,准确检测并合并此类跨页面结构对于避免生成不完整或碎片化的内容至关重要。
那么,具体怎么做?那就做成一个模型如何?最直接的方式,就是训练一个模型,以两个拆分的表格碎片作为输入,并生成一个完整的、结构良好的表格作为输出。
可以建模为两个任务,一个是检测任务,一个是合并任务。
其中:
对于检测任务,给定两个连续页面的Markdown(每个页面都构建为Markdown元素列表(例如,段落和表格)),目标是识别应跨页面合并的元素的索引。
例如,其实现很简单,就是通过prompt控制:
对于合并任务,如果要合并的元素是段落,可以直接将它们连接起来。但是,对于两个表格碎片,它们的合并更具挑战性,例如,跨越多页的表格会在第二页重复第一页的页眉。
另一个困难的情况是表格单元格包含较长的内容,这些内容在单元格内跨越多行,前几行出现在上一页,而其余行则延续到下一页,有一些包含大量列的表格被垂直拆分并放置在连续两个页面上的情况。
同样的,这个模型处理也很简单,直接通过prompt进行提示控制(段落直接写规则就好,如上面说的):
看下训练细节:在训练中使用了大约450,000个样本用于检测任务,以及100,000个样本用于合并任务,针对这两个任务,分别训练单页面解析和跨页面合并任务,而是在同一个多模态LLM中使用不同的提示进行联合训练。
3、在跨页段落及表格的合并问题上可用的两个评估基准
这个项目提供了两个评测基准。

4、在实际落地中需要考虑的点
但是,一般来讲,直接写规则拼接即可,再加一个模型做其实会很慢,所以,最合适的方式,其实是加一个开关进行控制,例如,这个项目中,设置–skip_cross_page_merge跳过解析过程中的跨页面合并来加速,会简单地将各个页面的解析结果拼接起来生成最终的Markdown文档。
此外,在部署侧,最新的NVIDIAGPU(在RTX3090、4090、L40S、A100、H100上测试),至少具有12GB的GPURAM,20GB可用磁盘空间。
最后,具体结果如何,其实还得看具体测试,很多评估结果都是相对的,并且可信度、一般性都会严格可信,可用,可借鉴,对于我们而言,最重要的是知道其实现的技术思路和想解决的问题。

那么具体怎么做的?
1、Merkle树
Merkle树是一种树形结构,其中每个“叶”节点都标记有数据块的加密哈希值,每个非叶节点都标记有其子节点标签的加密哈希值,这种结构创建了一个分层结构。
每一块数据(比如一个文件)都有其独特的指纹(哈希值);成对的指纹被组合并赋予一个新的指纹;这个过程一直持续,直到你只剩下一个主指纹(根哈希值)。
2、具体怎么做的树构建?
Cursor首先在本地将代码库文件分割成语义上有意义的块,启用代码库索引时,Cursor会扫描编辑器中打开的文件夹,并计算所有有效文件的哈希值的Merkle树。

但是,还是老问题,代码库索引的有效性在很大程度上取决于代码是如何被分割的。
简单的方法会按字符、单词或行来分割代码,但它们往往会错过语义边界,从而导致嵌入质量下降。
一个更有效的方法是使用一个理解代码结构的智能分割器,例如使用高级分隔符(如类和函数定义)在适当的语义边界处分割代码。
这个就是我们在前面文章中所述的,
《代码类型的RAG做chunk切分怎么做?兼看改进AST方案》(https ://mp. weixin.qq. com/s/N7C-1IRgJYZyyNYiFexC2Q)
基于代码的抽象语法树(AST)结构来分割代码。通过深度优先遍历AST,它将代码分割成适合标记限制的子树。为了避免创建过多的小块,只要不超过标记限制,就会将兄弟节点合并成更大的块。

此外,为了在仍然允许基于路径的过滤的同时保持隐私,Cursor会为每个向量存储一个混淆的相对文件路径。
1、https ://read. engineerscodex.com/p/how-cursor-indexes-codebases-fast
2、https ://ocrflux. pdfparser.io/#/blog
老刘,NLP开源爱好者与践行者,主页:https ://liuhuanyong. github.io。
对大模型&知识图谱&RAG&文档理解感兴趣,并对每日早报、老刘说NLP历史线上分享、心得交流等感兴趣的,欢迎加入社区,社区持续纳新。
加入社区方式:关注公众号,在后台菜单栏中点击会员社区加入。


文章作者: ZejunCao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ZejunCao !
  目录