PP-DocLayoutV3 与 PaddleOCR-VL-1.5 的组合,是百度飞桨针对复杂文档解析场景推出的高性能联合流水线。其中,PaddleOCR-VL-1.5 本身采用两阶段架构:第一阶段使用 PP-DocLayoutV2 进行版面分析与阅读顺序预测,第二阶段由 PaddleOCR-VL-0.9B 多模态模型完成精细识别与结构化输出。将第一阶段替换为 PP-DocLayoutV3,即可获得更强、更精准的联合解析能力。
| 配套 | 版本 |
|---|---|
| 固件与驱动 | 25.5.1 |
| CANN | 8.5.1 |
| Python | 3.11 |
| 推荐使用镜像 | v0.19.1rc1 |
# 定义要使用的 Docker 镜像(Ascend NPU 环境的 vLLM 镜像)
export IMAGE=quay.io/ascend/vllm-ascend:v0.19.1rc1
# 启动 Docker 容器
# 参数说明:
# --name PaddleOCR-VL-1.5 : 容器名称
# --shm-size=1g : 共享内存大小(防止内存不足)
# --net=host : 使用主机网络模式(便于容器内外通信)
# --device /dev/davinci4 : 挂载 NPU 设备(根据实际可用设备调整)
# --device /dev/davinci_manager : NPU 管理设备
# --device /dev/devmm_svm : 共享虚拟内存设备
# --device /dev/hisi_hdc : HiSilicon 调试通道设备
# -v /usr/local/dcmi : 挂载 DCMI 工具(设备监控)
# -v /usr/local/Ascend/driver : 挂载 Ascend 驱动文件
# -v /root/.cache : 挂载模型缓存目录(vLLM 自动下载模型到此处)
docker run -itd \
--name PaddleOCR-VL-1.5 \
--shm-size=1g \
--net=host \
--device /dev/davinci0 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v /root/.cache:/root/.cache \
$IMAGE bash
# 进入已启动的容器({container_id} 替换为实际容器ID或使用容器名)
docker exec -it PaddleOCR-VL-1.5 /bin/bashvllm启动服务时可自动下载模型权重至/root/.cache/目录下,如果离线环境不方便下载,也可手动下载准备
modelscope download --model PaddlePaddle/PaddleOCR-VL-1.5 --local_dir /workspace/PaddleOCR-VL-1.5# 环境变量配置
export VLLM_USE_MODELSCOPE=True # 启用 ModelScope 模型下载支持
export MODEL_PATH="/workspace/PaddleOCR-VL-1.5" # 模型本地路径(自动下载时可省略)
export TASK_QUEUE_ENABLE=1 # 启用任务队列(提高并发性能)
export CPU_AFFINITY_CONF=1 # 启用 CPU 亲和性绑定(优化性能)
export PYTORCH_NPU_ALLOC_CONF="expandable_segments:True" # NPU 内存分配策略
# 启动 vLLM 服务(后台运行)
# 参数说明:
# --max-num-batched-tokens 16384 : 单批次最大 token 数(影响吞吐量)
# --served-model-name : 服务对外暴露的模型名称
# --trust-remote-code : 允许执行模型中的自定义代码
# --no-enable-prefix-caching : 禁用前缀缓存(避免内存占用过高)
# --mm-processor-cache-gb 4 : 多模态处理器缓存大小(GB)
# --compilation-config : 编译配置(FULL_DECODE_ONLY 优化解码性能)
# --additional_config : 额外配置(启用 CPU 绑定)
# --port 8000 : 服务端口
vllm serve ${MODEL_PATH} \
--max-num-batched-tokens 16384 \
--served-model-name PaddleOCR-VL-1.5-0.9B \
--trust-remote-code \
--no-enable-prefix-caching \
--mm-processor-cache-gb 4 \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
--additional_config '{"enable_cpu_binding":true}' \
--port 8000 from openai import OpenAI
client = OpenAI(
api_key="EMPTY",
base_url="http://localhost:8000/v1",
timeout=3600
)
# Task-specific base prompts
TASKS = {
"ocr": "OCR:",
"table": "Table Recognition:",
"formula": "Formula Recognition:",
"chart": "Chart Recognition:",
}
messages = [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://ofasys-multimodal-wlcb-3-toshanghai.oss-accelerate.aliyuncs.com/wpf272043/keepme/image/receipt.png"
}
},
{
"type": "text",
"text": TASKS["ocr"]
}
]
}
]
response = client.chat.completions.create(
model="PaddleOCR-VL-1.5-0.9B",
messages=messages,
temperature=0.0,
)
print(f"Generated text: {response.choices[0].message.content}")成功输出:
Generated text: Auntie Anne's
CINNAMON SUGAR
1 x 17,000
SUB TOTAL
17,000
GRAND TOTAL
17,000
CASH IDR
20,000
CHANGE DUE
3,000# 启动 PP-DocLayoutV3 专用 Docker 容器
# 参数说明:
# --user root : 以 root 用户身份运行
# --name PP-DocLayoutV3 : 容器名称
# --privileged : 特权模式(允许访问设备)
# --shm-size 64g : 共享内存大小(布局检测需要较大内存)
# --network host : 主机网络模式
docker run -itd \
--user root \
--name PP-DocLayoutV3 \
--privileged \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/dcmi:/usr/local/dcmi \
--shm-size 64g \
--network host \
ccr-2vdh3abv-pub.cnc.bj.baidubce.com/paddlepaddle/paddleocr-vl:latest-huawei-npu \
/bin/bash
# 进入容器
docker exec -it PP-DocLayoutV3 /bin/bash
# 在容器内下载 PP-DocLayoutV3 模型(ModelScope)
# 模型将下载到 /workspace/PP-DocLayoutV3 目录
modelscope download --model PaddlePaddle/PP-DocLayoutV3 --local_dir /workspace/PP-DocLayoutV3from paddleocr import PaddleOCRVL
doclayout_model_path = "/workspace/PP-DocLayoutV3"
pipeline = PaddleOCRVL(vl_rec_backend="vllm-server",
vl_rec_server_url="http://localhost:8000/v1",
layout_detection_model_name="PP-DocLayoutV3",
layout_detection_model_dir=doclayout_model_path,
device="npu")
output = pipeline.predict("https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/paddleocr_vl_demo.png")
for i, res in enumerate(output):
res.save_to_json(save_path=f"output_{i}.json")
res.save_to_markdown(save_path=f"output_{i}.md")
# 预期output_0.json和output_0.md正确生成,且内容与图片相符
paddle原生模型在npu上性能较差,如需高性能模型需要使用OM模型
# ==============================================
# 说明:OM模型可以和PaddleOCR-VL-1.5使用同一个容器,但建议使用虚拟环境隔离
# ==============================================
docker exec -it PaddleOCR-VL-1.5 /bin/bash
# 1. 下载 ONNX 格式的 PP-DocLayoutV3 模型
# 模型将下载到 /workspace/PP-DocLayoutV3_onnx 目录
modelscope download --model PaddlePaddle/PP-DocLayoutV3_onnx --local_dir /workspace/PP-DocLayoutV3_onnx
# 2. 使用 ATC 工具将 ONNX 模型转换为 OM 模型
# 参数说明:
# --model : 输入的 ONNX 模型路径
# --framework=5 : 框架类型(5 表示 ONNX)
# --output : 输出的 OM 模型路径
# --soc_version : 目标芯片版本(Ascend910B3)
# --input_shape : 输入张量形状(动态批处理)
# --precision_mode_v2 : 精度模式(mixed_float16 混合精度)
atc --model=/workspace/PP-DocLayoutV3_onnx/inference.onnx \
--framework=5 \
--output=/workspace/PP-DocLayoutV3_onnx/inference \
--soc_version=Ascend910B3 \
--input_shape "im_shape:-1,2;image:-1,3,800,800;scale_factor:-1,2" \
--precision_mode_v2=mixed_float16
# 3. 安装系统依赖组件
apt-get update
apt-get install -y libgl1 libglib2.0-0 # 图像处理库
# 4. 创建并配置 Python 虚拟环境
# 下载并安装 Miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh -O miniconda.sh
chmod 777 miniconda.sh # 添加执行权限
bash miniconda.sh -b -p ~/miniconda3 # 静默安装 Miniconda
source ~/miniconda3/bin/activate # 激活 Miniconda
conda init bash # 初始化 conda(写入 .bashrc)
source ~/.bashrc # 刷新环境变量
# 创建名为 pplayout 的虚拟环境(Python 3.11.14)
conda create -n pplayout python==3.11.14 -y
conda activate pplayout # 激活虚拟环境
# 安装核心依赖包(使用阿里云镜像加速)
pip install -i https://mirrors.aliyun.com/pypi/simple/ \
paddleocr==3.4.0 \
paddlex[ocr]==3.4.3 \
paddlepaddle==3.2.2 \
numpy==1.26.4 \
openai==2.15.0
# 5. 安装 AIS Bench 推理工具(NPU 推理依赖)
wget https://aisbench.obs.myhuaweicloud.com/packet/ais_bench_infer/0.0.2/ait/ais_bench-0.0.2-py3-none-any.whl
wget https://aisbench.obs.myhuaweicloud.com/packet/ais_bench_infer/0.0.2/ait/aclruntime-0.0.2-cp311-cp311-linux_aarch64.whl
pip install ais_bench-0.0.2-py3-none-any.whl
pip install aclruntime-0.0.2-cp311-cp311-linux_aarch64.whl
# 6. 为 paddlex 打补丁(修复 NPU 兼容性问题)
git clone https://atomgit.com/Ascend-SACT/PP-DocLayoutV3_PaddleOCR-VL-1.5.git
cd PP-DocLayoutV3_PaddleOCR-VL-1.5
workdir=$(pwd) # 保存当前工作目录
source_path=$(pip show paddlex | grep Location | awk '{print $2}') # 获取 paddlex 安装路径
cd ${source_path}/paddlex # 进入 paddlex 目录
patch -p1 --dry-run < ${workdir}/paddlex.patch # 预检查补丁(可选)
patch -p1 < ${workdir}/paddlex.patch # 应用补丁
# 7. 测试单阶段布局检测
# 切换到 infer.py 所在的工作目录(替换为实际路径)
cd ${workdir} # 返回原工作目录
# 下载测试图片
wget https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/layout.jpg
# 运行推理(--image_dir 指定输入图片,--model_dir 指定 OM 模型目录)
python3 infer.py --image_dir layout.jpg --model_dir /workspace/PP-DocLayoutV3_onnx/预期结果: layout_res.jpg, layout_res.json 正确生成
(pplayout) root@syn-119:/workspace/output# ls
layout_res.jpg layout_res.jsonlayout_res.jpg 如下:

