فهرست منبع

Merge pull request #2706 from opendatalab/release-2.0.5

Release 2.0.5
Xiaomeng Zhao 5 ماه پیش
والد
کامیت
e8865a679a

+ 2 - 1
README.md

@@ -51,8 +51,9 @@ Easier to use: Just grab MinerU Desktop. No coding, no login, just a simple inte
 </div>
 
 # Changelog
-- 2025/06/17 2.0.4 Released 
+- 2025/06/17 2.0.5 Released 
   - Fixed the issue where models were still required to be downloaded in the `sglang-client` mode  
+  - Fixed the issue where the `sglang-client` mode unnecessarily depended on packages like `torch` during runtime.
   - Fixed the issue where only the first instance would take effect when attempting to launch multiple `sglang-client` instances via multiple URLs within the same process
 - 2025/06/15 2.0.3 released
   - Fixed a configuration file key-value update error that occurred when downloading model type was set to `all`

+ 2 - 1
README_zh-CN.md

@@ -50,8 +50,9 @@
 </div>
 
 # 更新记录
-- 2025/06/17 2.0.4发布
+- 2025/06/17 2.0.5发布
   - 修复了`sglang-client`模式下依然需要下载模型的问题
+  - 修复了`sglang-client`模式需要依赖`torch`等实际运行不需要的包的问题
   - 修复了同一进程内尝试通过多个url启动多个`sglang-client`实例时,只有第一个生效的问题
 - 2025/06/15 2.0.3发布
   - 修复了当下载模型类型设置为`all`时,配置文件出现键值更新错误的问题

+ 2 - 5
mineru/backend/pipeline/pipeline_analyze.py

@@ -2,15 +2,12 @@ import os
 import time
 from typing import List, Tuple
 import PIL.Image
-import torch
+from loguru import logger
 
 from .model_init import MineruPipelineModel
 from mineru.utils.config_reader import get_device
 from ...utils.pdf_classify import classify
 from ...utils.pdf_image_tools import load_images_from_pdf
-
-from loguru import logger
-
 from ...utils.model_utils import get_vram, clean_memory
 
 
