【使用Flask基于PaddleOCR3.0开发一个接口 调用时报错RuntimeError: std::exception】

项目场景:

使用PaddleOCR3.0开发一个OCR接口,使用Flask封装成接口使用


问题描述

使用Flask基于PaddleOCR3.0 CPU模式开发了一个接口, 每次调用接口就会调用一次ocr.predict(path)方法。

在调试的过程中发现每次调用的第一次可以正常返回, 然后第二次就会提示:RuntimeError: std::exception。然后后续又可以...以此类推。

当前代码的实现方式是建了一个全局的OCR引擎,然后在项目启动的时候初始化


原因分析:

首先既然存在好用的情况,那核心代码应该是没问题的。

后面考虑是不是多线程导致的问题,因为我的Flask开了多线程

后面在查询资料时看到了PaddleOCR中的Issues中有人有相同的问题,链接如下:
https://github.com/PaddlePaddle/PaddleOCR/issues/15621

大致原因也是多线程引起的问题

我们观察到使用paddle+mkldnn时,有两种情况可能会遇到类似的问题:

1.多线程同时操作一个predictor;

2.在非主线程中操作全局predictor。

第一种情况是因为paddle inference不被设计为线程安全的,应用代码不应该假设其线程安全性,使用类似动态图的方式来做并行推理,所以可能需要加锁或者创建多个实例控制并发;第二种情况考虑是paddle inference的bug,目前暂时没有简单的解决办法,建议可以考虑维护一个线程池,并在每个线程中创建单独的predictor


解决方案:

方案一:修改Flask的多线程配置,取消多线程设置

这个方法我修改后测试过,确实是可以解决这个问题。但是之前启用多线程就是考虑性能方面。所以我没有选择该方案

方案二:根据Issues中的建议,加锁或者用线程池(我选择的是使用线程池的方式)

首先取消设置全局OCR引擎,新增获取OCR引擎方法:

python 复制代码
# 线程本地存储,确保每个线程有自己的OCR引擎实例
thread_local = threading.local()
def get_ocr_engine():
    """获取当前线程的OCR引擎实例,如果不存在则创建新的"""
    if not hasattr(thread_local, "ocr_engine"):
        logger.info(f"正在为线程 {threading.get_ident()} 初始化PaddleOCR模型,首次使用时可能需要1-3分钟...")
        try:
            thread_local.ocr_engine = PaddleOCR(
                use_doc_orientation_classify=False,
                use_doc_unwarping=False,
                use_textline_orientation=False,
                device='cpu'
            )
            logger.info(f"✅ 线程 {threading.get_ident()} 的OCR引擎初始化成功!")
        except Exception as e:
            logger.error(f"❌ OCR引擎初始化失败: {str(e)}")
            logger.error(traceback.format_exc())
            raise RuntimeError("模型初始化失败") from e
    
    return thread_local.ocr_engine

然后修改执行OCR的方法

python 复制代码
def perform_ocr(image):
    """对图像进行OCR识别"""
    try:
        # 获取当前线程的OCR引擎
        ocr_engine = get_ocr_engine()
        # 新版PaddleOCR调用方式
        result = ocr_engine.predict(image)
        return result
    except Exception as e:
        logger.error(f"OCR处理异常: {str(e)}", exc_info=True)
        raise RuntimeError("OCR处理失败") from e

之前是直接用全局的OCR引擎调用predict方法,修改后从自己的线程中获取OCR引擎,没有则创建

相关推荐
Carl_奕然24 分钟前
【大模型】Agent之:从Prompt到Context的演进之路
人工智能·python·语言模型·prompt·多模态
eqwaak036 分钟前
实战项目与工程化:端到端机器学习流程全解析
开发语言·人工智能·python·机器学习·语言模型
upgrador2 小时前
PYTHON:Python 新版本下载安装更新&py文件Pycharm运行指南
开发语言·python
闲人编程2 小时前
使用Django从零开始构建一个个人博客系统
后端·python·django·接口·restful·web·个人博客
做运维的阿瑞2 小时前
从入门到精通:Django的深度探索之旅
开发语言·后端·python·系统架构·django
czliutz2 小时前
Phpstudy博客网站apache2日志分析python代码
开发语言·python
AI数据皮皮侠2 小时前
全国各省市绿色金融指数及原始数据(1990-2022年)
大数据·人工智能·python·深度学习·机器学习·金融
唐古乌梁海3 小时前
Flask项目中CSRF Token实现的解决方案
python·flask·csrf
月疯4 小时前
FLASK与JAVA的文件互传(单文件互传亲测)
后端·python·flask
程序猿小D4 小时前
【完整源码+数据集+部署教程】医疗设备显示器图像分割系统: yolov8-seg-C2f-SCConv
python·yolo·计算机视觉·数据集·yolov8·医疗设备显示器图像分割系统