PaddleOCR-VL-1.6_Demo/README.md

234 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ocr-VL1.6
本地部署 [PaddlePaddle/PaddleOCR-VL-1.6](https://github.com/PaddlePaddle/PaddleOCR) 的实验项目,包含已实测的 CPU 版本和独立隔离、待 NVIDIA GPU 验证的 GPU 版本。
> 在线 Demo: [HuggingFace Space](https://huggingface.co/spaces/PaddlePaddle/PaddleOCR-VL-1.6_Online_Demo) · 模型权重: [HuggingFace](https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.6)
## 项目结构
```
ocr-VL1.6/
├── main.py # CPU 单图 OCR + Benchmark
├── batch_ocr.py # CPU 批量 OCR系统友好的多进程版本
├── pyproject.toml # CPU 项目依赖
├── uv.lock # CPU 锁文件
├── gpu/ # 独立 GPU 子项目
│ ├── main.py # GPU 单图 Benchmark
│ ├── verify_env.py # CUDA 环境与计算验证
│ ├── setup_env.py # 按 CUDA Wheel 类型创建环境
│ ├── pyproject.toml # GPU 独立依赖
│ ├── .python-version # GPU 使用 Python 3.11
│ └── README.md # GPU 安装与运行说明
├── benchmarks/
│ └── gpu/ # GPU Benchmark JSON 输出目录
├── images/
│ └── 手写01.png # 测试图片手写中文1758×646
└── README.md
```
## 技术栈
| 组件 | 版本 | 说明 |
| ---------------- | ----- | ---------------------------------------- |
| PythonCPU | 3.13 | 根目录独立环境 |
| PythonGPU | 3.11 | `gpu/` 独立环境,提升 GPU Wheel 兼容性 |
| PaddlePaddle | 3.2.1 | CPU 使用 `paddlepaddle`GPU 使用 `paddlepaddle-gpu` |
| PaddleOCR | 3.7.0 | 带 `doc-parser` extra |
| PaddleOCR-VL-1.6 | 0.9B | 主 OCR 视觉语言模型(~1.8GB |
| PP-DocLayoutV3 | - | 版面检测模型(~126MB |
模型缓存目录:`~/.paddlex/official_models/`
## 快速开始
### 前提条件
- Python ≥ 3.13
- [uv](https://github.com/astral-sh/uv) 包管理器
### 安装
```bash
uv sync
```
### 运行
```bash
# 单张图片 OCR自动使用全部 CPU 核心)
uv run python main.py
# 批量 OCR多进程并行安全默认值
uv run python batch_ocr.py images/
```
首次运行会自动从 ModelScope 下载模型文件(约 2GB后续使用缓存。
### GPU 子项目
> **状态:已实现、未实测。** 当前开发机器只有集成显卡,不能运行 NVIDIA CUDA。GPU 代码已通过语法、CLI 和无 CUDA 安全退出检查,但安装兼容性、显存占用和性能数据必须在目标 NVIDIA GPU 机器上验证。
CPU 与 GPU 使用不同虚拟环境,禁止在根目录 CPU `.venv` 中安装 `paddlepaddle-gpu`
```bash
# 查看 GPU 安装命令,不实际安装
python gpu/setup_env.py --cuda cu118 --dry-run
# 在目标 NVIDIA GPU 机器创建 gpu/.venv根据官方兼容表选择 cu118 或 cu126
python gpu/setup_env.py --cuda cu118
# 检查 CUDA 构建、GPU 设备和矩阵乘法
uv run --project gpu python gpu/verify_env.py
# 运行 GPU 单图 Benchmark
uv run --project gpu python gpu/main.py --warmup 1 --rounds 3
```
GPU Benchmark JSON 写入 `benchmarks/gpu/`。详细说明见 [`gpu/README.md`](gpu/README.md)。
## 工作原理
`PaddleOCRVL` pipeline 分两阶段:
```
输入图片 → [PP-DocLayoutV3 版面检测] → [PaddleOCR-VL-1.6-0.9B 文字识别] → 结构化输出
```
1. **版面检测** — PP-DocLayoutV3 检测页面中的文本块区域(坐标 + 标签 + 置信度)
2. **OCR 识别** — PaddleOCR-VL-1.6-0.9BGQA 架构视觉语言模型)逐块识别文字
3. **结果输出** — 返回 `PaddleOCRVLResult`,包含布局信息和识别文本
### 输出结构
| 字段 | 类型 | 说明 |
| ---------------------- | ---------------------- | ------------------------------------------------------------ |
| `layout_det_res.boxes` | list[dict] | 版面文本区域cls_id, label, score, coordinate, polygon_points |
| `parsing_res_list` | list[PaddleOCRVLBlock] | 识别文本块($.label, $.bbox, $.content, $.polygon_points |
| `model_settings` | dict | 推理配置开关(版面检测/图表/印章等) |
| `width` / `height` | int | 图片尺寸 |
## 性能优化迭代
测试机器Windows 11, CPU 20 核(逻辑线程), RAM 32GB, PaddlePaddle 3.2.1 CPU
### 迭代 0初始状态无任何优化
直接调用 `pipeline.predict()`,未设置任何线程参数。
| 阶段 | 耗时 |
| ----------------------- | --------------- |
| 模型初始化(加载权重) | ~60s |
| 首次推理(含 JIT 编译) | ~285s |
| 后续推理 | ~238s~4 min |
### 迭代 1算子级并行 — `core.set_num_threads()`
**探索过程:**
| 尝试 | 方法 | 结果 |
| ---- | -------------------------------------------------- | ---------------------------------------------------- |
| ❌ | `paddle.set_num_threads()` | Paddle 3.x 已移除该 API |
| ❌ | 环境变量 `OMP_NUM_THREADS` / `MKL_NUM_THREADS` | Paddle 3.x 内部使用 oneDNN不读取这些变量 |
| ✅ | `from paddle import core; core.set_num_threads(N)` | **有效!** oneDNN 底层算子matmul 等)受该 API 控制 |
**矩阵乘法微基准测试4000×4000**
| 线程数 | 耗时 (matmul) | 加速比 |
| ------ | ------------- | -------- |
| 1 | 0.952s | 1.0x |
| 4 | 0.419s | 2.3x |
| 8 | 0.323s | 2.9x |
| 16 | 0.240s | 4.0x |
| **20** | **0.223s** | **4.3x** |
**应用到 OCR 后的实际效果:**
设置 `core.set_num_threads(20)` 后重新评测:
| 阶段 | 优化前 | 优化后 | 提速 |
| ---------- | ------ | --------------------- | -------- |
| 模型初始化 | ~60s | ~40s | 1.5x |
| 推理 | ~238s | **~162s~2.7 min** | **1.5x** |
**为什么不是 4.3x** 矩阵乘法只是 OCR pipeline 的一部分。自回归解码(逐 token 生成天然串行、I/O 等待、版面检测中的非矩阵运算等不受线程数影响。
---
### 迭代 2批量多进程并行 — `batch_ocr.py`
**思路:** 多张图片时,用 `multiprocessing.Pool` 启动多个独立进程,每个进程加载一份 pipeline 实例,同时处理不同图片。
**遇到的问题 & 修复(迭代 2.1**
| 问题 | 原因 | 修复 |
|------|------|------|
| 系统卡顿/黑屏/无响应 | `Pool.starmap` 同时启动 N 个进程,同步加载 N×2GB 模型CPU + 内存瞬间打满 | ① 进程错峰启动(随机延迟 0~15s`psutil` 降低进程优先级 ③ 预留 1 核给 OS ④ `imap_unordered` 替代 `starmap` |
**策略:**
- 每个子进程独立调用 `core.set_num_threads((总核心-1) / 进程数)`,预留核心给 OS
- 例如 2 进程 × 9 线程 = 18 核,留 2 核给系统
- `--stagger` 控制错峰窗口,默认 15s
```bash
# 2 进程并行(安全默认值)
uv run python batch_ocr.py images/
# 4 进程并行(需 32GB+ RAM
uv run python batch_ocr.py images/ --workers 4
# 自定义错峰窗口(值越大内存峰值越低,但总耗时增加)
uv run python batch_ocr.py images/ --workers 4 --stagger 30
```
| 配置 | 适用场景 | 理论加速比 | 内存开销 | 实际限制 |
| -------------------- | -------- | --------------- | ---------- | -------------- |
| `set_num_threads(N)` | 单张图片 | ~1.5x | 无额外开销 | 自回归解码瓶颈 |
| `batch_ocr.py` | 批量多图 | ~NxN=进程数) | N × 2GB | 内存/内存带宽,需错峰避免打满系统 |
> ⚠️ 每个进程独立加载模型(~2GB32GB RAM 建议从 `--workers 2` 开始测试。默认值是相对保守配置,但是否稳定仍取决于可用内存、散热、后台应用和图片复杂度。
---
### 迭代 3独立 GPU 子项目(待实机验证)
为避免 `paddlepaddle``paddlepaddle-gpu` 相互覆盖,在同一仓库新增 `gpu/` 子项目,使用独立 Python、虚拟环境、依赖配置和锁文件。
已完成:
- `gpu/setup_env.py`:根据 `cu118` / `cu126` Wheel 索引创建环境
- `gpu/verify_env.py`:检查 CUDA 构建、设备数量并执行 GPU 矩阵乘法
- `gpu/main.py`:显式指定 `device="gpu:N"`,支持预热、多轮计时和 JSON 输出
- 无 CUDA 时立即退出,不静默回退到 CPU
- CPU 环境下已通过 Python 语法、CLI 和安全退出检查
尚未验证:
- NVIDIA 驱动、CUDA Wheel 与目标 GPU 的兼容性
- PaddleOCR-VL-1.6 GPU 模型初始化是否正常
- GPU 显存峰值和真实推理速度
- FP16/BF16、TensorRT 或批量推理收益
---
### 优化总结
| 迭代 | 状态 | 结果 |
|------|------|------|
| CPU 初始版本 | 已实测 | 后续单图约 238s |
| CPU `set_num_threads(20)` | 已实测 | 单图约 162s约 1.5x 加速 |
| CPU 多进程批量 | 已实现,稳定性依机器而定 | 理论提升批量吞吐;当前没有足够的可靠实测数据支持固定加速比 |
| 独立 GPU 子项目 | 已实现,未实机验证 | 等待 NVIDIA CUDA GPU 测试 |
> CPU 单图当前实测约 2.7 分钟。批量多进程主要提高总吞吐不会缩短某一张图片自身的推理延迟。GPU 性能在实机验证前不作预测。
## 已知局限
| 问题 | 影响 | 说明 |
| ------------------ | ----------------------- | ------------------------------------- |
| CPU 推理极慢 | 单图 ~2.7 min优化后 | 0.9B VL 模型不适合 CPU 实时场景 |
| 自回归解码串行 | 无法更细粒度并行 | 生成阶段逐 token 依赖,多线程收益有限 |
| 内存占用大 | 每进程需 ~2GB | 限制了 `batch_ocr.py` 并行度 |
| Windows 控制台乱码 | 中文输出显示为乱码 | GBK 编码问题,文件写入/pipe 正常 |
| GPU 未实机验证 | 暂无 GPU 性能结论 | 当前机器只有集成显卡,需 NVIDIA CUDA GPU 验证 |
| ccache 警告 | 无实际影响 | 仅影响首次编译加速,可忽略 |