入门

快速开始与 API安装在线 OCRCode generator (EN)

模型与产线

PP-OCRv6 模型支持语言PP-StructureV3PaddleOCR-VL

部署与集成

Serving & API (EN)PaddleOCR.js (EN)MCP server (EN)

排错与升级

常见错误从 2.x 迁移Releases (EN)

评估

Our benchmark (EN)Compare OCR tools (EN)License & cost (EN)

工具

在线 OCR安装命令生成器Code generator (EN)报错修复助手2.x → 3.x 代码转换语言代码查询

语言

English简体中文日本語在线体验 OCR
文档解析 · 基于 PaddleOCR 3.7.0 实测

PP-StructureV3:文档转 Markdown,附真实输出

PP-StructureV3 是 PaddleOCR 的版面分析产线:它找出页面上的标题、段落、表格、公式和图片,用专门的模型分别识别,再按阅读顺序输出 Markdown 和 JSON。普通 CPU 就能运行。我们安装了它,用一张发票和一页论文做了测试,并原样展示输出结果。

已对照 PaddleOCR 3.7.0 核实更新于 15 分钟阅读
本页目录
  1. PP-StructureV3 能做什么
  2. 安装
  3. 快速开始:Python 与命令行
  4. 真实输出:一张发票和一页论文
  5. 修复:改用 PP-OCRv6 文本模型
  6. 多页 PDF 转为一个 Markdown 文件
  7. 表格
  8. 公式
  9. 印章与图表
  10. 重要参数
  11. 结果里有什么
  12. 保存:Markdown、JSON、Word、HTML、Excel
  13. CPU 上的性能
  14. 从 PaddleOCR 2.x 的 PPStructure 迁移
  15. 什么时候不该用 PP-StructureV3
  16. 常见问题

简短回答:先 pip install "paddleocr[doc-parser]",然后 PPStructureV3().predict("file.pdf"),再对每一页调用 save_to_markdown()。表格输出为 HTML,公式输出为 LaTeX。在我们的 4 核 CPU 上,每页约 13–15 秒。有一个值得知道的技巧:3.7 版的产线仍然用 PP-OCRv5 模型识别文字——改传 PP-OCRv6 模型后,我们发票上的文字错误全部消失,而且速度更快。

PP-StructureV3 能做什么#

PP-StructureV3 随 PaddleOCR 3.0 于 2025 年 5 月发布,是在之前的版面解析产线基础上构建的。它带来了更好的版面、表格和公式模型,以及图表理解、多栏阅读顺序和 Markdown 输出。15它由大约十几个小模型串联而成,每个模型都由一个 use_* 开关控制启用与否:

1 · 输入图片或 PDFPDF 逐页渲染为图片。方向校正和弯曲矫正可选(默认关闭)。
2 · 版面PP-DocLayout_plus-L20 种区块类型,另有 PP-DocBlockLayout 检测分栏区域。
3 · 识别OCR · 表格 · 公式每个区块交给对应的模型。印章和图表可选(默认关闭)。
4 · 组装Markdown + JSON区块按阅读顺序排列;也可导出 DOCX、HTML 和 XLSX。

下面是 PaddleOCR 3.7.0 实际加载的默认模型。它们写在 PaddleX 3.7.2 的产线配置里,而不是 PaddleOCR 自己的文档里,所以其中有几项会让人意外:3

任务默认模型默认开启?开关
版面检测PP-DocLayout_plus-L始终开启—
区域(分栏)检测PP-DocBlockLayout是use_region_detection
文本检测 / 识别PP-OCRv5_server_det / PP-OCRv5_server_rec始终开启—
表格PP-LCNet_x1_0_table_cls 判断有线表还是无线表;SLANeXt_wired / SLANet_plus 识别结构;RT-DETR-L 单元格检测模型是use_table_recognition
公式PP-FormulaNet_plus-L是use_formula_recognition
印章PP-OCRv4_server_seal_det否use_seal_recognition
图表 → 表格PP-Chart2Table(0.58B 参数)否use_chart_recognition
整页方向 / 弯曲矫正PP-LCNet_x1_0_doc_ori / UVDoc否use_doc_orientation_classify、use_doc_unwarping
文本行方向PP-LCNet_x1_0_textline_ori否use_textline_orientation

有两点需要注意。使用文档里写的无线表(无边框表格)模型是 SLANeXt_wireless,但配置实际加载的是 SLANet_plus。13另外,PP-StructureV3 不使用 PP-DocLayoutV2/V3——它们属于 PaddleOCR-VL。两者的取舍在于:PP-StructureV3 能给出单元格级和文本行级的坐标,而 VL 系列不能。5

安装#

PP-StructureV3 除了 PaddleOCR 和推理引擎之外,还需要 doc-parser 这个 extra。以下是我们使用的命令:4

