Files
Fairscan_cyy/requirements/mineru-integration.md
MobKBK 1848a88fcf
Some checks failed
Android CI / build (push) Has been cancelled
初步完成框架
- 实时图传:WebSocket JPEG 帧发送 + 帧率控制 + PC 浏览器预览
- PDF 上传与处理:上传/处理分离,支持 ocrpdf 和 markdown 两种类型
- MinerU 真实接入:markdown 处理 + images ZIP 打包
- OCRmyPDF 接入:ocrpdf 生成可搜索双层 PDF
- 手机端任务管理面板:轮询状态 + SAF 目录选择下载
- PC 管理面板:/dashboard 文件与任务管理
- 网络层:OkHttp 客户端、WebSocket 图传、局域网发现占位

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 17:03:18 +08:00

393 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MinerU 接入 FairScan PC Server 对接文档
> 本文档记录 MinerU 在本机的环境信息、API 用法,以及如何将其接入 FairScan PC 服务器,
> 替换当前的模拟处理逻辑。
---
## 1. 本机环境信息
> **统一环境**MinerU 和 OCRmyPDF 共用一个 conda 环境 `MinerU`
> PC 服务器始终通过 `conda activate MinerU` 启动。
| 项目 | 值 |
|------|-----|
| MinerU 源码路径 | `F:/datasets_rm/MinerU/` |
| **已安装版本** | **3.0.9** |
| **最新版本** | **3.2.2**446 commits 差距) |
| Conda 环境 | `D:/ProgramData/miniconda3/envs/MinerU/` |
| Python | 3.10.20 |
| PyTorch | 2.6.0+cu124 |
| CUDA | 12.4 |
| GPU | NVIDIA GeForce RTX 4060 Laptop GPU (8 GB VRAM) |
| Transformers | 4.57.6 |
| onnxruntime | 1.23.2 |
| Pipeline 模型 | ✅ 已下载HF cache: `C:/Users/32892/.cache/huggingface/hub/models--opendatalab--PDF-Extract-Kit-1.0` |
| VLM 模型 | ✅ 已下载HF cache: `C:/Users/32892/.cache/huggingface/hub/models--opendatalab--MinerU2.5-2509-1.2B` |
| HF Hub 离线模式 | ✅ `HF_HUB_OFFLINE=1`main.py 启动时设置) |
| OCRmyPDF | ✅ v15.4.4 已安装(源码 `F:/datasets_rm/ocRmypdf`,同一 conda 环境) |
| Tesseract | ❌ 待安装OCRmyPDF 必需依赖) |
---
## 2. 前置准备:升级 MinerU强烈建议
当前安装的 3.0.9 与最新 3.2.2 差距较大446 commits主要改进包括
- **`aio_do_parse()` 异步接口** — 可直接 await 调用,不阻塞 FastAPI 事件循环
- **并发锁优化** — Layout/MFR/OCR 使用独立推理锁,减少 GPU 争用
- **PDF 渲染修复** — 大量 PDFium 资源泄漏和崩溃修复
- **图像分析** — 新增 `image_analysis` 参数
- **Client-side 输出生成** — 新增 `client_side_output_generation` 选项
### 2.1 拉取最新代码
```bash
cd F:/datasets_rm/MinerU
git checkout main
git pull origin main
git checkout mineru-3.2.2-released
```
### 2.2 更新安装
```bash
conda activate MinerU
pip install -e .
```
### 2.3 验证
```bash
# 检查版本
python -c "from mineru.version import __version__; print(__version__)" # 应为 3.2.2
# 验证模型可用
python -c "
from mineru.utils.models_download_utils import auto_download_and_get_model_root_path
print('Pipeline:', auto_download_and_get_model_root_path('models/README.md', 'pipeline'))
print('VLM:', auto_download_and_get_model_root_path('/', 'vlm'))
"
```
> **注意**:如果之后需要用 `model_source=local` 指定自定义模型路径,才需要创建 `~/.mineru.json` 配置文件。默认的 HuggingFace 缓存模式不需要。
---
## 3. MinerU 编程接口
### 3.1 核心函数:`do_parse`
```python
from mineru.cli.common import do_parse, read_fn
from mineru.utils.enum_class import MakeMode
from pathlib import Path
def do_parse(
output_dir: str, # 输出目录路径
pdf_file_names: list[str], # PDF 文件名列表(不含扩展名)
pdf_bytes_list: list[bytes], # PDF 文件字节列表
p_lang_list: list[str], # 语言列表("ch", "en", "japan" 等)
backend: str = "pipeline", # "pipeline" | "vlm-auto-engine" | "hybrid-auto-engine"
parse_method: str = "auto", # "auto" | "txt" | "ocr"
formula_enable: bool = True,
table_enable: bool = True,
server_url: str | None = None, # 远程服务器 URL仅 http-client 后端)
f_dump_md: bool = True, # 输出 .md 文件
f_dump_middle_json: bool = True, # 输出 _middle.json
f_dump_model_output: bool = True, # 输出 _model.json
f_dump_orig_pdf: bool = True, # 输出原始 PDF 副本
f_dump_content_list: bool = True, # 输出 _content_list.json
f_draw_layout_bbox: bool = True, # 输出带布局框的 PDF
f_draw_span_bbox: bool = True, # 输出带 span 框的 PDF
f_make_md_mode: MakeMode = MakeMode.MM_MD, # Markdown 模式
start_page_id: int = 0,
end_page_id: int | None = None, # None = 所有页
**kwargs,
)
```
### 3.2 `read_fn` 辅助函数
```python
from mineru.cli.common import read_fn
# 读取 PDF 文件为 bytes
pdf_bytes = read_fn("F:/path/to/doc.pdf")
# 也支持图片文件(自动转为 PDF bytes
png_bytes = read_fn("scan.png")
```
### 3.3 输出目录结构
Pipeline 后端(`backend="pipeline"`)输出:
```
{output_dir}/
{pdf_name}/
auto/ # parse_method="auto"
{pdf_name}.md # ★ Markdown 输出(主要产物)
{pdf_name}_middle.json # 中间解析结果
{pdf_name}_model.json # 模型原始输出
{pdf_name}_content_list.json
{pdf_name}_origin.pdf # 原始 PDF 副本
{pdf_name}_layout.pdf # 布局可视化
{pdf_name}_span.pdf # Span 可视化
images/ # 提取的图片
```
### 3.4 语言代码
| 代码 | 语言 |
|------|------|
| `ch` | 简体中文 |
| `ch_server` | 中文服务器版(较快) |
| `ch_lite` | 中文轻量版 |
| `en` | 英语 |
| `japan` | 日语 |
| `korean` | 韩语 |
| `chinese_cht` | 繁体中文 |
---
## 4. 接入方案
### 方案 A直接异步 API 调用(强烈推荐,需 v3.2.2
升级到 v3.2.2 后,可以直接使用 `aio_do_parse()` — MinerU 原生异步接口,无需 `asyncio.to_thread()`
**优点**
- **原生 async**,直接 await不阻塞 FastAPI 事件循环
- 最简单,不需要进程间通信
- 可直接获取输出文件路径
**前提**
- FairScan PC 服务器在 MinerU conda 环境中运行
- `F:/datasets_rm/MinerU` 已通过 `pip install -e .` 安装
**实现思路**
```python
# ---- pc-server/main.py 新增代码 ----
from pathlib import Path
from mineru.cli.common import aio_do_parse, read_fn
async def real_mineru_processing(task_id: str):
"""使用 MinerU 异步接口真实处理 PDF"""
task = tasks_db.get(task_id)
if task is None:
return
file_name = task.get("fileName", "document.pdf")
base_name = Path(file_name).stem
upload_path = Path(task["uploadPath"])
process_type = task.get("processType", "ocrpdf")
lang = task.get("options", {}).get("lang", "ch")
task["status"] = "processing"
task["progress"] = 10
task["message"] = "MinerU processing started..."
output_dir = TASKS_DIR / task_id
output_dir.mkdir(exist_ok=True)
pdf_bytes = read_fn(upload_path)
try:
if process_type == "markdown":
await aio_do_parse(
output_dir=str(output_dir),
pdf_file_names=[base_name],
pdf_bytes_list=[pdf_bytes],
p_lang_list=[lang],
backend="pipeline",
f_dump_md=True,
f_dump_middle_json=False,
f_dump_model_output=False,
f_dump_orig_pdf=False,
f_dump_content_list=False,
f_draw_layout_bbox=False,
f_draw_span_bbox=False,
)
md_path = output_dir / base_name / "auto" / f"{base_name}.md"
if md_path.exists():
art_id = str(uuid.uuid4())
artifacts_db[task_id] = [{
"artifactId": art_id, "fileName": f"{base_name}.md",
"fileSize": md_path.stat().st_size, "fileType": "md",
"filePath": str(md_path),
}]
artifacts_map[art_id] = artifacts_db[task_id][0]
task.update(status="completed", progress=100,
message="MinerU Markdown completed")
return
elif process_type == "ocrpdf":
await aio_do_parse(
output_dir=str(output_dir),
pdf_file_names=[base_name],
pdf_bytes_list=[pdf_bytes],
p_lang_list=[lang],
backend="pipeline",
f_dump_md=False,
f_dump_middle_json=False,
f_dump_model_output=False,
f_dump_orig_pdf=False,
f_dump_content_list=False,
f_draw_layout_bbox=True,
f_draw_span_bbox=False,
)
layout_pdf = output_dir / base_name / "auto" / f"{base_name}_layout.pdf"
if layout_pdf.exists():
art_id = str(uuid.uuid4())
artifacts_db[task_id] = [{
"artifactId": art_id, "fileName": f"{base_name}_ocr.pdf",
"fileSize": layout_pdf.stat().st_size, "fileType": "pdf",
"filePath": str(layout_pdf),
}]
artifacts_map[art_id] = artifacts_db[task_id][0]
task.update(status="completed", progress=100,
message="OCR PDF completed")
return
task["status"] = "failed"
task["message"] = "MinerU did not produce output"
except Exception as e:
task["status"] = "failed"
task["message"] = f"MinerU error: {str(e)}"
logger.error(f"MinerU task {task_id} failed: {e}")
```
### 方案 B子进程调用备选
通过 `subprocess` 调用 `mineru` CLI
```python
import subprocess
import asyncio
async def mineru_subprocess(task_id: str):
task = tasks_db[task_id]
upload_path = task["uploadPath"]
output_dir = TASKS_DIR / task_id
cmd = [
r"D:/ProgramData/miniconda3/envs/MinerU/python.exe",
"-m", "mineru.cli.client",
"-p", str(upload_path),
"-o", str(output_dir),
"-b", "pipeline",
"-l", "ch",
]
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
# 轮询进度(可选:监控 stdout 中的进度信息)
while True:
line = await proc.stdout.readline()
if not line:
break
# 解析进度...
returncode = await proc.wait()
if returncode == 0:
task["status"] = "completed"
else:
task["status"] = "failed"
```
**优点**进程隔离MinerU 崩溃不影响 FairScan 服务。
**缺点**:进度监控困难,需要 IPC。
### 方案 CMinerU FastAPI 服务
运行 MinerU 自带的 FastAPI 服务 `mineru-api` 作为微服务FairScan 通过 HTTP 调用。
这一方案与 pc-api-spec.md 中对原子服务的建议一致,但实现复杂度更高。
---
## 5. 与 pc-api-spec.md 的对应关系
根据接口规范,两种 `processType` 与 MinerU 的映射:
| processType | MinerU 后端 | 输出文件 | 文件类型 |
|-------------|-----------|---------|---------|
| `markdown` | `backend="pipeline"` | `{name}.md` | `text/markdown` |
| `ocrpdf` | `backend="pipeline"` + `f_draw_layout_bbox=True` | `{name}_layout.pdf` | `application/pdf` |
两种类型共用同一个 MinerU `do_parse` 调用,仅输出选项不同。
---
## 6. 接入步骤建议
### Step 1升级 MinerU 到最新版
```bash
cd F:/datasets_rm/MinerU
git checkout main && git pull origin main
git checkout mineru-3.2.2-released
conda activate MinerU
pip install -e .
```
验证:
```bash
python -c "from mineru.cli.common import aio_do_parse; print('OK')"
```
### Step 2切换 PC 服务器运行环境
```bash
conda activate MinerU
cd E:/race_save/FairScan_cyy/FairScan/pc-server
python main.py
```
### Step 3替换 `simulate_processing` 为真实 MinerU 调用
`main.py` 中将 `simulate_processing` 替换为 `real_mineru_processing`(参考方案 A 的实现)。
### Step 4端到端测试
1. 用小 PDF1-2 页)先用 `parse_method="txt"` 测试(速度快)
2. 确认无误后切换为 `parse_method="auto"`(完整 OCR+公式+表格)
3. 测试处理完成后产物下载
---
## 7. 注意事项
| 项目 | 说明 |
|------|------|
| **GPU 显存** | RTX 4060 有 8GB VRAM。pipeline 后端约需 4-6GBVLM 后端约需 6-8GB。建议用 pipeline 后端。 |
| **处理速度** | 普通 A4 PDFpipeline 后端约 3-8 秒/页(取决于内容复杂度)。 |
| **语言** | 默认传 `ch`简体中文。FairScan 可扩展语言选择功能。 |
| **页数限制** | 可用 `start_page_id` / `end_page_id` 限制处理范围。 |
| **大文件** | PDF > 100 页建议分批处理。 |
| **超时** | 单次处理时间与页数成正比,不要设置过短的 HTTP 超时。 |
| **锁模型** | `do_parse` 不是线程安全的。FastAPI 的 `async` 端点应在线程池中调用,避免阻塞事件循环。 |
| **错误处理** | `do_parse` 出错会抛出异常,需捕获并设置 `task["status"] = "failed"`。 |
---
## 8. 关键参考文件
| 文件 | 说明 |
|------|------|
| `F:/datasets_rm/MinerU/mineru/cli/common.py` | `do_parse()` 主入口 |
| `F:/datasets_rm/MinerU/mineru/cli/client.py` | CLI 参数定义 |
| `F:/datasets_rm/MinerU/mineru/cli/output_paths.py` | 输出路径解析 |
| `F:/datasets_rm/MinerU/mineru/utils/config_reader.py` | 配置读取 |
| `F:/datasets_rm/MinerU/mineru/utils/enum_class.py` | 枚举类型定义 |
| `F:/datasets_rm/MinerU/mineru.template.json` | 配置文件模板 |
| `E:/race_save/FairScan_cyy/FairScan/pc-server/main.py` | FairScan PC 服务器(需修改) |
| `E:/race_save/FairScan_cyy/FairScan/requirements/pc-api-spec.md` | API 接口规范 |