mirror of
https://github.com/opendatalab/MinerU.git
synced 2026-09-21 12:42:22 +08:00
feat: add hybrid-flash processing functions for synchronous and asynchronous analyze stages
This commit is contained in:
@@ -297,6 +297,8 @@ def doc_analyze(
|
||||
**kwargs,
|
||||
):
|
||||
"""hybrid-flash第一阶段analyze:返回pipeline形态model_list和backend元信息。"""
|
||||
# hybrid-flash 当前只执行 analyze,客户端输出开关属于最终输出阶段,不能下传到模型初始化。
|
||||
kwargs.pop("client_side_output_generation", None)
|
||||
if predictor is None:
|
||||
predictor = ModelSingleton().get_model(backend, model_path, server_url, **kwargs)
|
||||
predictor = _maybe_enable_serial_execution(predictor, backend)
|
||||
@@ -425,6 +427,8 @@ async def aio_doc_analyze(
|
||||
**kwargs,
|
||||
):
|
||||
"""异步hybrid-flash analyze入口,返回pipeline形态model_list和backend元信息。"""
|
||||
# hybrid-flash 当前只执行 analyze,客户端输出开关属于最终输出阶段,不能下传到模型初始化。
|
||||
kwargs.pop("client_side_output_generation", None)
|
||||
if predictor is None:
|
||||
predictor = await _get_model_async(backend, model_path, server_url, **kwargs)
|
||||
predictor = _maybe_enable_serial_execution(predictor, backend)
|
||||
|
||||
+158
-30
@@ -10,6 +10,7 @@ from typing import Sequence
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from mineru.cli.backend_options import normalize_backend
|
||||
from mineru.data.data_reader_writer import FileBasedDataWriter
|
||||
from mineru.utils.draw_bbox import draw_layout_bbox, draw_span_bbox
|
||||
from mineru.utils.engine_utils import get_vlm_engine
|
||||
@@ -69,9 +70,15 @@ def ensure_backend_dependencies(backend: str) -> None:
|
||||
|
||||
|
||||
def _load_hybrid_analyze_entrypoint(entrypoint_name: str, backend: str):
|
||||
"""按 hybrid 后端家族加载普通 hybrid 或 hybrid-flash 的 analyze 入口。"""
|
||||
ensure_backend_dependencies(backend)
|
||||
module_name = (
|
||||
"mineru.backend.hybrid_flash.hybrid_flash_analyze"
|
||||
if backend.startswith("hybrid-flash-")
|
||||
else "mineru.backend.hybrid.hybrid_analyze"
|
||||
)
|
||||
try:
|
||||
hybrid_analyze = importlib.import_module("mineru.backend.hybrid.hybrid_analyze")
|
||||
hybrid_analyze = importlib.import_module(module_name)
|
||||
except (ImportError, ModuleNotFoundError) as exc:
|
||||
raise HybridDependencyError(
|
||||
build_hybrid_dependency_error_message(backend)
|
||||
@@ -498,6 +505,112 @@ def _process_vlm(
|
||||
)
|
||||
|
||||
|
||||
def _process_hybrid_flash(
|
||||
output_dir,
|
||||
pdf_file_names,
|
||||
pdf_bytes_list,
|
||||
h_lang_list,
|
||||
parse_method,
|
||||
inline_formula_enable,
|
||||
backend,
|
||||
f_draw_layout_bbox,
|
||||
f_draw_span_bbox,
|
||||
f_dump_md,
|
||||
f_dump_middle_json,
|
||||
f_dump_model_output,
|
||||
f_dump_orig_pdf,
|
||||
f_dump_content_list,
|
||||
f_make_md_mode,
|
||||
table_enable,
|
||||
server_url=None,
|
||||
image_analysis=True,
|
||||
**kwargs,
|
||||
):
|
||||
"""同步运行 hybrid-flash analyze 阶段,当前只产出 analyze 调试结果。"""
|
||||
hybrid_flash_doc_analyze = _load_hybrid_analyze_entrypoint(
|
||||
"doc_analyze",
|
||||
f"hybrid-flash-{backend}",
|
||||
)
|
||||
|
||||
if not backend.endswith("client"):
|
||||
server_url = None
|
||||
|
||||
for idx, (pdf_bytes, lang) in enumerate(zip(pdf_bytes_list, h_lang_list)):
|
||||
pdf_file_name = pdf_file_names[idx]
|
||||
local_image_dir, _local_md_dir = prepare_env(
|
||||
output_dir,
|
||||
pdf_file_name,
|
||||
f"hybrid_{parse_method}",
|
||||
)
|
||||
image_writer = FileBasedDataWriter(local_image_dir)
|
||||
|
||||
hybrid_flash_doc_analyze(
|
||||
pdf_bytes=pdf_bytes,
|
||||
image_writer=image_writer,
|
||||
backend=backend,
|
||||
parse_method=parse_method,
|
||||
language=lang,
|
||||
inline_formula_enable=inline_formula_enable,
|
||||
table_enable=table_enable,
|
||||
server_url=server_url,
|
||||
image_analysis=image_analysis,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
async def _async_process_hybrid_flash(
|
||||
output_dir,
|
||||
pdf_file_names,
|
||||
pdf_bytes_list,
|
||||
h_lang_list,
|
||||
parse_method,
|
||||
inline_formula_enable,
|
||||
backend,
|
||||
f_draw_layout_bbox,
|
||||
f_draw_span_bbox,
|
||||
f_dump_md,
|
||||
f_dump_middle_json,
|
||||
f_dump_model_output,
|
||||
f_dump_orig_pdf,
|
||||
f_dump_content_list,
|
||||
f_make_md_mode,
|
||||
table_enable,
|
||||
server_url=None,
|
||||
image_analysis=True,
|
||||
**kwargs,
|
||||
):
|
||||
"""异步运行 hybrid-flash analyze 阶段,当前只产出 analyze 调试结果。"""
|
||||
aio_hybrid_flash_doc_analyze = _load_hybrid_analyze_entrypoint(
|
||||
"aio_doc_analyze",
|
||||
f"hybrid-flash-{backend}",
|
||||
)
|
||||
|
||||
if not backend.endswith("client"):
|
||||
server_url = None
|
||||
|
||||
for idx, (pdf_bytes, lang) in enumerate(zip(pdf_bytes_list, h_lang_list)):
|
||||
pdf_file_name = pdf_file_names[idx]
|
||||
local_image_dir, _local_md_dir = prepare_env(
|
||||
output_dir,
|
||||
pdf_file_name,
|
||||
f"hybrid_{parse_method}",
|
||||
)
|
||||
image_writer = FileBasedDataWriter(local_image_dir)
|
||||
|
||||
await aio_hybrid_flash_doc_analyze(
|
||||
pdf_bytes=pdf_bytes,
|
||||
image_writer=image_writer,
|
||||
backend=backend,
|
||||
parse_method=parse_method,
|
||||
language=lang,
|
||||
inline_formula_enable=inline_formula_enable,
|
||||
table_enable=table_enable,
|
||||
server_url=server_url,
|
||||
image_analysis=image_analysis,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
def _process_hybrid(
|
||||
output_dir,
|
||||
pdf_file_names,
|
||||
@@ -684,6 +797,7 @@ def do_parse(
|
||||
client_side_output_generation=False,
|
||||
**kwargs,
|
||||
):
|
||||
backend = normalize_backend(backend)
|
||||
need_remove_index = _process_office_doc(
|
||||
output_dir,
|
||||
pdf_file_names=pdf_file_names,
|
||||
@@ -718,10 +832,7 @@ def do_parse(
|
||||
if backend.startswith("vlm-"):
|
||||
backend = backend[4:]
|
||||
|
||||
if backend == "vllm-async-engine":
|
||||
raise Exception("vlm-vllm-async-engine backend is not supported in sync mode, please use vlm-vllm-engine backend")
|
||||
|
||||
if backend == "auto-engine":
|
||||
if backend == "engine":
|
||||
backend = get_vlm_engine(inference_engine='auto', is_async=False)
|
||||
|
||||
os.environ['MINERU_VLM_FORMULA_ENABLE'] = str(formula_enable)
|
||||
@@ -737,24 +848,33 @@ def do_parse(
|
||||
elif backend.startswith("hybrid-"):
|
||||
ensure_backend_dependencies(backend)
|
||||
backend = backend[7:]
|
||||
is_flash = backend.startswith("flash-")
|
||||
|
||||
if backend == "vllm-async-engine":
|
||||
raise Exception(
|
||||
"hybrid-vllm-async-engine backend is not supported in sync mode, please use hybrid-vllm-engine backend")
|
||||
if is_flash:
|
||||
backend = backend[6:]
|
||||
|
||||
if backend == "auto-engine":
|
||||
if backend == "engine":
|
||||
backend = get_vlm_engine(inference_engine='auto', is_async=False)
|
||||
|
||||
os.environ['MINERU_VLM_TABLE_ENABLE'] = str(table_enable)
|
||||
os.environ['MINERU_VLM_FORMULA_ENABLE'] = "true"
|
||||
|
||||
_process_hybrid(
|
||||
output_dir, pdf_file_names, pdf_bytes_list, p_lang_list, parse_method, formula_enable, backend,
|
||||
f_draw_layout_bbox, f_draw_span_bbox, f_dump_md, f_dump_middle_json,
|
||||
f_dump_model_output, f_dump_orig_pdf, f_dump_content_list, f_make_md_mode,
|
||||
server_url, image_analysis=image_analysis,
|
||||
client_side_output_generation=client_side_output_generation, **kwargs,
|
||||
)
|
||||
if is_flash:
|
||||
_process_hybrid_flash(
|
||||
output_dir, pdf_file_names, pdf_bytes_list, p_lang_list, parse_method, formula_enable, backend,
|
||||
f_draw_layout_bbox, f_draw_span_bbox, f_dump_md, f_dump_middle_json,
|
||||
f_dump_model_output, f_dump_orig_pdf, f_dump_content_list, f_make_md_mode,
|
||||
table_enable, server_url, image_analysis=image_analysis,
|
||||
client_side_output_generation=client_side_output_generation, **kwargs,
|
||||
)
|
||||
else:
|
||||
_process_hybrid(
|
||||
output_dir, pdf_file_names, pdf_bytes_list, p_lang_list, parse_method, formula_enable, backend,
|
||||
f_draw_layout_bbox, f_draw_span_bbox, f_dump_md, f_dump_middle_json,
|
||||
f_dump_model_output, f_dump_orig_pdf, f_dump_content_list, f_make_md_mode,
|
||||
server_url, image_analysis=image_analysis,
|
||||
client_side_output_generation=client_side_output_generation, **kwargs,
|
||||
)
|
||||
|
||||
|
||||
async def aio_do_parse(
|
||||
@@ -781,6 +901,7 @@ async def aio_do_parse(
|
||||
client_side_output_generation=False,
|
||||
**kwargs,
|
||||
):
|
||||
backend = normalize_backend(backend)
|
||||
# Office 解析是同步且可能耗时的操作,异步入口需要放到线程中避免阻塞事件循环。
|
||||
need_remove_index = await asyncio.to_thread(
|
||||
_process_office_doc,
|
||||
@@ -818,10 +939,7 @@ async def aio_do_parse(
|
||||
if backend.startswith("vlm-"):
|
||||
backend = backend[4:]
|
||||
|
||||
if backend == "vllm-engine":
|
||||
raise Exception("vlm-vllm-engine backend is not supported in async mode, please use vlm-vllm-async-engine backend")
|
||||
|
||||
if backend == "auto-engine":
|
||||
if backend == "engine":
|
||||
backend = get_vlm_engine(inference_engine='auto', is_async=True)
|
||||
|
||||
os.environ['MINERU_VLM_FORMULA_ENABLE'] = str(formula_enable)
|
||||
@@ -837,23 +955,33 @@ async def aio_do_parse(
|
||||
elif backend.startswith("hybrid-"):
|
||||
ensure_backend_dependencies(backend)
|
||||
backend = backend[7:]
|
||||
is_flash = backend.startswith("flash-")
|
||||
|
||||
if backend == "vllm-engine":
|
||||
raise Exception("hybrid-vllm-engine backend is not supported in async mode, please use hybrid-vllm-async-engine backend")
|
||||
if is_flash:
|
||||
backend = backend[6:]
|
||||
|
||||
if backend == "auto-engine":
|
||||
if backend == "engine":
|
||||
backend = get_vlm_engine(inference_engine='auto', is_async=True)
|
||||
|
||||
os.environ['MINERU_VLM_TABLE_ENABLE'] = str(table_enable)
|
||||
os.environ['MINERU_VLM_FORMULA_ENABLE'] = "true"
|
||||
|
||||
await _async_process_hybrid(
|
||||
output_dir, pdf_file_names, pdf_bytes_list, p_lang_list, parse_method, formula_enable, backend,
|
||||
f_draw_layout_bbox, f_draw_span_bbox, f_dump_md, f_dump_middle_json,
|
||||
f_dump_model_output, f_dump_orig_pdf, f_dump_content_list, f_make_md_mode,
|
||||
server_url, image_analysis=image_analysis,
|
||||
client_side_output_generation=client_side_output_generation, **kwargs,
|
||||
)
|
||||
if is_flash:
|
||||
await _async_process_hybrid_flash(
|
||||
output_dir, pdf_file_names, pdf_bytes_list, p_lang_list, parse_method, formula_enable, backend,
|
||||
f_draw_layout_bbox, f_draw_span_bbox, f_dump_md, f_dump_middle_json,
|
||||
f_dump_model_output, f_dump_orig_pdf, f_dump_content_list, f_make_md_mode,
|
||||
table_enable, server_url, image_analysis=image_analysis,
|
||||
client_side_output_generation=client_side_output_generation, **kwargs,
|
||||
)
|
||||
else:
|
||||
await _async_process_hybrid(
|
||||
output_dir, pdf_file_names, pdf_bytes_list, p_lang_list, parse_method, formula_enable, backend,
|
||||
f_draw_layout_bbox, f_draw_span_bbox, f_dump_md, f_dump_middle_json,
|
||||
f_dump_model_output, f_dump_orig_pdf, f_dump_content_list, f_make_md_mode,
|
||||
server_url, image_analysis=image_analysis,
|
||||
client_side_output_generation=client_side_output_generation, **kwargs,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user