Skip to content

[Bug] PP-DocLayout-{L,M,S,_plus-L} 在 CPU 上崩溃:MKLDNN_BLOCKLIST 漏登记该族模型,PPStructureV3 静默回退 #5231

Open
biqiliu/PaddleX
#1

Description

Checklist:

描述问题

该问题由AI发现并且解决,以下包含AI生成内容

PPStructureV3(以及任何直接用 PP-DocLayout-* 的调用)在 CPU 上必然崩溃,因为 get_default_run_mode() 把这四个模型判给了 run_mode="mkldnn",而 Paddle 3.3.1 的 PIR→oneDNN 转换器不支持它们携带的 pir::ArrayAttribute<pir::DoubleAttribute> 属性

崩溃由 PPStructureV3 内部捕获,用户只能看到:

WARNING | Layout detection failed — falling back to PP-OCRv4 for all images

所以这是一个静默失效:接口照常返回文本,用户以为表格/卡片路由在工作,实际一直在走回退路径。
按 OCR_TABLE_DETECTION 之类的开关调参完全无效,因为失败发生在开关生效之前。

底层缺陷是 Paddle core 的(已由 Paddle#79749
跟踪,2026-09-08 至今 open)。但 PaddleX 侧有一个四行的独立修复,不需要等 core:
MKLDNN_BLOCKLIST 里已经登记了同族模型,唯独漏了这四个。


四个模型全部受影响

模型 结果
PP-DocLayout-L 崩
PP-DocLayout-M 崩
PP-DocLayout-S 崩
PP-DocLayout_plus-L 崩

为什么判定是 blocklist 漏登记(而不是用法问题)

paddlex/inference/models/runners/paddle_static/config/blocklists.py(release/3.7)里,
MKLDNN_BLOCKLIST 已经包含同族模型:

"Mask-RT-DETR-M", "Mask-RT-DETR-S",
"Co-Deformable-DETR-Swin-T", "Co-DINO-Swin-L",
"PP-DocLayoutV2", "PP-DocLayoutV3",
"SLANeXt_wired", "SLANeXt_wireless", "SLANet", "SLANet_plus",

注意这里的不一致:PPStructureV3 自己的依赖集里,表格识别模型
(SLANet_plus、SLANeXt_*)都已经登记了,唯独管道第一步就要跑的 layout 检测模型没登记。
也就是说同一份文件里,同类模型一半登记了一半没登记。

复现

  1. 您是否已经正常运行我们提供的教程?

是,就是教程里的 PPStructureV3 用法,未改代码逻辑。

  1. 您是否在教程的基础上修改代码内容?还请您提供运行的代码

修改的代码 / 最小复现(不需要 paddleocr、不需要 PPStructureV3 管道):

from paddlex import create_model

model = create_model(model_name="PP-DocLayout_plus-L")   # 换成 -L / -M / -S 同样崩
list(model.predict("any_screenshot.png"))
  1. 您使用的数据集是?

任意飞猪 App agent客服对话长截图(1170×9744 等),无特殊要求;任意图片均可复现。

  1. 请提供您出现的报错信息及相关log
NotImplementedError: (Unimplemented) ConvertPirAttribute2RuntimeAttribute
not support [pir::ArrayAttribute<pir::DoubleAttribute>]
  (at /paddle/paddle/fluid/framework/new_executor/instruction/onednn/onednn_instruction.cc:116)

create_model() 正常,崩在第一次 predict()。

已验证的修复

把四个模型名加入 MKLDNN_BLOCKLIST(运行期 monkeypatch 验证,等价于改那四行):

模型 打补丁前 打补丁后
PP-DocLayout-L 崩 OK, boxes=7
PP-DocLayout-S 崩 OK, boxes=8
PP-DocLayout_plus-L 崩 OK, boxes=10

另一种可行 workaround:PADDLE_PDX_ENABLE_MKLDNN_BYDEFAULT=False(对所有模型关闭 mkldnn)。
实测对 PP-OCRv4 路径几乎无代价(1.48 MB 长图 25.5 s vs 26.6 s),但它牺牲了其它模型的 mkldnn
加速,属于缓解而非修复。

环境

  1. 请提供您使用的PaddlePaddle和PaddleX的版本号

PaddlePaddle 3.3.1(CPU build)、PaddleX 3.7.2、paddleocr 3.7.0

  1. 请提供您使用的操作系统信息,如Linux/Windows/MacOS

Linux x86_64(python:3.11.11-slim 容器)

  1. 请问您使用的Python版本是?

Python 3.11.11

  1. 请问您使用的CUDA/cuDNN的版本号是?

CUDA/cuDNN:无(纯 CPU)

建议

在 MKLDNN_BLOCKLIST 中补上:

"PP-DocLayout-L",
"PP-DocLayout-M",
"PP-DocLayout-S",
"PP-DocLayout_plus-L",

顺带建议:PPStructureV3 在 layout 检测失败时,除了 WARNING 之外应把“已回退”状态
暴露到返回结果或至少提升日志级别(PPStructureV3 用户默认拿到的是降级输出而不知情)。

附:PaddleX 结果对象的三处不一致

做下游集成时踩到的,和 blocklist 是两件独立的事,但同属一个 API 可用性问题:

  1. 同一份结果里字段命名不一致:res["layout_det_res"]["boxes"] 用 label,
    而 res["parsing_res_list"] 用 block_label / block_content / block_id。
    照 label 写就永远取不到值。
  2. result.html 没有文档化的形状:实际是 {"table_1": "<html>…"}(键为
    table_<block_id>),但没有任何字段说明;早期代码按 result.html["res"] 读,
    KeyError 被静默吞掉,表格内容全丢。
  3. 失败是静默的:layout 检测失败只打一条 WARNING 就回退;表格 HTML 取不到时
    返回空字符串而没有异常。下游拿到的都是“成功但内容为空/降级”的结果。

第 3 点最伤:我们这边因此出现过「表格图 → OCR 产出 0 字符 → 后续阶段格式化空文档」
的链路,属于最难发现的一类缺陷。建议 PaddleX 在结果里显式暴露 degraded / fallback
标志,或至少在返回空内容时抛异常。

Activity

  1. biqiliu commented on Oct 23, 2026

    @biqiliu

    Hi maintainers, I've opened PR #5234 adding the four missing model names (PP-DocLayout-L/M/S/plus-L) to MKLDNN_BLOCKLIST. Please review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions