ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

PP-OCRv5 移动端 ONNX 推理加速实战:4 个数据流阶段,把单行识别压回毫秒级

2026/8/24 1:12:24 拓冰建站 浏览量
PP-OCRv5 移动端 ONNX 推理加速实战:4 个数据流阶段,把单行识别压回毫秒级 PP-OCRv5 移动端 ONNX 推理加速实战4 个数据流阶段把单行识别压回毫秒级【免费下载链接】ta_PP-OCRv5_mobile_rec_onnx项目地址: https://ai.gitcode.com/paddlepaddle/ta_PP-OCRv5_mobile_rec_onnx手机里做文档扫描一条文本行要识别 800 毫秒用户的手指已经开始滑动了。慢的往往不是模型权重而是预处理、shape 配置、解码链路这些模型之外的环节。PP-OCRv5 移动端 ONNX 推理加速这件事拆开看就是四段数据流进图 → 推理 → 解码 → 调度。本文按这条链路逐段讲瓶颈和改法配置都能直接落到inference.yml里。项目速览与快速上手3 分钟跑通第一次推理ta_PP-OCRv5_mobile_rec_onnx是飞桨 PaddlePaddle 旗下 PP-OCRv5 移动端文字识别rec 阶段模型的 ONNX 版本。仓库里只有三个文件inference.onnx模型权重、inference.yml预处理、后处理、推理引擎的完整配置、README.md。它负责已裁剪的文本行 → 字符串这一环通常接在上游检测模型的输出后面。先 clone 下来用 onnxruntime 喂一张 48 像素高的输入验证模型能跑通git clone https://gitcode.com/paddlepaddle/ta_PP-OCRv5_mobile_rec_onnx cd ta_PP-OCRv5_mobile_rec_onnx再跑一段最小推理脚本确认输入输出维度符合预期import numpy as np import onnxruntime as ort sess ort.InferenceSession(inference.onnx) x np.random.randn(1, 3, 48, 320).astype(np.float32) # batch1高固定 48 out sess.run(None, {sess.get_inputs()[0].name: x}) print(out[0].shape) # (1, T, 229)T 个时间步229 228 个字符 CTC blank能打印出 shape链路就算通了。下面四个阶段的优化目标只有一个让这张图从进模型到吐出字符每一步都不做无用功。按数据流拆解移动端 ONNX 推理加速的 4 个阶段精简 OCR 预处理 Pipeline固定 48 像素高去掉多余的颜色转换这一段的瓶颈是每帧都在做颜色空间转换和动态 resize纯 CPU 开销却经常占到总耗时的 15% 以上。inference.yml里的预处理链已经给出了答案重点看这两项配置PreProcess: transform_ops: - DecodeImage: channel_first: false # 保持 HWC少一次转置 img_mode: BGR # 模型按 BGR 训练免 RGB 转换 - RecResizeImg: image_shape: [3, 48, 320] # 高固定 48宽按比例缩放为什么这样做img_mode: BGR让解码结果直接对齐模型训练时的色彩空间省掉每帧一次的 RGB 拷贝channel_first: false让数据以 HWC 进引擎避免在 Python 层做transpose高度锁死 48、宽度按长宽比缩放并截断到上限模型永远看到标准姿态的文本行。预期收益预处理阶段耗时约降 20%长宽比极端的图还能避免识别退化。预处理理顺之后下一站是耗时真正的大头——推理本身。配置 TensorRT 动态 shape 档位消除运行时重编译推理段的瓶颈在动态宽度文本行从 160 像素到 3200 像素都有不声明 shape profileTRT 遇到没见过的宽度就要现场编译引擎首帧卡顿换个宽度又卡顿一次。仓库配置用 min/opt/max 三档把宽度区间钉死Hpi: backend_configs: paddle_infer: trt_dynamic_shapes: x: - - [1, 3, 48, 160] # min短文本行 - - [1, 3, 48, 320] # opt最常见的宽度 - - [8, 3, 48, 3200] # max长图 批量三档的含义min 覆盖最短输入opt 对准高频宽度让 TRT 优先为该档生成最优 kernelmax 兜住长文档和批处理场景。运行时所有宽度都落在 profile 之内走kernel 选择而不是重新编译。预期收益首帧从数百毫秒的编译耗时降到预热后的几十毫秒稳态推理提速约 40%具体幅度视 GPU 型号而定。优化 CTC 解码路径查表只构建一次解码段的瓶颈随文本变长而放大输出序列有 T 个时间步如果每步都去 228 个字符的字典里做字符串比较查找宽 1280 的长文本解码耗时能追上推理本身。inference.yml的后处理指定的是CTCLabelDecode字典共 228 个字符输出 229 类含 blank。代码侧只守一条原则——字典表进程启动时构建一次之后全部走整数索引chars list(char_dict) # 启动时构建一次之后只做整数下标 prev -1 for t in range(T): c int(logits[t].argmax()) if c ! BLANK and c ! prev: # 跳过 CTC blank 与连续重复 text.append(chars[c]) prev cCTC 的 blank 跳过和重复折叠规则天然适合流式处理每个时间步只有一次 argmax 加一次数组下标字典查找从 O(T×228) 次字符串比较降到 O(T) 次整数比较。预期收益长文本宽 1280 以上的解码耗时约减半短文本感知不明显但也不会回退。系统级调度预热、内存池与批处理取舍调度这段的瓶颈不在单帧耗时而在第一次和内存抖动冷启动时引擎加载加编译叠在第一帧上连续推理时中间 tensor 反复分配释放内存碎片越滚越大。三条可落地的做法启动时对 48×320 的标准图跑一次空推理做预热把 TRT 编译和 context 创建挪到用户不可见的时段中间 buffer解码后的图像、reshape 后的张量用内存池复用帧间隔的分配开销消失移动端延迟优先batch 固定为 1确需吞吐的离线场景再放大到 8正好对上配置里的 max 档位。收益主要体现在稳定性上首帧耗时降到预热后水平峰值内存下降视 batch 策略而定长会话不再出现周期性卡顿。实战走查一条 320 像素文本行的完整识别链路拿文档扫描里最常见的单行横排文字走一遍全链路上游检测框切出 1200×40 的条带 →DecodeImage解出 BGR 图 →RecResizeImg压到 48×320保持长宽比超限截断→ TRT 推理 →CTCLabelDecode折叠出字符串。同一台参考设备中端 ARM SoC下表为示例基准你的设备需要重测优化前后对照指标优化前默认配置优化后本文配置说明首帧耗时含 TRT 编译约 950 ms约 90 ms预热 shape profile稳态单帧宽 320约 68 ms约 24 ms预处理精简 kernel 命中 opt 档长文本宽 1280约 210 ms约 96 ms解码查表优化占比放大峰值内存约 46 MB约 29 MB内存池 batch1读这张表的关键在于优化前的大头是编译、拷贝、字符串查找三件与识别本身无关的事优化后耗时结构里推理占了绝对大头——这才是健康的状态。剩下能榨的空间在权重本身那就属于下面的进阶方向了。避坑清单、进阶方向与资源指引最容易踩的五个坑对照检查一遍只改了RecResizeImg的高度却没锁宽度上限极端长条图把 TRT 打回重编译——宽度上限要和 profile 的 max 档对齐把channel_first翻成 true 又在模型侧期望 HWC等于每帧多一次显式转置解码字典每帧重建228 个字符的字符串比较白白做几千次——表只在初始化时构建一次移动端上开 batch8 追吞吐延迟和峰值内存同时失控延迟敏感场景就该用 1在 Python 层用image.transpose()做 CHW 转换而不是让引擎按 HWC 吃数据、内部处理布局。进阶方向点到为止权重层面可以上 INT8 量化需要准备设备上的校准集PP-OCRv5 这类 CNNCTC 结构对 PTQ 比较友好模型层面可以蒸馏一个更小的学生模型替换inference.onnx引擎层面除了 TRT 路径还可以评估 MNN、NCNN 这类移动端推理库配置层里的预处理和后处理段可以直接复用。资源方面模型与全部配置就在仓库根目录inference.onnx和inference.yml改配置不用碰模型。更深的推理加速讨论可以去飞桨 PaddlePaddle 官方社区和 PaddleOCR 文档站搜ONNX 导出和TensorRT 动态 shape两个词基本能覆盖本文所有延伸问题。下一步动作先在自己目标设备上把优化前的基线测出来首帧加稳态各取 100 次均值再按四个阶段逐项改配置、逐项记录最后把前后对比数据贴到 PaddleOCR 社区讨论区——你的设备数据正好能补全视硬件而定的那部分。【免费下载链接】ta_PP-OCRv5_mobile_rec_onnx项目地址: https://ai.gitcode.com/paddlepaddle/ta_PP-OCRv5_mobile_rec_onnx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考