DayBreak-u / chineseocr_lite

超轻量级中文ocr,支持竖排文字识别, 支持ncnn、mnn、tnn推理 ( dbnet(1.8M) + crnn(2.5M) + anglenet(378KB)) 总模型仅4.7M
GNU General Public License v2.0
11.8k stars 2.26k forks source link

关于GPU版本的Ort要比基于CPU版本的慢大约10倍左右 #314

Open onlyhantenghao opened 3 years ago

onlyhantenghao commented 3 years ago

如题,在部署并验证之后发现,基于Ort_GPU的版本端到端的推理要比基于Cpu版本的慢10倍左右,我不确定问题出在哪里,请问各位有没有什么想法?

DayBreak-u commented 3 years ago

可能是gpu模型加载比较慢

onlyhantenghao commented 3 years ago

可能是gpu模型加载比较慢

不太可能吧,模型的初始化和推理是分开的,测试是仅仅针对于推理 auto outputTensor = session.Run(Ort::RunOptions{nullptr}, NetInputNames.data(), &inputTensor, NetInputNames.size(), NetOutputNames.data(), NetOutputNames.size()); ,也就是只对比这一行的耗时。 考虑到可能是不是输入的影响,我对多张输入推理进行平均,结果大约慢4倍左右。

zwfcrazy commented 3 years ago

我也对比了一下cpu和gpu,发现几个点:

  1. 每张图第一次跑都很慢,第二次就快了。而且这和pytorch那种第一次跑比较慢不一样,这是每张图的第一次都慢。举个栗子,按下列顺序测试图片:
    • 图片1,需要跑几秒钟
    • 图片1,只要跑0.几秒
    • 图片2,需要跑几秒钟
    • 图片2,只要跑0.几秒
    • 图片1,只要跑0.几秒
  2. 如果不看一张图的第一次运行时间,而只看第二次的话,可以发现:
    • 目标检测gpu比cpu快
    • 角度检测和文字识别gpu比cpu慢

感觉这里面有不少内存和显存之间数据搬运的问题。可能作者写的时候就没有给gpu优化?

toxic-0518 commented 3 years ago

对比了下 onnxruntime==1.4.0 & onnxruntime-gpu==1.4.0 检测毫无疑问是gpu快, cpu大约1.1s, gpu大约0.1s 识别模型,我对图片中每一个文字区域进行了时间分析, 发现gpu普遍比cpu慢,以及gpu每run几次就会出现单行识别时间>0.4s的情况,尝试将图片宽度fix住(crop/padding)问题仍存在 用可视化工具看了下onnx的结构没发现什么问题,尝试把onnx转成pb或者其他模型测试,但失败了。不知作者能否提供下原始的模型,我这边看看问题。

toxic-0518 commented 3 years ago

给一个降级解决方案吧 如果要用gpu去infer的话可以这样做:

  1. requirements.txt中的onnxruntime==1.4.0 -> onnxruntime-gpu==1.4.0
  2. CRNN.py中handler初始化的地方改下代码

class CRNNHandle: def init(self, model_path): self.sess = rt.InferenceSession(model_path) self.sess.set_providers([self.sess.get_providers()[1]]) # 强制指定用CPU识别


检测部分不变
这样会快不少
hello2mao commented 2 years ago

+1 mark

Object1009 commented 9 months ago

解决了吗?我在C++版本的ONNXRuntime也遇到了同样的问题

chl916185 commented 9 months ago
  1. 第一次慢,从第二次开始快:应该是硬件从休眠状态warmup,比如cpu从低功耗低频状态提升到正常状态。
  2. db适合用gpu,而angle和crnn正好相反、用CPU更快。

针对第一点,怎么做啊,让cpu到正常状态

pengcheng001 commented 5 months ago

其实应该是这样的,第一次推理会有缓存,把缓存记录下来,再推理的时候,速度就快了,如果换个shape推理,又会慢。所以也不是前面的人说的硬件启动之类的

mcmy commented 5 months ago

解决了吗?我在C++版本的ONNXRuntime也遇到了同样的问题

我今天测试也遇到了这个问题,识别屏幕第一次花了31秒,第二次花了300毫秒,调试下来发现原因det模型会根据传入图片大小调整输入层,rec的shape会根据单条文本长度而变化,每个不同长度的文本和不同大小的图片都需要重复初始化gpu,如果不考虑极致性能可以把图片处理为同一大小,rec也处理为同一大小(图片宽度不足则末尾补充黑色)再进行识别 image image