摘要
很多人以为 PDF 转 Markdown 很简单:把字抽出来,再套一层 Markdown 语法就完了。
但真正做过 RAG、知识库、企业文档检索的人都知道,最容易翻车的从来不是“没识别到字”,而是标题层级丢失、表格被打散、公式错乱、多栏顺序混乱、图片和正文混在一起。最后你喂给大模型的,不是知识,而是噪声。本文就用 PP-StructureV3 来讲清楚一件事:PDF 转 Markdown,本质上不是抽字,而是一项文档结构恢复任务。
正文
一、PDF 转 Markdown,很多人一开始就把任务理解错了
第一次做 PDF 转 Markdown 时,很多人都会下意识觉得:
不就是把 PDF 里的文字提取出来,然后换成 Markdown 格式吗?
真做起来才发现,事情根本没这么简单。
因为对大模型、RAG、知识库来说,真正有价值的从来不只是“字”,而是结构化信息。
比如:
- 哪些是一级标题,哪些是二级标题
- 哪些是正文,哪些是图注
- 哪些内容属于表格
- 多栏排版到底应该先读左边还是先读右边
- 公式、图片、图表要不要保留,怎么保留
所以更准确的说法应该是:
PDF 转 Markdown,不是“抽字 + 套格式”,而是一项以 OCR 为底座的文档结构恢复任务。
这也是很多工具“看起来能转,实际不好用”的根本原因。因为它们做到了“有输出”,但没做到“可用输出”。而你原文里提到的判断非常关键:
PDF → Markdown 的可用性,不只是文本正确,还取决于布局、顺序、元素结构和序列化是否正确。
二、为什么很多 PDF 转 Markdown 工具,最后都卡在“能看但不能用”?
这个问题特别真实。
很多方案转完以后,乍一看内容都在,但你一旦拿去做检索、切块、问答、知识库,就会立刻暴露问题:
1. 标题层级没了
整篇文档变成一坨平铺文本,后续 chunking 根本没法优雅做,检索边界也会失真。
2. 表格被打散
单元格顺序乱了,列和列之间关系丢了。对合同、财报、说明书这种文档,几乎是致命问题。
3. 阅读顺序错乱
尤其是多栏 PDF、脚注、页眉页脚、图文混排场景,最容易出现“识别率看着还行,读起来像随机拼接”的情况。
4. 公式、图表、图片信息丢失
很多技术文档的重要信息根本不在纯正文里。你只抽字,等于把文档价值砍掉一大截。
所以问题不在于“有没有转成 Markdown”,而在于:
你转出来的是不是一份真正适合大模型消费、适合后续检索和切分的 Markdown。
三、从 OCR 强,到 PDF 转 Markdown 强,中间其实差了一整条能力链
这是很多人最容易忽略的一点。
“OCR 很强”≠“PDF 转 Markdown 很强”。
中间其实隔着一整条链路,而且哪一层做不好,最终结果都会崩。
你原文里把这条链拆得很清楚,我把它改成更适合 CSDN 读者理解的版本:
第 1 层:先把字读对
标题错字、表格漏字、公式符号错识别,后面的结构恢复都会被连带放大。
第 2 层:再把版面块分对
标题、正文、表格、图片、图注,必须先分清,后面才能导出结构化结果。
第 3 层:再把阅读顺序排对
多栏、脚注、图文混排最考验这一层。很多“识别率不行”的问题,本质上其实是顺序错了。
第 4 层:再把关键元素还原对
表格还是表格,公式还是公式,图还是图,而不是全部压平成普通文本。
第 5 层:最后稳定导出 Markdown
只有前面都做对,最后这份 Markdown 才真正“能看、能切、能检索、能喂模型”。
这也是为什么,真正靠谱的 PDF 转 Markdown 方案,不能只讲 OCR,而要讲整条文档结构恢复链路。
四、为什么我更看好 PP-StructureV3 这条路线?
因为它更接近“把问题做对”的思路。
PP-StructureV3 的价值,不只是一个 OCR 模型,而是它更像一条完整的结构化文档解析链:
版面分析、文本识别、表格识别、公式识别、阅读顺序恢复,以及 Markdown/JSON 导出。
这点特别重要。
很多工具的问题是:
先 OCR 一下,后面再“想办法拼一拼”。
但 PP-StructureV3 更接近的思路是:
从底层文字,到页面结构,到输出格式,一开始就按“结构化文档解析”来做。
换句话说,它更贴近真实工程目标:
不是把 PDF 变成一堆文本,而是把复杂 PDF 还原成可继续处理、可供大模型消费的结构化文档。
五、先别空谈,直接上手:环境准备
如果你只是想快速验证,环境其实并不复杂。my.feishu.cn/docx/Rj3Xdk…
1. 安装 PaddlePaddle(GPU 示例)
python -m pip install paddlepaddle-gpu==3.3.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu118/
这里有一个很容易踩坑的点:
模型缓存路径尽量不要出现中文,否则实际运行时可能会遇到识别或路径相关问题。
2. 安装 PaddleOCR
全量安装:
python -m pip install "paddleocr[all]"
如果你这次重点就是文档解析,其实更推荐直接装这个:
python -m pip install -U "paddleocr[doc-parser]"
安装完之后,可以顺手检查一下 Paddle 是否识别到 GPU:
python -c "import paddle; print(paddle.__version__); print(paddle.device.is_compiled_with_cuda()); print(paddle.get_device())"
如果输出里是 True,并且设备显示 gpu:0,说明 GPU 环境已经识别成功。
六、实战:把整份 PDF 合并成一个 Markdown
这一步很关键。
因为很多人第一次跑 PP-StructureV3,会发现它默认是按页处理 PDF。
但真正的业务需求通常不是“每页一个 md”,而是最后拿到整份完整 Markdown。
你文档里的这段脚本就很适合拿来直接做首轮验证:
from pathlib import Path
from paddleocr import PPStructureV3
pdf_path = Path(r"C:\Users\小周\Desktop\实验报告1.pdf")
output_dir = Path(r"D:\pp_output")
pipeline = PPStructureV3()
results = pipeline.predict(str(pdf_path))
markdown_list = []
markdown_images = []
for res in results:
md_info = res.markdown
markdown_list.append(md_info)
markdown_images.append(md_info.get("markdown_images", {}))
merged_markdown = pipeline.concatenate_markdown_pages(markdown_list)
output_dir.mkdir(parents=True, exist_ok=True)
md_file = output_dir / f"{pdf_path.stem}.md"
if isinstance(merged_markdown, dict):
markdown_text = merged_markdown.get("markdown_texts", "")
else:
markdown_text = getattr(merged_markdown, "markdown_texts", str(merged_markdown))
with open(md_file, "w", encoding="utf-8") as f:
f.write(markdown_text)
for item in markdown_images:
if item:
for rel_path, image in item.items():
img_path = output_dir / rel_path
img_path.parent.mkdir(parents=True, exist_ok=True)
image.save(img_path)
print(f"Markdown 已保存: {md_file}")
这段代码最实用的地方,不只是“能跑”,而是它把两个工程上很真实的需求一起做了:
- 把多页 PDF 合并成一份 Markdown
- 把 Markdown 里引用到的图片资源也一起落盘
这样你拿到的结果,就不是一个孤零零的 .md 文件,而是一份真正能继续处理的文档输出。
然后我在github里面上传了PP-StructureV3跑数据集OmniDocBench的代码,大家感兴趣也可以去跑一下。
指标显示PP-StructureV3的表现不错。
七、这几个坑,我建议你别等踩了再回头
1. 纯英文 PDF,别直接用默认配置
如果文档是纯英文,直接切英文配置,通常会更稳:
pipeline = PPStructureV3(lang="en")
2. 扫描件、拍照页、歪斜页,不要默认配置一把梭
这类文档建议把方向分类、去畸变、文本行方向这些开关打开:
pipeline = PPStructureV3(
use_doc_orientation_classify=True,
use_doc_unwarping=True,
use_textline_orientation=True,
)
3. 输出路径尽量给目录,不要硬写成单文件
因为 PDF 是逐页产出结果的,直接写死单文件路径,后面很容易覆盖资源、搞乱引用关系。
4. 不要把原始 Markdown 直接扔进向量库
这个点非常重要。真正影响 RAG 效果的,很多时候不是“有没有转出来”,而是“转出来以后有没有清洗”。
至少建议做这些后处理:
- 去页眉页脚
- 合并断裂段落
- 规范标题层级
- 清洗空行
- 检查图片路径
- 对表格做必要修复
很多人以为模型不行,实际问题可能根本不在模型,而在后处理太粗糙。
八、工程落地别“一把梭”,分流才是正解
如果你只是做 demo,当然所有 PDF 都可以直接丢给一个统一流程。
但如果你做的是项目、服务、批量处理,那我非常认同你文档里的思路:
不要让所有 PDF 都走同一条解析链路。
更合理的方式是分三层:
方案 A:简单电子版走轻量路线
如果 PDF 有文字层、排版简单,就先走轻量流程,节省成本和时间。
方案 B:复杂文档切到 PP-StructureV3
比如这些特征出现时,就值得升级解析链路:
- 扫描件
- 中文复杂版面
- 表格密集
- 多栏
- 公式较多
- 阅读顺序容易混乱
方案 C:统一后处理
无论前面走哪条路,最后都做一次 Markdown 清洗和规范化。
这样做的好处非常现实:
- 简单文档跑得快
- 复杂文档质量稳
- 整体成本更可控
这才是更接近生产环境的思路。
九、结论:如果你要的是“能喂给大模型的 Markdown”,重点就不是提取文字,而是恢复结构
这篇文章真正想说清楚的,其实只有一句话:
PDF 转 Markdown,不是把字抠出来就结束了,而是要尽量把文档结构恢复出来。
如果你只是想把 PDF 里的文字抽出来,工具很多。
但如果你的目标是:
- RAG
- 知识库
- Agent 文档理解
- 企业级 PDF 解析
- 后续结构化检索
那真正关键的就不是“提取文字”,而是“恢复结构”。
从这个角度看,PP-StructureV3 值得重视的地方也很明确:
- 它不只是 OCR
- 它更强调结构恢复
- 它更适合复杂 PDF
- 它更适合 Markdown / JSON 这类结构化输出
- 它更适合作为 RAG 前处理的一环
所以,如果你的 PDF 转 Markdown 目标不是“能看”,而是“能用”,那 PP-StructureV3 确实是一条值得优先尝试的路线。