# 切换到 infer_e2e.py 所在的工作目录
cd /workspace/PP-DocLayoutV3_PaddleOCR-VL-1.5
python infer_e2e.py --vllm_ip http://127.0.0.1:8000/v1 --layout_detection_model_dir /workspace/PP-DocLayoutV3_onnx --data_dir ./demo.pdf
# 日志如下
# ========== Summary ==========
# Total files processed: 1
# Total time (s): 7.33
# Avg time per file (s): 7.325
# [INFO] unload model success, model Id is 2147483648
# [INFO] end to reset device 0
# [INFO] end to finalize acl# 激活 pplayout 虚拟环境(需先按 3.2.1 节完成环境配置)
conda activate pplayout
# 安装 openxlab 数据集下载工具
pip install openxlab
pip install -U openxlab
# 切换到工作目录
cd /workspace
# 进行登录,输入对应的 AK/SK
openxlab login
# 数据集信息及文件列表查看
openxlab dataset info --dataset-repo OpenDataLab/OmniDocBench
# 数据集下载
openxlab dataset get --dataset-repo OpenDataLab/OmniDocBench
# 数据集文件下载(按需下载单个文件)
openxlab dataset download --dataset-repo OpenDataLab/OmniDocBench --source-path /README.md --target-path ./
# 解压数据集 PDF 文件
unzip ./OpenDataLab___OmniDocBench/pdfs.zip
# 运行全量数据集推理
cd /workspace/PP-DocLayoutV3_PaddleOCR-VL-1.5
python test.py --data_dir /workspace/OpenDataLab___OmniDocBench/pdfs --model_dir /workspace/PP-DocLayoutV3_onnx/
# ========== Summary ==========
# Total files processed: 1614
# Total time (s): 9256.76
# Avg time per file (s): 5.735
# 整理输出结果
mkdir -p output/pdfs/end2end
cp output/pdfs/*.md /output/pdfs/end2end
for f in output/pdfs/end2end/*_0.md; do mv "$f" "${f%_0.md}.md"; done
# 评测时需要指定 OmniDocBench 的 JSON 标注文件路径
# 路径示例:/workspace/OpenDataLab___OmniDocBench/OmniDocBench.json注意:登录时需要输入 Access Key 和 Secret Key。
| 组件 | 版本 |
|---|---|
| Python | 3.10.x |
| TeX Live | 2025 |
| pdflatex | 3.141592653-2.6-1.40.28 |
| ImageMagick | 7.1.1-47 |
| Ghostscript | 9.55.0 |
# 可以和PP-DocLayoutV3使用同一个容器,但是需要虚拟环境隔离
# 1. 创建并激活评测专用虚拟环境
conda create -n omnidocbench python=3.10 -y
conda activate omnidocbench
# 2. 克隆 OmniDocBench 评测工具并安装
cd /workspace
git clone https://github.com/opendatalab/OmniDocBench.git && cd OmniDocBench
pip install -e .
python -c "from src.core.pipeline import run_config_file; print('OK')"
# 3. 安装 TeX Live(推荐使用离线安装)
wget -c -t 0 https://mirrors.huaweicloud.com/CTAN/systems/texlive/Images/texlive2025.iso
apt-get update && apt-get install -y libarchive-tools
mkdir texlive-iso
bsdtar -x -f texlive2025.iso -C texlive-iso
cd texlive-iso && ./install-tl # 如果需要 root 权限,加 sudo(但容器内通常已经是 root)
echo 'export PATH=/usr/local/texlive/2025/bin/aarch64-linux:$PATH' >> ~/.bashrc
source ~/.bashrc
# 验证 TeX Live 安装
pdflatex --version | head -2
# 预期显示
# pdfTeX 3.141592653-2.6-1.40.29 (TeX Live 2025)
# kpathsea version 6.4.2
kpsewhich CJK.sty && kpsewhich c70gkai.fd
# 预期显示
# /usr/local/texlive/2025/texmf-dist/tex/latex/cjk-utf8/CJK.sty
# /usr/local/texlive/2025/texmf-dist/tex/latex/cjk-utf8/c70gkai.fd
# 4. 安装 ImageMagick 依赖
apt-get install -y build-essential pkg-config \
libjpeg-dev libpng-dev libtiff-dev libwebp-dev \
libfreetype6-dev libfontconfig1-dev
# 5. 编译安装 ImageMagick
cd /tmp
wget https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.1-47.tar.gz
tar xzf 7.1.1-47.tar.gz && cd ImageMagick-7.1.1-47
./configure --with-modules --enable-shared --with-gslib \
--with-gs-font-dir=/usr/share/fonts/type1/gsfonts --prefix=/usr/local
make -j$(nproc) && make install && ldconfig
magick --version | head -2 # 预期: ImageMagick 7.1.1-47
# 允许 PDF 读写
POLICY_FILE=$(find /usr/local/etc/ImageMagick-7 -name policy.xml 2>/dev/null | head -1)
[ -n "$POLICY_FILE" ] && sed -i \
's|<policy domain="coder" rights="none" pattern="PDF" />|<policy domain="coder" rights="read\|write" pattern="PDF" />|' \
"$POLICY_FILE"
# 6. 切换回 OmniDocBench 目录运行评测
cd /workspace/OmniDocBench
# 验证环境
python -m pytest tools/test_environment_and_smoke.py::TestEnvironmentVersions -v -s # 预期没有 failed
# 运行端到端评测
python pdf_validation.py --config configs/end2end.yaml
# configs/end2end.yaml里面的
# 计算整体指标
python overall_metric.py| 模式 | text_block_Edit_dist | display_formula_CDM | table_TEDS | table_TEDS_structure_only | reading_order_Edit_dist | overall |
|---|---|---|---|---|---|---|
| end2end | 0.106 | 88.555 | 88.975 | 91.558 | 0.187 | 88.976667 |