From 9ef41799c9bba83709a8119454106297ff9b9318 Mon Sep 17 00:00:00 2001 From: huangrh Date: Thu, 19 Mar 2026 15:02:01 +0800 Subject: [PATCH] Gracefully handle missing PaddleOCRVL --- python_api/ocr_api_server.py | 64 +++++++++++-------- .../resources/python-api/ocr_api_server.py | 64 +++++++++++-------- 2 files changed, 74 insertions(+), 54 deletions(-) diff --git a/python_api/ocr_api_server.py b/python_api/ocr_api_server.py index 02cf583..9ae032b 100644 --- a/python_api/ocr_api_server.py +++ b/python_api/ocr_api_server.py @@ -16,7 +16,11 @@ import logging import traceback from pathlib import Path from flask import Flask, request, jsonify -from paddleocr import PaddleOCR, PaddleOCRVL +from paddleocr import PaddleOCR +try: + from paddleocr import PaddleOCRVL # type: ignore +except Exception: + PaddleOCRVL = None # 配置日志 logging.basicConfig( @@ -93,26 +97,30 @@ def init_models(): logger.info("=" * 60) logger.info("正在初始化 PaddleOCRVL...") logger.info("=" * 60) - try: - vl_kwargs = { - "use_seal_recognition": True, - "use_ocr_for_image_block": True, - "use_layout_detection": True, - "use_doc_orientation_classify": False, - "use_doc_unwarping": False, - } - if layout_dir: - vl_kwargs["layout_detection_model_dir"] = str(layout_dir) - vl_kwargs["layout_detection_model_name"] = "PP-DocLayoutV3" - if vl_rec_dir: - vl_kwargs["vl_rec_model_dir"] = str(vl_rec_dir) - vl_kwargs["vl_rec_model_name"] = "PaddleOCR-VL-1.5-0.9B" - - vl_pipeline = PaddleOCRVL(**vl_kwargs) - logger.info("✅ PaddleOCRVL 初始化成功") - except Exception as e: - logger.error(f"❌ PaddleOCRVL 初始化失败: {e}", exc_info=True) + if PaddleOCRVL is None: + logger.warning("PaddleOCRVL not available in installed paddleocr. Skipping VL pipeline.") vl_pipeline = None + else: + try: + vl_kwargs = { + "use_seal_recognition": True, + "use_ocr_for_image_block": True, + "use_layout_detection": True, + "use_doc_orientation_classify": False, + "use_doc_unwarping": False, + } + if layout_dir: + vl_kwargs["layout_detection_model_dir"] = str(layout_dir) + vl_kwargs["layout_detection_model_name"] = "PP-DocLayoutV3" + if vl_rec_dir: + vl_kwargs["vl_rec_model_dir"] = str(vl_rec_dir) + vl_kwargs["vl_rec_model_name"] = "PaddleOCR-VL-1.5-0.9B" + + vl_pipeline = PaddleOCRVL(**vl_kwargs) + logger.info("✅ PaddleOCRVL 初始化成功") + except Exception as e: + logger.error(f"❌ PaddleOCRVL 初始化失败: {e}", exc_info=True) + vl_pipeline = None # 初始化 PP-OCRv5 logger.info("=" * 60) @@ -220,10 +228,11 @@ def ocr_pdf(): # 处理 PDF(传递 verbose 参数) try: + ocr_model = 'paddleocr_vl' if vl_pipeline else 'ppocr_v5' result = process_single_pdf_standalone( Path(pdf_path), Path(output_dir), - ocr_model='paddleocr_vl', + ocr_model=ocr_model, vl_pipeline=vl_pipeline, verbose=verbose # 新增:传递verbose参数 ) @@ -298,12 +307,13 @@ def ocr_image(): return jsonify({'success': False, 'error': f'Image not found: {image_path}'}), 404 logger.info(f"处理图像: {image_path}") - - # 使用 PaddleOCRVL 识别 - if not vl_pipeline: - return jsonify({'success': False, 'error': 'PaddleOCRVL not initialized'}), 500 - - result = vl_pipeline.ocr(image_path) + # Use PaddleOCRVL if available, otherwise fallback to PaddleOCR + if vl_pipeline: + result = vl_pipeline.ocr(image_path) + else: + if not ocr_pipeline: + return jsonify({'success': False, 'error': 'OCR pipeline not initialized'}), 500 + result = ocr_pipeline.ocr(image_path) # 提取文本 texts = [] diff --git a/src/main/resources/python-api/ocr_api_server.py b/src/main/resources/python-api/ocr_api_server.py index 5a627fb..226cb6d 100644 --- a/src/main/resources/python-api/ocr_api_server.py +++ b/src/main/resources/python-api/ocr_api_server.py @@ -15,7 +15,11 @@ import json import logging from pathlib import Path from flask import Flask, request, jsonify -from paddleocr import PaddleOCR, PaddleOCRVL +from paddleocr import PaddleOCR +try: + from paddleocr import PaddleOCRVL # type: ignore +except Exception: + PaddleOCRVL = None # 配置日志 logging.basicConfig( @@ -92,26 +96,30 @@ def init_models(): logger.info("=" * 60) logger.info("正在初始化 PaddleOCRVL...") logger.info("=" * 60) - try: - vl_kwargs = { - "use_seal_recognition": True, - "use_ocr_for_image_block": True, - "use_layout_detection": True, - "use_doc_orientation_classify": False, - "use_doc_unwarping": False, - } - if layout_dir: - vl_kwargs["layout_detection_model_dir"] = str(layout_dir) - vl_kwargs["layout_detection_model_name"] = "PP-DocLayoutV3" - if vl_rec_dir: - vl_kwargs["vl_rec_model_dir"] = str(vl_rec_dir) - vl_kwargs["vl_rec_model_name"] = "PaddleOCR-VL-1.5-0.9B" - - vl_pipeline = PaddleOCRVL(**vl_kwargs) - logger.info("✅ PaddleOCRVL 初始化成功") - except Exception as e: - logger.error(f"❌ PaddleOCRVL 初始化失败: {e}", exc_info=True) + if PaddleOCRVL is None: + logger.warning("PaddleOCRVL not available in installed paddleocr. Skipping VL pipeline.") vl_pipeline = None + else: + try: + vl_kwargs = { + "use_seal_recognition": True, + "use_ocr_for_image_block": True, + "use_layout_detection": True, + "use_doc_orientation_classify": False, + "use_doc_unwarping": False, + } + if layout_dir: + vl_kwargs["layout_detection_model_dir"] = str(layout_dir) + vl_kwargs["layout_detection_model_name"] = "PP-DocLayoutV3" + if vl_rec_dir: + vl_kwargs["vl_rec_model_dir"] = str(vl_rec_dir) + vl_kwargs["vl_rec_model_name"] = "PaddleOCR-VL-1.5-0.9B" + + vl_pipeline = PaddleOCRVL(**vl_kwargs) + logger.info("✅ PaddleOCRVL 初始化成功") + except Exception as e: + logger.error(f"❌ PaddleOCRVL 初始化失败: {e}", exc_info=True) + vl_pipeline = None # 初始化 PP-OCRv5 logger.info("=" * 60) @@ -219,10 +227,11 @@ def ocr_pdf(): # 处理 PDF(传递 verbose 参数) try: + ocr_model = 'paddleocr_vl' if vl_pipeline else 'ppocr_v5' result = process_single_pdf_standalone( Path(pdf_path), Path(output_dir), - ocr_model='paddleocr_vl', + ocr_model=ocr_model, vl_pipeline=vl_pipeline, verbose=verbose # 新增:传递verbose参数 ) @@ -280,12 +289,13 @@ def ocr_image(): return jsonify({'success': False, 'error': f'Image not found: {image_path}'}), 404 logger.info(f"处理图像: {image_path}") - - # 使用 PaddleOCRVL 识别 - if not vl_pipeline: - return jsonify({'success': False, 'error': 'PaddleOCRVL not initialized'}), 500 - - result = vl_pipeline.ocr(image_path) + # Use PaddleOCRVL if available, otherwise fallback to PaddleOCR + if vl_pipeline: + result = vl_pipeline.ocr(image_path) + else: + if not ocr_pipeline: + return jsonify({'success': False, 'error': 'OCR pipeline not initialized'}), 500 + result = ocr_pipeline.ocr(image_path) # 提取文本 texts = []