paddleocr在uvicorn中多workers部署遇到的问题

在使用fastapi部署ocr服务时,很简单的写了一个ocr的类,然后开调:

model定义如下:

class Model:
    def __init__(self, name, det=True):
        self.name = name
        self.model = PaddleOCR()
        self.det = det

    def prepare_input(self, urls, url_safe=True):
        images = []
#        ....
        return images

    def postprocess(self, rec_res):
        return rec_res

    def __call__(self, batch):
        
        res = []
        if self.det:
            for image in images:
                s = time.time()
                r = self.model.ocr(image)
                # ....
        return res

当使用如下配置时:

uvicorn.run("ocr_server:app",
                host="0.0.0.0",
                port=1),
                reload=False,
                workers=1)

运行都很ok。

然后为了增加并发,workers设置为2,就报了奇奇怪怪的错误:

ModuleNotFoundError: No module named 'paddleocr.tools'; 'paddleocr' is not a package

就纳闷了,why?我的代码哪里出错了?为什么多进程起就这么容易出环境问题?

后来找了chatgpt聊了,它给了个方法,将paddleocr放在函数中导入即可:

class Model:
    def __init__(self, name, det=True):

        self.name = name
        self.model = None
        self.det = det

    def initialize_model(self):
        '''
        必须延迟加载,否则uvicor会导致环境错误
        :return:
        '''
        from paddleocr import PaddleOCR
        if self.model is None:
            self.model = PaddleOCR()

    def prepare_input(self, images):
        return images

    def postprocess(self, rec_res):
        return rec_res

    def __call__(self, batch):
        '''

        :param batch: 每个输入包含一个参数表示是否要做det
        :return:
        '''
        if not self.model:
            self.initialize_model()
        #....

在call函数中延迟加载,此时问题得到解决。

但是问题是解决了,可这为什么呢?chatgpt也没有很好的解释。它给的答案是多进程,其他进程会复制主进程的导入模块状态,包括导包、初始化类(导包也是初始化的一种,所以即使放在init函数里面也会导致报错,只有在某个函数中延迟加载。)会产生一些问题。在运行时的函数中,有自己的上下文,进程间的内容都是隔离的,所以不会出现问题。

但是还是不知道这是为什么?希望有大佬指点一下为什么。

注:上述中用到的python术语简写,如call指代__call__。

你可能感兴趣的:(python,开发语言)