Repository navigation
Description
Checklist:
- 查找历史相关issue寻求解答
- 翻阅FAQ
- 翻阅PaddleX 文档
- 确认bug是否在新版本里还未修复
描述问题
该问题由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 检测模型没登记。
也就是说同一份文件里,同类模型一半登记了一半没登记。
复现
- 您是否已经正常运行我们提供的教程?
是,就是教程里的 PPStructureV3 用法,未改代码逻辑。
- 您是否在教程的基础上修改代码内容?还请您提供运行的代码
修改的代码 / 最小复现(不需要 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"))- 您使用的数据集是?
任意飞猪 App agent客服对话长截图(1170×9744 等),无特殊要求;任意图片均可复现。
- 请提供您出现的报错信息及相关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
加速,属于缓解而非修复。
环境
- 请提供您使用的PaddlePaddle和PaddleX的版本号
PaddlePaddle 3.3.1(CPU build)、PaddleX 3.7.2、paddleocr 3.7.0
- 请提供您使用的操作系统信息,如Linux/Windows/MacOS
Linux x86_64(python:3.11.11-slim 容器)
- 请问您使用的Python版本是?
Python 3.11.11
- 请问您使用的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 可用性问题:
- 同一份结果里字段命名不一致:
res["layout_det_res"]["boxes"]用label,
而res["parsing_res_list"]用block_label/block_content/block_id。
照label写就永远取不到值。 result.html没有文档化的形状:实际是{"table_1": "<html>…"}(键为
table_<block_id>),但没有任何字段说明;早期代码按result.html["res"]读,
KeyError 被静默吞掉,表格内容全丢。- 失败是静默的:
layout检测失败只打一条WARNING就回退;表格 HTML 取不到时
返回空字符串而没有异常。下游拿到的都是“成功但内容为空/降级”的结果。
第 3 点最伤:我们这边因此出现过「表格图 → OCR 产出 0 字符 → 后续阶段格式化空文档」
的链路,属于最难发现的一类缺陷。建议 PaddleX 在结果里显式暴露 degraded / fallback
标志,或至少在返回空内容时抛异常。
Activity
biqiliu commentedon Oct 23, 2026
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.