gpt4 book ai didi

python - 当与多处理一起使用时,PyTesseract 调用工作非常慢

转载 作者:行者123 更新时间:2023-12-04 02:54:53 28 4
gpt4 key购买 nike

我有一个函数,它接收图像列表并在对图像应用 OCR 后在列表中生成输出。我有另一个函数通过使用多处理来控制此函数的输入。因此,当我有一个列表(即没有多处理)时,列表中的每个图像花费了大约 1 秒,但是当我将必须并行处理的列表增加到 4 个时,每个图像花费了惊人的 13 秒。

为了了解问题的真正所在,我尝试创建一个问题的最小工作示例。这里我有两个函数 eat25eat100 打开图像 name 并将其提供给 OCR,OCR 使用 API pytesseracteat25 执行 25 次,eat100 执行 100 次。

我的目标是在没有多处理的情况下运行 eat100,在有多处理(4 个进程)的情况下运行 eat25。从理论上讲,如果我有 4 个独立的处理器(我有 2 个内核,每个内核有 2 个线程,因此 CPU(s) = 4(请纠正我,如果我是这里错了))。

但是当我看到代码在打印了 4 次“Processing 0”后甚至没有响应时,所有的理论都付诸东流了。不过,单处理器函数 eat100 运行良好。

我已经测试了一个简单的范围立方函数,它在多处理下运行良好,所以我的处理器确实运行良好。这里唯一的罪魁祸首可能是:

  • pytesseract:参见 this
  • 错误的代码?我做的不对。

`

from pathos.multiprocessing import ProcessingPool
from time import time
from PIL import Image
import pytesseract as pt
def eat25(name):
for i in range(25):
print('Processing :'+str(i))
pt.image_to_string(Image.open(name),lang='hin+eng',config='--psm 6')
def eat100(name):
for i in range(100):
print('Processing :'+str(i))
pt.image_to_string(Image.open(name),lang='hin+eng',config='--psm 6')
st = time()
eat100('normalBox.tiff')
en = time()
print('Direct :'+str(en-st))
#Using pathos
def caller():
pool = ProcessingPool()
pool.map(eat25,['normalBox.tiff','normalBox.tiff','normalBox.tiff','normalBox.tiff'])
if (__name__=='__main__'):
caller()
en2 = time()

print('Pathos :'+str(en2-en))

那么,问题究竟出在哪里呢?感谢您的帮助!

编辑:图像 normalBox.tiff 可以在 here 中找到。如果人们重现代码并检查问题是否仍然存在,我会很高兴。

最佳答案

我是pathos 的作者。如果您的代码需要 1s 来串行运行,那么很可能在原始进程中并行运行需要更长的时间。使用简单的进程并行会产生开销:

  1. 必须在每个处理器上启动一个新的 python 实例
  2. 您的函数和依赖项需要序列化并发送到每个处理器
  3. 您的数据需要序列化并发送给处理器
  4. 反序列化也是如此
  5. 您可能会因长期池或大量数据序列化而遇到内存问题。

我建议检查一些简单的事情来检查您的问题可能出在哪里:

  • 尝试使用 pathos.pools.ThreadPool 来使用线程并行而不是进程并行。这可以减少序列化和启动池的一些开销。
  • 尝试使用 pathos.pools._ProcessPool 来改变 pathos 管理池的方式。没有下划线,pathos 将池保持为单例,并且需要“终止”以显式终止池。带有下划线的是,当您删除池对象时,池将消失。请注意,您的caller 函数不会关闭加入(或终止)池。
  • 您可能想通过尝试 dill.dumps 您尝试并行处理的元素之一来检查序列化了多少。大型 numpy 数组之类的东西可能需要一段时间才能序列化。如果传递的内容很大,您可以考虑使用共享内存数组(即 multiprocess.Arraynumpy 数组的等效版本——也请参阅:numpy.ctypeslib)以最小化每个进程之间传递的内容。

后者需要做更多的工作,但如果您有很多要序列化的内容,则可以节省大量资金。没有共享内存池,因此如果您需要走那条路线,则必须对各个 multiprocess.Process 对象执行 for 循环。

关于python - 当与多处理一起使用时,PyTesseract 调用工作非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53468446/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com