@@ -166,7 +163,7 @@ def batch_image_analyze(
         try:
             import torch_npu
             if torch_npu.npu.is_available():
-                torch.npu.set_compile_mode(jit_compile=False)
+                torch_npu.npu.set_compile_mode(jit_compile=False)
         except Exception as e:
             raise RuntimeError(
                 "NPU is selected as device, but torch_npu is not available. "

+ 0 - 1
mineru/backend/vlm/vlm_analyze.py

@@ -8,7 +8,6 @@ from mineru.utils.pdf_image_tools import load_images_from_pdf
 from .base_predictor import BasePredictor
 from .predictor import get_predictor
 from .token_to_middle_json import result_to_middle_json
-from ...utils.enum_class import ModelPath
 from ...utils.models_download_utils import auto_download_and_get_model_root_path
 
 

+ 18 - 18
mineru/cli/client.py

@@ -9,7 +9,6 @@ from mineru.utils.model_utils import get_vram
 from ..version import __version__
 from .common import do_parse, read_fn, pdf_suffixes, image_suffixes
 
-
 @click.command()
 @click.version_option(__version__,
                       '--version',
@@ -139,25 +138,26 @@ from .common import do_parse, read_fn, pdf_suffixes, image_suffixes
 
 def main(input_path, output_dir, method, backend, lang, server_url, start_page_id, end_page_id, formula_enable, table_enable, device_mode, virtual_vram, model_source):
 
-    def get_device_mode() -> str:
-        if device_mode is not None:
-            return device_mode
-        else:
-            return get_device()
-    if os.getenv('MINERU_DEVICE_MODE', None) is None:
-        os.environ['MINERU_DEVICE_MODE'] = get_device_mode()
+    if not backend.endswith('-client'):
+        def get_device_mode() -> str:
+            if device_mode is not None:
+                return device_mode
+            else:
+                return get_device()
+        if os.getenv('MINERU_DEVICE_MODE', None) is None:
+            os.environ['MINERU_DEVICE_MODE'] = get_device_mode()
 
-    def get_virtual_vram_size() -> int:
-        if virtual_vram is not None:
-            return virtual_vram
-        if get_device_mode().startswith("cuda") or get_device_mode().startswith("npu"):
-            return round(get_vram(get_device_mode()))
-        return 1
-    if os.getenv('MINERU_VIRTUAL_VRAM_SIZE', None) is None:
-        os.environ['MINERU_VIRTUAL_VRAM_SIZE']= str(get_virtual_vram_size())
+        def get_virtual_vram_size() -> int:
+            if virtual_vram is not None:
+                return virtual_vram
+            if get_device_mode().startswith("cuda") or get_device_mode().startswith("npu"):
+                return round(get_vram(get_device_mode()))
+            return 1
+        if os.getenv('MINERU_VIRTUAL_VRAM_SIZE', None) is None:
+            os.environ['MINERU_VIRTUAL_VRAM_SIZE']= str(get_virtual_vram_size())
 
-    if os.getenv('MINERU_MODEL_SOURCE', None) is None:
-        os.environ['MINERU_MODEL_SOURCE'] = model_source
+        if os.getenv('MINERU_MODEL_SOURCE', None) is None:
+            os.environ['MINERU_MODEL_SOURCE'] = model_source
 
     os.makedirs(output_dir, exist_ok=True)
 

+ 8 - 5
mineru/cli/common.py

@@ -8,15 +8,12 @@ from pathlib import Path
 import pypdfium2 as pdfium
 from loguru import logger
 
-from mineru.backend.pipeline.pipeline_middle_json_mkcontent import union_make as pipeline_union_make
-from mineru.backend.pipeline.model_json_to_middle_json import result_to_middle_json as pipeline_result_to_middle_json
-from mineru.backend.vlm.vlm_middle_json_mkcontent import union_make as vlm_union_make
-from mineru.backend.vlm.vlm_analyze import doc_analyze as vlm_doc_analyze
-from mineru.backend.pipeline.pipeline_analyze import doc_analyze as pipeline_doc_analyze
 from mineru.data.data_reader_writer import FileBasedDataWriter
 from mineru.utils.draw_bbox import draw_layout_bbox, draw_span_bbox
 from mineru.utils.enum_class import MakeMode
 from mineru.utils.pdf_image_tools import images_bytes_to_pdf_bytes
+from mineru.backend.vlm.vlm_middle_json_mkcontent import union_make as vlm_union_make
+from mineru.backend.vlm.vlm_analyze import doc_analyze as vlm_doc_analyze
 
 pdf_suffixes = [".pdf"]
 image_suffixes = [".png", ".jpeg", ".jpg"]
@@ -99,6 +96,11 @@ def do_parse(
 ):
 
     if backend == "pipeline":
+
+        from mineru.backend.pipeline.pipeline_middle_json_mkcontent import union_make as pipeline_union_make
+        from mineru.backend.pipeline.model_json_to_middle_json import result_to_middle_json as pipeline_result_to_middle_json
+        from mineru.backend.pipeline.pipeline_analyze import doc_analyze as pipeline_doc_analyze
+
         for idx, pdf_bytes in enumerate(pdf_bytes_list):
             new_pdf_bytes = convert_pdf_bytes_to_bytes_by_pypdfium2(pdf_bytes, start_page_id, end_page_id)
             pdf_bytes_list[idx] = new_pdf_bytes
@@ -163,6 +165,7 @@ def do_parse(
 
             logger.info(f"local output dir is {local_md_dir}")
     else:
+
         if backend.startswith("vlm-"):
             backend = backend[4:]
 

+ 7 - 1
mineru/model/table/rapid_table.py

@@ -1,4 +1,5 @@
 import os
+import html
 import cv2
 import numpy as np
 from loguru import logger
@@ -8,6 +9,11 @@ from mineru.utils.enum_class import ModelPath
 from mineru.utils.models_download_utils import auto_download_and_get_model_root_path
 
 
+def escape_html(input_string):
+    """Escape HTML Entities."""
+    return html.escape(input_string)
+
+
 class RapidTableModel(object):
     def __init__(self, ocr_engine):
         slanet_plus_model_path = os.path.join(auto_download_and_get_model_root_path(ModelPath.slanet_plus), ModelPath.slanet_plus)
@@ -63,7 +69,7 @@ class RapidTableModel(object):
         # Continue with OCR on potentially rotated image
         ocr_result = self.ocr_engine.ocr(bgr_image)[0]
         if ocr_result:
-            ocr_result = [[item[0], item[1][0], item[1][1]] for item in ocr_result if
+            ocr_result = [[item[0], escape_html(item[1][0]), item[1][1]] for item in ocr_result if
                       len(item) == 2 and isinstance(item[1], tuple)]
         else:
             ocr_result = None

+ 7 - 3
mineru/utils/config_reader.py

@@ -1,10 +1,15 @@
 # Copyright (c) Opendatalab. All rights reserved.
 import json
 import os
-
-import torch
 from loguru import logger
 
+try:
+    import torch
+    import torch_npu
+except ImportError:
+    pass
+
+
 # 定义配置文件名常量
 CONFIG_FILE_NAME = os.getenv('MINERU_TOOLS_CONFIG_JSON', 'mineru.json')
 
@@ -78,7 +83,6 @@ def get_device():
             return "mps"
         else:
             try:
-                import torch_npu
                 if torch_npu.npu.is_available():
                     return "npu"
             except Exception as e:

+ 6 - 3
mineru/utils/model_utils.py

@@ -1,5 +1,4 @@
 import time
-import torch
 import gc
 from PIL import Image
 from loguru import logger
@@ -7,6 +6,12 @@ import numpy as np
 
 from mineru.utils.boxbase import get_minbox_if_overlap_by_ratio
 
+try:
+    import torch
+    import torch_npu
+except ImportError:
+    pass
+
 
 def crop_img(input_res, input_img, crop_paste_x=0, crop_paste_y=0):
 
@@ -303,7 +308,6 @@ def clean_memory(device='cuda'):
             torch.cuda.empty_cache()
             torch.cuda.ipc_collect()
     elif str(device).startswith("npu"):
-        import torch_npu
         if torch_npu.npu.is_available():
             torch_npu.npu.empty_cache()
     elif str(device).startswith("mps"):
@@ -325,7 +329,6 @@ def get_vram(device):
         total_memory = torch.cuda.get_device_properties(device).total_memory / (1024 ** 3)  # 将字节转换为 GB
         return total_memory
     elif str(device).startswith("npu"):
-        import torch_npu
         if torch_npu.npu.is_available():
             total_memory = torch_npu.npu.get_device_properties(device).total_memory / (1024 ** 3)  # 转为 GB
             return total_memory

+ 8 - 0
signatures/version1/cla.json

@@ -319,6 +319,14 @@
       "created_at": "2025-06-17T03:09:54Z",
       "repoId": 765083837,
       "pullRequestNo": 2676
+    },
+    {
+      "name": "hsia",
+      "id": 654127,
+      "comment_id": 2979415817,
+      "created_at": "2025-06-17T17:35:10Z",
+      "repoId": 765083837,
+      "pullRequestNo": 2699
     }
   ]
 }