# paddleocr-vl-npu-optimization **Repository Path**: swner_admin/paddleocr-vl-npu-optimization ## Basic Information - **Project Name**: paddleocr-vl-npu-optimization - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-12-25 - **Last Updated**: 2025-12-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PaddleOCR-VL 华为昇腾 910A NPU 优化实战 将 PaddleOCR-VL 视觉语言模型部署到华为昇腾 910A NPU,推理时间从 **65秒优化到19秒**,提升 **3.4倍**。 ## 安装 ```bash pip install paddleocr-vl-npu ``` 或从源码安装: ```bash git clone https://gitee.com/swner_admin/paddleocr-vl-npu-optimization.git cd paddleocr-vl-npu-optimization pip install -e . ``` ## 快速使用 ```python from paddleocr_vl_npu import PaddleOCRVLNPU # 初始化(自动下载模型、应用NPU优化、预热) ocr = PaddleOCRVLNPU(device_id=0) # OCR识别 result = ocr.ocr("test.jpg", prompt="请识别图片中的文字") print(result) # 带耗时统计 result, elapsed = ocr.ocr_with_time("test.jpg") print(f"结果: {result}, 耗时: {elapsed:.2f}秒") ``` ## 命令行使用 ```bash # 基础使用 paddleocr-vl-npu /path/to/image.png # 指定提示词 paddleocr-vl-npu /path/to/image.png --prompt "请识别表格内容" # 指定NPU设备 paddleocr-vl-npu /path/to/image.png --device 0 ``` ## 性能对比 | 优化阶段 | 大图耗时 (2454×1322) | 提升 | |---------|---------------------|------| | 原版 (无优化) | ~65秒 | 基准 | | + dtype转换 + eager attention | ~60秒 | 1.08x | | + 预热 + KV cache | ~21秒 | 3.1x | | + npu_rms_norm | ~20秒 | 3.25x | | + npu_rotary_mul | ~19秒 | **3.4x** | ## 环境要求 - **硬件**: 华为昇腾 910A/910B NPU - **驱动**: CANN 8.0+ - **Python**: 3.10+ - **PyTorch**: 2.5.1 - **torch-npu**: 2.5.1 ## 文件说明 ### 核心文件 | 文件 | 说明 | 使用场景 | |-----|------|---------| | `paddleocr_vl_npu_ops.py` | **NPU算子优化版本(推荐)** | 生产环境使用,性能最优 | | `paddleocr_vl_optimized.py` | 基础优化版本 | 不依赖NPU专用算子时使用 | | `paddleocr_vl_exact.py` | 精确一致版本 | 需要与CPU结果完全一致时使用 | ### 补丁文件 | 文件 | 说明 | 使用方法 | |-----|------|---------| | `apply_npu_patch.py` | 模型补丁脚本v1 | `python apply_npu_patch.py /path/to/model` | | `apply_npu_patch_v2.py` | 模型补丁脚本v2(含SiLU) | `python apply_npu_patch_v2.py /path/to/model` | | `npu_ops_patch.py` | NPU算子补丁模块 | `import npu_ops_patch; npu_ops_patch.apply()` | | `exact_ops.py` | 精确一致算子实现 | `from exact_ops import ExactRMSNorm, ExactSiLU` | ### 测试文件 | 文件 | 说明 | 使用方法 | |-----|------|---------| | `benchmark_ops.py` | 算子性能测试 | `python benchmark_ops.py` | | `benchmark_accuracy.py` | 算子准确率测试 | `python benchmark_accuracy.py` | | `error_analysis.py` | 误差归因分析 | `python error_analysis.py` | --- ## 详细使用指南 ### 1. paddleocr_vl_npu_ops.py - NPU算子优化版(推荐) 集成了 `npu_rms_norm` 和 `npu_rotary_mul` 优化算子,性能最优。 ```python from paddleocr_vl_npu_ops import PaddleOCRVLNPUOptimized # 初始化 ocr = PaddleOCRVLNPUOptimized( model_path='/path/to/PaddleOCR-VL', # 模型路径 device_id=0 # NPU设备ID ) # 推理 result, elapsed = ocr.ocr( image_path='test.jpg', prompt='OCR', max_new_tokens=512 ) print(f"识别结果: {result}") print(f"耗时: {elapsed:.2f}秒") ``` 命令行: ```bash python paddleocr_vl_npu_ops.py /path/to/image.png "请识别文字" ``` ### 2. paddleocr_vl_optimized.py - 基础优化版 不依赖NPU专用算子,使用标准PyTorch实现。 ```python from paddleocr_vl_optimized import PaddleOCRVLNPU ocr = PaddleOCRVLNPU(device_id=0) result = ocr.ocr('test.jpg', prompt='OCR') ``` ### 3. apply_npu_patch.py - 应用模型补丁 直接修改模型文件,替换为NPU优化算子。 ```bash # 应用补丁 python apply_npu_patch.py ~/.paddlex/official_models/PaddleOCR-VL/modeling_paddleocr_vl.py # 补丁会自动备份原文件为 .backup ``` 补丁内容: - 替换 `Ernie4_5RMSNorm.forward` 为 `npu_rms_norm` - 优化 `apply_rotary_pos_emb_ernie` 使用 `npu_rotary_mul` ### 4. benchmark_ops.py - 性能测试 对比三种实现方式的性能差异。 ```bash python benchmark_ops.py ``` 输出示例: ``` 【1. RMSNorm 性能对比】 PyTorch 原生实现: avg=0.45ms npu_rms_norm 算子: avg=0.25ms >>> NPU 算子加速比: 1.78x 【2. RoPE 性能对比】 PyTorch 原生实现: avg=1.20ms npu_rotary_mul 算子: avg=0.31ms >>> NPU 算子加速比: 3.90x ``` ### 5. benchmark_accuracy.py - 准确率测试 验证NPU算子与PyTorch原生实现的数值一致性。 ```bash python benchmark_accuracy.py ``` 输出示例: ``` 【RMSNorm 准确率】 最大绝对误差: 0.000198 相对误差: 0.02% 结果: ✅ 通过 【RoPE 准确率】 最大绝对误差: 0.000000 结果: ✅ 完全一致 ``` ### 6. error_analysis.py - 误差归因 分析误差来源,找出精度损失的具体位置。 ```bash python error_analysis.py ``` --- ## 优化原理详解 ### 第一步:基础适配 (65秒 → 60秒) **问题1: 不支持 bfloat16** ```python # 昇腾910A不支持bfloat16,需要转换为float16 _original_to = torch.Tensor.to def patched_to(self, *args, **kwargs): if kwargs.get('dtype') == torch.bfloat16: kwargs['dtype'] = torch.float16 return _original_to(self, *args, **kwargs) torch.Tensor.to = patched_to ``` **问题2: 不支持 Flash Attention** ```python config = AutoConfig.from_pretrained(model_path, trust_remote_code=True) config._attn_implementation = 'eager' # 禁用Flash Attention ``` ### 第二步:推理优化 (60秒 → 21秒) **预热模型** - NPU kernel 预编译 ```python def _warmup(self): dummy = Image.new('RGB', (224, 224), 'white') self.ocr(dummy, "test", max_new_tokens=8) torch.npu.synchronize() ``` **启用 KV Cache** ```python output_ids = model.generate( **inputs, use_cache=True, # 关键! do_sample=False, ) ``` ### 第三步:NPU算子替换 (21秒 → 19秒) | 算子 | 用途 | 加速比 | 准确率 | |-----|------|-------|--------| | npu_rms_norm | RMSNorm层 | 1.78x | 误差<0.02% | | npu_rotary_mul | RoPE位置编码 | 3.90x | 完全一致 | | npu_silu | SiLU激活 | 0.82x (不推荐) | - | **替换 RMSNorm** ```python # 原始 PyTorch 实现 variance = x.pow(2).mean(-1, keepdim=True) output = weight * x * torch.rsqrt(variance + eps) # NPU 优化算子 output, _ = torch_npu.npu_rms_norm(x, weight, epsilon=eps) ``` **替换 RoPE** ```python # 原始 PyTorch 实现 def rotate_half(x): x1, x2 = x[..., :x.shape[-1]//2], x[..., x.shape[-1]//2:] return torch.cat((-x2, x1), dim=-1) q_embed = (q * cos) + (rotate_half(q) * sin) # NPU 优化算子 q_embed = torch_npu.npu_rotary_mul(q, cos, sin) ``` --- ## 三种实现方式对比 | 实现方式 | 说明 | 性能 | 准确率 | |---------|------|------|--------| | PyTorch原生 | 标准实现,torch_npu自动转换 | 基准 | 基准 | | torch_npu代理 | 自动映射到NPU | ~1.2x | 一致 | | NPU专用算子 | 手动调用华为优化算子 | ~2-4x | 一致/更高 | --- ## 常见问题 **Q: RuntimeError: does not support bfloat16** ```python # 使用dtype补丁转换为float16(已内置) ``` **Q: Flash Attention 报错** ```python config._attn_implementation = 'eager' ``` **Q: npu_add_rms_norm 不支持** ``` 910A不支持该算子,仅910B/910C可用 ``` **Q: 推理很慢** 1. 确保模型预热 2. 启用 KV cache 3. 限制输入图像大小 4. 使用 NPU 专用算子 --- ## 资源链接 - [PaddleOCR-VL 模型](https://huggingface.co/PaddlePaddle/PaddleOCR-VL) - [torch-npu 文档](https://gitee.com/ascend/pytorch) - [昇腾算子文档](https://www.hiascend.com/document) - [CANN 开发工具包](https://www.hiascend.com/software/cann) ## 作者 闫广庆 | 2024-12-24 ## License MIT