封面


点此进入系列专栏


有段时间没更新博客了。正好趁这个系列的第 0 章,干脆重新介绍下自己,也顺便讲讲这组文章是怎么来的。

这篇没什么知识密度,算是背景交代,随便看看就好,当个睡前读物。

如果你会点进这篇文章,大概率已经被 PDF 折磨过。那种“肉眼看着挺正常,程序一读就开始发疯”的感觉,我非常熟。

表格散成几段话,顺序莫名其妙,数字对不上位置。你一开始还会怀疑是不是自己代码写得不对,后来换了几个库、调了几轮参数,才慢慢意识到一件事:好像不是我一个人遇到这个问题。


我最早其实不是搞 PDF 的,甚至一开始也不是做互联网后端的。

读研的时候在一个偏硬件的实验室,导师是搞硬件的,实验室里有人做算法、有人画电路板、有人搞机械,写代码的只有我一个。非科班,全靠兴趣硬啃。

那会儿技术栈非常“原始”,纯 C,天天拿着飞思卡尔的板子烧程序。研究寄存器的 0 和 1 怎么配,内存是怎么翻页的,嵌入式操作系统切线程的时候是怎么在栈上保存和恢复现场的,甚至琢磨怎么用 C 去模拟面向对象。

飞思卡尔单片机开发板

现在回头看,那段时间留下的最大影响,不是某个具体技术点,而是一个习惯:我不太接受“黑箱”,总想知道它到底在干嘛。

那几年我也写了不少嵌入式相关的博客,翻译过一堆技术文档。那时候还没有 GPT 这种工具,全是人肉翻译。印象很深的是在学生宿舍,一边循环播放斗鱼上的《地下交通站》,一边对着英文文档一句一句啃。

地下交通站


毕业之后转去做互联网后端,算是一次比较大的转向。

校招那年,非科班拿了几家 offer,最后选了字节,从此开始用 Golang 写后端。顺带一提,从 C 转 Go 真的很爽,可以理解成“自带 GC 和协程的 C”,写起来非常顺。

在字节做的是一个海外 toC 的 IM 应用,主要负责账号模块和 IM 的主消息链路。业务本身相对稳定,需求不算多,反而给了我不少“自己折腾”的空间。

压测、性能分析、瓶颈定位、链路埋点、多级缓存、冷热分离……围绕高并发、高可用、可观测性那一套,基本能试的都试了一遍。那几年算是技术成长非常快的一段时间。

后来业务增长乏力,DAU 一直起不来,职业前景无望,我在字节待了三年后,开始找下一份工作。部门最终在我离开一年后也没能继续活下去。

字节工牌


真正把我拽进 PDF 解析这件事,是在后面这家公司。

2023 年底,我加入了一家百来人的 AI 小公司,开始做工程后端,技术栈也慢慢变成 Golang + Python。小公司的基建和大厂完全是两个世界,这点只有自己待过才有感觉。

在大厂,很多事情是“提个工单就行”;在这里,更多时候是你自己 ssh 上机器,kubectl apply 一堆 yaml,自己选型、自己封装、自己维护。说实话,这段经历反而让我第一次真正理解了:大厂那些看起来理所当然的基建,底下到底包了多少东西。

也是在这个阶段,我开始系统性地接触 RAG,也就是现在很常见的文档知识库构建流程:文档解析、切块、embedding、进向量库,然后给大模型做问答。

而在所有文档类型里,最难、也最常见的,恰恰就是 PDF。


一开始是金融业务线的需求,需要解析 A 股财报 PDF。不只是把文字读出来,还要求对表格里的数据做到文本行级溯源,某个数值来自哪一行哪一列,要能在原文中高亮出来。A股财报都是下图这种方方正正的表格和文字,算是比较简单的类型了。
A股财报示例
当时公司里已经有一版 PDF 解析代码,但效果不太行。页眉页脚靠文本匹配,表格识别正确率也不高,维护这块代码的同事又准备离职。另一位同事在调研各种开源方案,试了几轮都不太理想。如果这块搞不定,单子大概率就做不了了。

我参与了一点调研之后发现,这事不是“完全不可能”,而是之前的思路有点问题。于是就把这活接了下来,先通过组合几种不同的开源算法和库,在特定类型的文档上把正确率拉上去,把业务先救下来。

然后就一发不可收拾。


最早的版本,只能处理比较规整的文字版 PDF,多栏直接炸,扫描件基本没戏。后来一点点往前推,拆页面、分策略,扫描件和文字版一套方案搞定,再到后面做成异构计算架构,GPU 算子独立部署,高度配置化,一个中心服务覆盖不同业务需求。

到现在,这套 PDF 解析服务已经能覆盖大部分常见场景,在内部评测中,文本型 PDF 的解析正确率比同类开源方案高了几个点,性能也还不错。公司对外卖产品的时候,基本都会默认把这块能力一起打包出去。

当前解析效果
我自己也算是因为这件事,在公司里站稳了脚跟,拿过创业者奖,绩效也极好。
创业者奖


写这一系列文章,其实没什么宏大的目标。

只是这两年踩下来,越来越觉得:PDF 解析真正难的地方,往往不在代码,而在前面的判断。
该走哪条路线?
什么时候该换方法,而不是继续死磕?

这些东西,文档里很少写,博客里也不太有人慢慢讲。

因为公司层面没有开源实现,我也不会细讲内部代码,更多会结合开源方案和真实工程经验,把思路、边界和取舍说清楚。希望能让后来的人,少走一点弯路。

下一篇,我们就从一个最基础、也最容易被忽略的问题开始聊:

PDF,为什么这么难解析?

如果你也正在被 PDF 折磨,希望这个系列能对你有点用。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