python -m pip install paddlepaddle==3.2.0
python -m pip install "paddleocr[doc-parser]==3.7.0" python-docx
python -m pip install paddlepaddle-gpu==3.2.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/
python -m pip install "paddleocr[doc-parser]==3.7.0" python-docx

这个 extra 会装上 paddlex[ocr,genai-client]——包括 BeautifulSoup、lxml、openpyxl、pypdfium2、scikit-learn、tokenizers 等。它要求 Python 3.9 或更高版本。我们额外安装 python-docx,因为这个 extra 不包含它,而缺了它 Word 导出——以及命令行的 --save_path——都会失败(详情)。我们锁定 paddlepaddle==3.2.0,是因为 PyPI 上当前的 3.3.1 版在我们的测试中会让 PaddleOCR 3.7.0 在 CPU 上崩溃(详情与修复方法)。

不装这个 extra,创建产线时就会失败。这是我们复现出的报错:

textPPStructureV3() without [doc-parser]
RuntimeError: A dependency error occurred during pipeline creation. Please refer to the installation documentation to ensure all required dependencies are installed.
(caused by DependencyError: `PP-StructureV3` requires additional dependencies. To install them, run `pip install "paddlex[ocr]==<PADDLEX_VERSION>"` if you're installing `paddlex` from an index, ...)

修复方法是 pip install "paddleocr[doc-parser]"——报错信息建议直接安装 paddlex[ocr],这样也行,但很容易与 PaddleOCR 锁定的版本对不上。

快速开始:Python 与命令行#

from paddleocr import PPStructureV3

pipeline = PPStructureV3(
    use_doc_orientation_classify=False,   # 本来就是默认值;旋转的扫描件请设为 True
    use_doc_unwarping=False,              # 拍摄的弯曲页面请设为 True
)
for res in pipeline.predict("invoice.png"):
    res.print()                                  # 在终端打印结构化结果
    res.save_to_markdown(save_path="output")     # output/invoice.md + output/imgs/
    res.save_to_json(save_path="output")         # output/invoice_res.json
    res.save_to_img(save_path="output")          # 版面、OCR 和阅读顺序的可视化图
paddleocr pp_structurev3 -i invoice.png --save_path ./output

# GPU,以及最常用的几个开关
paddleocr pp_structurev3 -i scan.pdf --device gpu:0 \
  --use_doc_orientation_classify True --use_chart_recognition True --save_path ./output

第一次运行会把所有默认模型下载到 ~/.paddlex/official_models/。在命令行中,--save_path 会对每一页调用所有已注册的保存方法,包括 Word 导出——所以没装 python-docx 时,我们的命令行运行写出了 Markdown、JSON、HTML、XLSX 和图片,然后以 ModuleNotFoundError: No module named 'docx' 和退出码 1 中止。94设备会自动选择(有 GPU 时用 GPU 0);传入 device="cpu" 或 device="gpu:0" 可以强制指定。

真实输出:一张发票和一页论文#

下面是默认产线在我们两张测试页面上的原始输出,未做任何修改。左边是输入的图片,右边是 save_to_markdown() 生成的 .md 文件。4

发票#

Northwind Lighting Co 的样例发票,含五行明细表格和合计金额
输入:invoice.png,1240 × 1754 px。
mdinvoice.md(默认模型)
## Northwind Lighting Co

88 Foundry Lane, Leeds LS1 4AB, United Kingdom billing@northwind-lighting.example·VAT GB 123 4567 89INVOICE

Invoice no.INV-2026-0917Issue date 14 Oct 2026Due date 13 Noy 2026

BILL TO

Ashgrove Architects Ltd Unit 5. CanaL Wharf Manchester M1 2EQ

PROJECT

Library refit, Ievel 2PO number: AA-77310


<div style="text-align: center;"><html><body><table border="1"><tbody><tr><td>Description</td><td>Qty</td><td>Unit price</td><td>Amount</td></tr><tr><td>LED panel 600×600,4000K</td><td>24</td><td>£46.00</td><td>£1,104.00</td></tr><tr><td>Linear pendant, 1.2 m</td><td>10</td><td>£128.50</td><td>£1,285.00</td></tr><tr><td>Emergency exit sign</td><td>6</td><td>£39.90</td><td>£239.40</td></tr><tr><td>DALI dimming driver</td><td>12</td><td>£22.75</td><td>£273.00</td></tr><tr><td>Installation labour (hours)</td><td>16</td><td>£55.00</td><td>£880.00</td></tr></tbody></table></body></html></div>


## Payment terms

Subtotal £3,781.40VAT 20%£756.28Total due £4,537.68Please pay within 30 days by bank transfer to Northwind Lighting Co.Sort code 12-34-56, account 87654321. Quote the invoice number as reference.Late payments may incur interest at 8% above the Bank of England base rate.

上面的表格 HTML 原样渲染后如下:

DescriptionQtyUnit priceAmount
LED panel 600×600,4000K24£46.00£1,104.00
Linear pendant, 1.2 m10£128.50£1,285.00
Emergency exit sign6£39.90£239.40
DALI dimming driver12£22.75£273.00
Installation labour (hours)16£55.00£880.00

做对了的:全部 24 个表格单元格、每个数字和价格、两个章节标题,以及付款条款的每一行。出错的地方:

  • 三行文字有错字:Noy 应为 Nov,Ievel(大写 I)应为 level,Unit 5. CanaL 应为 Unit 5, Canal。这些错误来自 PP-OCRv5 文本识别模型——见修复方法。
  • 区块内的换行直接消失,连空格都没留。“INV-2026-0917Issue date 14 Oct 2026Due date”在页面上原本是三行“标签/值”。如果你需要键值对,请读取 overall_ocr_res(每个文本行一条),而不是 Markdown。
  • 阅读顺序错了一次。合计金额区块被放到了“Payment terms”标题之后,并和下面的段落粘在一起。
  • 页脚不见了。“Thank you for your business.”其实被检测到了——它在 JSON 里,标签为 footer——但 footer 属于默认的 markdown_ignore_labels,同在其中的还有 header、number、footnote、aside_text 以及页眉/页脚图片。3传入 markdown_ignore_labels=[] 即可保留全部内容。
  • 表格没有 <thead>,表头行只是一个普通行。标题丢掉了末尾的句点(“Northwind Lighting Co”)。

含公式和表格的论文页#

学术论文样例页,含一个带编号的公式、一个三行结果表格和两个章节
输入:paper-page.png,1240 × 1600 px。
mdpaper-page.md
### 3. Training Objective

We train the recognizer with a standard sequence objective. Given N text-line images x_i and their transcriptions y_i, the model minimises the average negative log-likelihood of the target sequence:

$$\mathcal{L}=-\textstyle\frac{1}{N}{\sum_{i\:=\:1}^{N}}\mathsf{l o g}\:p(y_{i}\mid x_{i}),$$

Table 2 reports the effect of the training schedule on a held-out set of 2,000 receipt photographs. Longer schedules improve accuracy but cost time.

<div style="text-align: center;">Table 2. Schedule ablation on the receipt set.</div>



<div style="text-align: center;"><html><body><table border="1"><thead><tr><td>Schedule</td><td>Line accuracy</td><td>Train hours</td></tr></thead><tbody><tr><td>Short (20 epochs)</td><td>91.4%</td><td>6</td></tr><tr><td>Medium (50 epochs)</td><td>93.1%</td><td>15</td></tr><tr><td>Long (100 epochs)</td><td>93.6%</td><td>29</td></tr></tbody></table></body></html></div>


### 4. Discussion

The medium schedule offers the best trade-off : it reaches 93.1% line accuracy in roughly half the training time of the long schedule.

这一页的结果几乎完美。正文每个词都正确;表格完全准确,这次还有了正确的 <thead>;图表标题也作为独立区块保留了下来。公式是数学上正确的 LaTeX,但有两处小问题:“log”被输出为 \mathsf{l o g}(渲染成无衬线的“log”,而不是常见的 \log);公式编号“(1)”被检测为 formula_number,但没有出现在 Markdown 中。页码“4”是被有意去掉的(标签为 number)。带编号的标题变成了 ###;发票上不带编号的标题则变成了 ##。

修复:改用 PP-OCRv6 文本模型#

PaddleOCR 3.7.0 已把 PP-OCRv6 设为普通 OCR 的默认模型,但 PP-StructureV3 的配置仍然加载 PP-OCRv5_server_det 和 PP-OCRv5_server_rec。3你无法通过 ocr_version="PP-OCRv6" 切换——这个类在该参数上只接受 PP-OCRv3、v4 和 v5。2请直接传入模型名称:

pythonstructure_v6.py
from paddleocr import PPStructureV3

pipeline = PPStructureV3(
    text_detection_model_name="PP-OCRv6_medium_det",
    text_recognition_model_name="PP-OCRv6_medium_rec",
)

我们在同一台机器上用两种配置分别处理了这张发票。所有不同的行如下:4

默认(PP-OCRv5_server)使用 PP-OCRv6_medium页面上的原文
Due date 13 Noy 2026Due date 13 Nov 202613 Nov 2026
Library refit, Ievel 2Library refit, level 2Library refit, level 2
Unit 5. CanaL WharfUnit 5, Canal WharfUnit 5, Canal Wharf
LED panel 600×600,4000KLED panel 600×600, 4000KLED panel 600×600, 4000K
billing@…example·VAT GBbilling@…example· VAT GBbilling@…example · VAT GB

四个错字全部修正,还补回了两个缺失的空格,没有任何地方变差。这些错误确实来自文本模型:在我们的 普通 OCR 基准测试(英文) 中,单独运行的 PP-OCRv5_server 在这张发票上犯了完全相同的 Noy、CanaL 和 Ievel 错误。Markdown 的其余部分——表格、标题、阅读顺序——完全一致,因为只换了文本模型。

PP-OCRv6 快约 10%

换用 PP-OCRv6 文本模型还修正了所有文字错误。PP-StructureV3,发票页,热启动运行,4-vCPU Xeon,CPU 上的 PaddlePaddle 3.2.0。越低越快。

文本模型秒
默认(PP-OCRv5_server)14.9 s
PP-OCRv6_medium det + rec13.4 s
由 paddleocr.dev 于 2026-10-27 实测。脚本:_src/data/bench/structure_v6.py。

这个提速与我们的 普通 OCR 基准测试(英文) 一致:在 CPU 上,PP-OCRv6_medium 比 PP-OCRv5_server 更快也更准。另一个好处是:PP-OCRv6 medium 用一个模型就能识别 50 种语言,包括日文和 46 种拉丁字母语言,因此对默认模型处理得不太好的多语言混排文档也能覆盖。8

其他语言#

lang 参数会替你选择文本模型,但只会从 PP-OCRv5 及更早的模型中选。在 3.7.0 源码中,lang="en"、"ch"、"chinese_cht" 和 "japan" 都映射到 PP-OCRv5_server_rec;"fr"、"de" 等拉丁字母语言使用 latin_PP-OCRv5_mobile_rec;韩文、泰文、希腊文和东斯拉夫语言有各自的 PP-OCRv5 mobile 模型;阿拉伯文、西里尔文和天城文则退回到 PP-OCRv3 模型。2如果你传入了模型名称,lang 会被忽略并给出警告。全部语言代码见 语言列表。

多页 PDF 转为一个 Markdown 文件#

对 PDF 调用 predict() 会为每一页返回一个结果,save_to_markdown() 也是每页写一个文件。要得到单个文件,请收集每页的 res.markdown,再用 concatenate_markdown_pages() 合并,它还会判断段落是否跨页延续:12

pythonpdf_to_markdown.py
from pathlib import Path
from paddleocr import PPStructureV3

pipeline = PPStructureV3()
pages = pipeline.predict("report.pdf")

markdown_list, images = [], []
for res in pages:
    markdown_list.append(res.markdown)
    images.append(res.markdown.get("markdown_images", {}))

merged = pipeline.concatenate_markdown_pages(markdown_list)
text = merged["markdown_texts"]          # merged 是 MarkdownResult,不是 str

out = Path("output"); out.mkdir(exist_ok=True)
(out / "report.md").write_text(text, encoding="utf-8")
for page_images in images:                       # 图片和表格截图
    for rel_path, img in page_images.items():
        (out / rel_path).parent.mkdir(parents=True, exist_ok=True)
        img.save(out / rel_path)

官方的 PDF 示例会崩溃。使用文档把 concatenate_markdown_pages() 的返回值直接用 f.write(markdown_texts) 写入文件。1在 PaddleOCR 3.7.0 搭配 PaddleX 3.7.2 时,该函数返回的是 MarkdownResult 对象,我们得到了 TypeError: write() argument must be str, not MarkdownResult(外加一个空的输出文件)。请像上面的脚本那样用 ["markdown_texts"] 取值。34

我们的 2 页 PDF 测试结果#

我们用 Pillow 把同样的两张测试图片打包成 PDF(Pillow 会把它们存为 JPEG),再交给产线处理。PaddleX 以 2.0 倍缩放渲染 PDF 页面,所以发票变成了 1191 × 1684 px 的图片,而不是原来的 1240 × 1754。34这个小变化带来了明显的影响:

  • 默认模型丢掉了大部分词间空格:“88FoundryLane,LeedsLS14AB,UnitedKingdom”、“Please pay within30days”。不过 PNG 运行中的字符错误消失了。
  • 使用 PP-OCRv6 时文字是干净的——“88 Foundry Lane, Leeds LS1 4AB, United Kingdom”——只有一串数字例外(“VAT GB 123456789”)。
  • 两种配置下合计金额区块都消失了。“Subtotal”、“VAT 20%”和“Total due”都被 OCR 识别出来了——它们在 overall_ocr_res 里——但没有任何版面框覆盖它们,所以它们没能进入 parsing_res_list 和 Markdown。在 PNG 运行中,该区块的版面得分只有 0.40。
  • 第 2 页的公式比 PNG 版本更干净:是 \log p(y_{i}\mid x_{i}),而不是 \mathsf{l o g}。

区块缺失的修复方法是 layout_threshold。用 predict(..., layout_threshold=0.3) 重新处理 PDF 后,合计金额回到了 Markdown 中(“Subtotal £3,781.40VAT 20%£756.28Total due £4,537.68”)。不过标签也有变化:在 0.3 时,顶部两个标题之一不再被标为标题,还多出了一个 header 区块;在 0.2 时,顶部两个标题都不再是标题。阈值只需降到够用为止。4

总的经验是:版面检测决定了哪些内容能进入你的 Markdown,而它对分辨率和压缩很敏感。每遇到一种新的文档类型,都抽查几页,与保留了 OCR 找到的每一行的 overall_ocr_res 对照。

表格#

表格识别默认开启。分类模型先判断每个表格是有线表(带框线)还是无线表,然后结构模型和单元格模型把它重建为 HTML。页面上的每个表格都会进入 table_res_list,同样的 HTML 也会嵌入 Markdown。1

pythontables.py
for res in pipeline.predict("invoice.png"):
    for i, table in enumerate(res["table_res_list"]):
        html = table["pred_html"]          # "<html><body><table>..."
        cells = table["cell_box_list"]     # 每个单元格一个框,页面坐标
        print(i, len(cells), html[:80])
    res.save_to_html(save_path="output")   # 每个表格一个 .html 文件
    res.save_to_xlsx(save_path="output")   # 每个表格一个 .xlsx 文件

在我们的发票上,cell_box_list 有 24 个框,每个单元格一个;论文页上是 12 个。每个条目还有 table_ocr_pred,即表格内部的原始 OCR 结果。4影响表格行为的 predict() 选项有:2

参数默认值适用场景
use_table_orientation_classifyTrue表格在页面上可能旋转了 90°/180°/270°。
use_ocr_results_with_table_cellsTrue按预测的单元格边界切分 OCR 结果并重新识别,避免文字跨单元格丢失。
use_e2e_wired_table_rec_modelFalse有线表:只用结构模型,不用单元格检测模型。
use_e2e_wireless_table_rec_modelTrue无线表默认就只用结构模型。
use_wired_table_cells_trans_to_htmlFalse直接用检测到的有线表单元格框生成 HTML(适合规整的网格)。
use_wireless_table_cells_trans_to_htmlFalse同上,用于无线表。

如果你只需要表格、不需要版面分析,单独的 table_recognition_v2 产线(TableRecognitionPipelineV2)更轻量。

公式#

公式识别默认开启,使用 PP-FormulaNet_plus-L。每个公式都会出现在 formula_res_list 中,带有 rec_formula(LaTeX),并在 Markdown 中以 $$…$$ 块的形式出现——上面的论文页就是真实的例子。14L 模型精度最高,也是整条产线中最重的部分,远超其他模型。百度官方的数据(Tesla T4 GPU / Xeon Gold 6271C CPU):1

模型En-BLEUZh-BLEUCPU 毫秒(高性能模式)大小
PP-FormulaNet_plus-L(默认)92.2290.643125.58698 MB
PP-FormulaNet_plus-M91.4589.761615.80592 MB
PP-FormulaNet_plus-S88.7153.32260.99248 MB

对于在 CPU 上处理的纯英文文档,按这些数据,formula_recognition_model_name="PP-FormulaNet_plus-S" 每个公式大约快 12 倍,英文精度略有损失(中文则损失很大)。如果你的文档没有数学公式,use_formula_recognition=False 可以完全跳过这个模型。使用 engine="onnxruntime" 时也必须加上这个开关,因为那里暂不支持公式模型。1

印章与图表#

两者默认都关闭。use_seal_recognition=True 会加入 PP-OCRv4_server_seal_det 来识别印章上的弯曲文字——这在中文发票和合同上很常见——它有自己的 seal_det_* 阈值,结果写入 seal_res_list。1use_chart_recognition=True 会用 PP-Chart2Table 把柱状图、折线图和饼图转换为表格,这是一个 0.58B 参数、约 1.4 GB 的模型。1百度给出的质量数据前后不一:使用文档报告的“Model Score”为 75.98,3.1.0 的发布说明则是 RMS-F1 80.60%——可能是不同的指标。这两项都不在我们的测试范围内;鉴于模型体积,图表识别在 CPU 上会比较慢。

重要参数#

所有构造参数的默认值都是 None,意思是“使用 PaddleX 配置”。使用文档公布了这些参数最终对应的值——但对其中一些设置,PaddleOCR 3.7.0 实际加载的配置却不一样:13

参数文档写的PaddleX 3.7.2 配置作用
text_det_limit_side_len960736文本检测输入的目标尺寸。
text_det_limit_typemaxmin限制作用于长边还是短边。
text_det_unclip_ratio2.01.5每个文本框的外扩程度。
layout_threshold0.5按类别,0.3–0.5版面置信度阈值;可传浮点数或 {class_id: value}。
text_det_thresh / text_det_box_thresh0.3 / 0.60.3 / 0.6文本的像素阈值和检测框得分阈值。
layout_nms / layout_merge_bboxes_modeTrue / large—版面框重叠的处理方式。
use_region_detectionTrueTrue按分栏/区域分组,用于阅读顺序。
format_block_contentFalseFalse在 JSON 中把每个 block_content 格式化为 Markdown。
markdown_ignore_labelsnumber, footnote, header, header_image, footer, footer_image, aside_text不写入 Markdown 的区块。

以配置为准。我们保存的 JSON 记录了实际使用的设置:overall_ocr_res.text_det_params 显示为 limit_side_len 736, limit_type "min", unclip_ratio 1.5, max_side_limit 4000——是配置里的值,而不是文档里的值。4如果你按文档调了 PP-StructureV3 的参数却看不到变化,原因就在这里。

推理引擎相关选项同样以关键字参数传入:device、engine、enable_mkldnn(默认 True)、cpu_threads(默认 10)、enable_hpi、use_tensorrt、precision,以及用于完整 YAML 覆盖的 paddlex_config。1

结果里有什么#

每页的结果都是一个类似字典的对象。JSON 文件包含相同的字段:14

字段内容
parsing_res_list按阅读顺序排列的区块:block_label(text、paragraph_title、table、formula、figure_title、footer…)、block_content、block_bbox、block_id、block_order。被忽略的标签其 block_order: null。
layout_det_res原始版面框,带标签和得分。
overall_ocr_res每个文本行:rec_texts、rec_scores、rec_polys、rec_boxes,以及 text_det_params。我们的发票有 52 行。
table_res_list每个表格的 pred_html、cell_box_list、table_ocr_pred。
formula_res_listrec_formula(LaTeX)、rec_polys、formula_region_id。
seal_res_list印章文字(开启时)。
model_settings、width、height、page_index、page_count运行设置和页面信息(图片输入时 page_index 为 None)。

res.markdown 是一个字典,包含 markdown_texts、markdown_images、page_continuation_flags、page_index 和 input_path;res.img 提供可视化图像(layout_det_res、overall_ocr_res 等)。1

保存:Markdown、JSON、Word、HTML、Excel#

我们对结果调用了每一个保存方法。六个开箱即用,一个需要额外安装包:4

方法输出我们的结果
save_to_markdown(path){name}.md,外加一个存放表格、公式和图片截图的 imgs/ 文件夹成功
save_to_json(path){name}_res.json,包含上面所有字段成功
save_to_img(path)版面、OCR 和阅读顺序的可视化图成功
save_to_html(path)每个表格一个 {name}_table_1.html成功
save_to_xlsx(path)每个表格一个 {name}_table_1.xlsx成功
save_to_word(path){name}.docx(PaddleOCR 3.5.0 新增)安装 python-docx 之前一直失败
save_to_latex(path){name}.tex(使用文档中未提及)成功

PDF 输入时,文件名会带上页码后缀:report_0.md、report_1.md 依此类推。save_path 请传目录而不是文件名,否则各页会互相覆盖。1

save_to_word() 需要 python-docx,而 [doc-parser] 不会安装它。只装文档要求的 extra 时,我们遇到了 ModuleNotFoundError: No module named 'docx'——尽管官方的快速开始示例就调用了 save_to_word()。1执行 pip install python-docx 后,它顺利写出了 .docx。(trans extra 和 PaddleX 的 base extra 都包含 python-docx;doc-parser 不包含。)3

结果对象还有 save_all(path),会一次运行所有保存方法——这和命令行的 --save_path 做的事情一样,这也是命令行在缺少 python-docx 时同样失败的原因。

CPU 上的性能#

这里的所有测试都在 4-vCPU Intel Xeon @ 2.10 GHz、15 GB 内存、无 GPU 的机器上运行,使用 CPU 上的 PaddlePaddle 3.2.0 并开启默认的 oneDNN 加速。4

运行(热启动,即首次调用之后)默认模型PP-OCRv6 文本模型
发票,1240 × 1754 px14.9 s13.4 s
论文页,1240 × 1600 px*15.2–16.5 s14.1–16.2 s
2 页 PDF(两页合计)*—25.1 s

*在第二个会话中测得,当时机器上还有其他任务在运行,请视为近似值;发票的数据来自一次干净的运行。从我们的测试中得出三点实用建议:

  • 首次调用很慢。创建产线要加载大约十几个模型(第一次运行还要下载),第一次 predict() 还要预热。产线只创建一次,然后对所有文件复用。
  • 预留约 5 GB 内存。这是加载并运行默认产线时我们的 Python 进程占用的内存(常驻内存)。4 GB 的机器会很吃力。
  • 关掉不需要的功能是最有效的手段。按百度自己的表格,使用 L 模型的公式识别是最重的阶段(在他们的 CPU 上每个公式超过 3 秒);use_formula_recognition=False、use_chart_recognition=False(默认已关闭)以及换用 S 公式模型都能缩短耗时。1

百度公布的数据快得多,因为他们用的是 GPU 或大型服务器 CPU。对于默认配置,他们的 280 张图片基准报告:A100 上每张 1.38 s,A10 上 1.74 s,T4 上 3.70 s;“轻量”配置在 Intel Xeon 8350C CPU 上每张 3.74 s,在 Apple M4 上 12.22 s。6这些是我们没有复现的官方数据。

百度本地测试(925 页 PDF)V100A100
Server OCR,FormulaNet-L,无图表,最长边 40961.77 s/页1.12 s/页
同上,开启图表识别4.09 s/页2.76 s/页
Mobile OCR,FormulaNet-M,无图表,最长边 12000.99 s/页0.64 s/页

同一来源显示:图表识别会让每页耗时增加一倍以上,而 mobile/轻量配置大约能减半。使用 server 模型时,V100 上的峰值显存为 17.0 GB,A100 上为 21.8 GB;轻量配置下分别为 8.6 GB 和 11.4 GB。6

从 PaddleOCR 2.x 的 PPStructure 迁移#

PPStructure 在 3.x 中已被移除,from paddleocr import PPStructure 现在会抛出 ImportError。它的替代者是 PPStructureV3,而且与 PaddleOCR 类不同,它没有兼容层:每个旧关键字参数都会抛出 ValueError: Unknown argument: …。9

2.x3.x
PPStructure(use_gpu=True)PPStructureV3(device="gpu:0")(或 "cpu")
PPStructure(show_log=False)已移除;请使用 Python logging
table=True / formula=Trueuse_table_recognition / use_formula_recognition(公式现在默认开启)
image_orientation=Trueuse_doc_orientation_classify=True
layout=False、ocr=False没有对应参数;请使用 PaddleOCR 或 TableRecognitionPipelineV2
det_model_dir、rec_model_dir、use_angle_clstext_detection_model_dir、text_recognition_model_dir、use_textline_orientation
layout_score_thresholdlayout_threshold
recovery=True、convert_info_docx()res.save_to_word() / res.save_to_markdown()
save_structure_res()、to_excel()res.save_to_json()、res.save_to_xlsx()
engine(img)pipeline.predict(img)
mode='kie'PP-ChatOCRv4(paddleocr[ie])
命令行 --type structure --recovery truepaddleocr pp_structurev3 -i file --save_path out/

我们的 迁移指南 有完整的映射表,还有一个能自动改写旧代码的转换工具。

什么时候不该用 PP-StructureV3#

  • 你只需要文字。直接用 PaddleOCR 搭配 PP-OCRv6 更快:在我们的机器上,PP-OCRv6 medium 识别同一张发票用 PaddlePaddle 需要 9.3 s,用 ONNX Runtime 需要 5.7 s,PP-OCRv6 small 只要 1.9 s(基准测试(英文))。它还会返回每一行及其检测框,处理表单时这往往正是你需要的。
  • 你最看重困难文档上的精度,而且有 GPU。在 OmniDocBench v1.5(第三方)上,PP-StructureV3 总分 86.73;PaddleOCR-VL-1.5 为 94.50。7杂乱的扫描件、手写体和复杂版面正是 PaddleOCR-VL 的用武之地。
  • 表单与键值对抽取。如我们的发票所示,标签/值对在 Markdown 中会被合并成连续的文字。请使用行级 OCR 结果,或 PP-ChatOCRv4 这类信息抽取产线。
  • 原生数字 PDF。如果 PDF 本身已有文本层,直接提取文本可以完全避免 OCR 错误,耗时也只是零头;PP-StructureV3 适合扫描件和纯图片 PDF。对于 Word、Excel 和 PowerPoint 文件,PaddleOCR 的 doc2md 无需任何 OCR 即可转换。
  • 小机器。默认产线要加载大约十几个模型,其中包括一个 698 MB 的公式模型。在低内存服务器上,请关闭公式和图表识别,或使用轻量模型。

还没拿定主意?我们的 OCR 工具对比(英文) 把 PP-StructureV3 与 Docling、MinerU 等工具放在一起比较。

常见问题#

如何导入 PP-StructureV3?

from paddleocr import PPStructureV3——注意大小写和 V3。它需要 pip install "paddleocr[doc-parser]";不装这个 extra 会报“A dependency error occurred during pipeline creation”。

PP-StructureV3 需要 GPU 吗?

不需要。我们在没有 GPU 的 4-vCPU Xeon 上运行,每页约 13–15 秒。处理量大时 GPU 会有帮助:百度报告默认配置在 A100 上每张图片 1.38 s。

如何用 PaddleOCR 把 PDF 转成 Markdown?

运行 PPStructureV3().predict("file.pdf"),收集每一页的 res.markdown,再把列表传给 pipeline.concatenate_markdown_pages()。上面的 完整脚本 还会保存 Markdown 中引用的图片。

为什么 PPStructure(use_gpu=True) 会报错?

PPStructure 在 PaddleOCR 3.x 中已被移除,use_gpu 也已彻底不存在。请使用 PPStructureV3(device="gpu:0")。所有 2.x 的关键字参数名在 PPStructureV3 上都会报“Unknown argument”;见 映射表。

如何把表格导出为 Excel 或 HTML?

调用 res.save_to_xlsx("output") 或 res.save_to_html("output"),或者直接读取 res["table_res_list"][i]["pred_html"]。同样的 HTML 也嵌入在 Markdown 中。

为什么 Markdown 里少了一些文字?

页眉、页脚、页码、脚注和旁注默认通过 markdown_ignore_labels 排除。它们仍然在 JSON 里。传入 markdown_ignore_labels=[] 即可包含它们。

选 PP-StructureV3 还是 PaddleOCR-VL?

如果你用 CPU、需要表格单元格或文本行坐标,或者希望每个步骤都是可替换的小模型,选 PP-StructureV3。如果你有 GPU 并且想要最高精度,选 PaddleOCR-VL:它在 OmniDocBench v1.5 上得分 94.50,而 PP-StructureV3 为 86.73。

可以在 PP-StructureV3 里使用 PP-OCRv6 吗?

可以,我们也推荐这样做。传入 text_detection_model_name="PP-OCRv6_medium_det" 和 text_recognition_model_name="PP-OCRv6_medium_rec"。ocr_version="PP-OCRv6" 不起作用——对这个类来说,该参数最高只到 PP-OCRv5。

参考来源

  1. PP-StructureV3 使用教程,docs/version3.x/pipeline_usage/PP-StructureV3.en.md(仓库 commit dab3fe3,2026-09-16):模块(第 9–19 行)、模型表(83–891)、测试硬件(917–926)、命令行与 Python(963–1781)、参数默认值(1803–2470)、结果字段与方法(2771–2992)。中文版:PP-StructureV3.md(行号以英文版为准)。
  2. PaddleOCR 3.7.0 包源码(PyPI wheel),paddleocr/_pipelines/pp_structurev3.py:__init__ 参数(32–101)、ocr_version 仅限 PP-OCRv3–v5(28、103–106)、lang → 模型映射(530–660)、predict 默认值(148–185)、concatenate_markdown_pages(300–301)、命令行子命令(696)。paddleocr.dev 于 2026-10-27 阅读。
  3. PaddleX 3.7.2 wheel(PyPI,2026-06-25),paddlex/configs/pipelines/PP-StructureV3.yaml:默认模型(第 25–233 行)、开关与 markdown_ignore_labels(4–20)、文本检测设置(112–117)、各类别的版面阈值(28–48)。另见 inference/pipelines/layout_parsing/pipeline_v2.py:1323-1378(concatenate_markdown_pages 返回 MarkdownResult)和 inference/common/result/mixin.py:69-84(save_to_word)。
  4. paddleocr.dev 测试,2026-10-27:Linux x86-64,4 vCPU Intel Xeon @ 2.10 GHz,15 GB 内存,无 GPU,Python 3.13,paddlepaddle 3.2.0,paddleocr 3.7.0,paddlex 3.7.2。脚本和原始输出(Markdown + JSON)见 _src/data/bench/structure/;样例图片见 /assets/samples/invoice.webp 和 /assets/samples/paper-page.webp。
  5. PaddleOCR README.md:PP-StructureV3 的定位与单元格级坐标(第 41 行)、3.5.0 版于 2026-04-21 新增 DOCX 导出(97、101);3.0 版发布于 2025-05-20(docs/update/update.en.md:128,134)。
  6. PP-StructureV3 算法文档,docs/version3.x/algorithm/PP-StructureV3/PP-StructureV3.en.md:本地速度测试(305–921)、服务化测试(922–950)、280 张图片的产线基准(952–1497)、CPU 常见问题中的“约 3.74 秒”(1518)。均为官方数据。
  7. OmniDocBench README,v1_5 分支(opendatalab/OmniDocBench):PP-StructureV3 总分 86.73,第 806–817 行。第三方数据。
  8. PP-OCRv6 语言覆盖,docs/version3.x/algorithm/PP-OCRv6/PP-OCRv6.en.md:3:medium 和 small 用一个模型识别 50 种语言。
  9. 2.x → 3.x 参数映射:paddleocr/_common_args.py:52-54(“Unknown argument”)、docs/update/upgrade_notes.en.md:73、paddleocr 2.10.0 的 ppstructure/utility.py,以及命令行 --save_path 的行为 paddleocr/_utils/cli.py:41-45,68-73;汇总于我们的 迁移指南。
更新于 2026年10月27日·我们如何核实