在使用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函数里面也会导致报错,只有在某个函数中延迟加载。)会产生一些问题。在运行时的函数中,有自己的上下文,进程间的内容都是隔离的,所以不会出现问题。
但是还是不知道这是为什么?希望有大佬指点一下为什么。文章来源:https://www.toymoban.com/news/detail-684121.html
注:上述中用到的python术语简写,如call指代__call__。文章来源地址https://www.toymoban.com/news/detail-684121.html
到了这里,关于paddleocr在uvicorn中多workers部署遇到的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!