# pdf_converter_v2 启动说明 ## 使用脚本启动(推荐) 使用 `start_mineru_in_container.sh` 和 `start_api_in_container.sh` 时,**先起 MinerU,再起 pdf_converter_v2**。 ### 单卡 **1. 启动 MinerU API(端口 5282)** 在 **Clerk2.5 项目根目录** 执行: ```bash # 若项目不在 /root/work/Clerk2.5,可先设置(脚本也会按路径自动识别): # export CLERK_ROOT=/你的/Clerk2.5/路径 # NPU:默认 npu;未装 CANN 可先 export MINERU_DEVICE_MODE=cpu export MINERU_DEVICE_MODE=npu export MINERU_PORT=5282 sh pdf_converter_v2/scripts/start_mineru_in_container.sh ``` 或从 `pdf_converter_v2` 目录执行:`sh scripts/start_mineru_in_container.sh` **2. 启动 pdf_converter_v2 API(端口 4214)** 在同一台机、**Clerk2.5 项目根目录** 执行: ```bash export API_URL=http://127.0.0.1:5282 sh pdf_converter_v2/scripts/start_api_in_container.sh ``` 或从 `pdf_converter_v2` 目录:`sh scripts/start_api_in_container.sh` 脚本会后台运行并写日志,输出类似: - MinerU:`已后台启动 MinerU API,端口 5282`,日志默认 `$CLERK_ROOT/logs/mineru-api.log` - pdf_converter_v2:`已后台启动 pdf_converter_v2 API,端口 4214`,日志默认 `$CLERK_ROOT/logs/pdf-converter-v2-api.log` **查看日志:** `tail -f $CLERK_ROOT/logs/mineru-api.log` 或 `tail -f $CLERK_ROOT/logs/pdf-converter-v2-api.log` **多卡模型缓存:** 脚本会设置 `MODELSCOPE_CACHE=$CLERK_ROOT/.cache/modelscope`,多个 MinerU 实例共用同一缓存,避免每卡重复下载。若需自定义缓存目录,可设置 `export MODELSCOPE_CACHE=/你的路径` 后再执行脚本。 --- ## 一、单卡(一张 NPU/GPU,不用脚本时) ### 1. 先启动 MinerU API(提供 PDF→Markdown 转换) 在项目根目录(Clerk2.5)执行: ```bash # NPU 环境:会尝试加载 CANN;若未装 CANN 可先 export MINERU_DEVICE_MODE=cpu export MINERU_DEVICE_MODE=npu # 或 npu:0 export MINERU_PORT=5282 sh pdf_converter_v2/scripts/start_mineru_in_container.sh ``` 或使用虚拟环境直接起: ```bash cd /path/to/Clerk2.5 export PYTHONPATH=/path/to/Clerk2.5 python3 -m uvicorn mineru.cli.fast_api:app --host 0.0.0.0 --port 5282 ``` ### 2. 再启动 pdf_converter_v2 API(对外提供 /convert 等接口) ```bash cd /path/to/Clerk2.5 export PYTHONPATH=/path/to/Clerk2.5 export API_URL=http://127.0.0.1:5282 python3 pdf_converter_v2/api_server.py --host 0.0.0.0 --port 4214 ``` 或使用脚本后台启动: ```bash sh pdf_converter_v2/scripts/start_api_in_container.sh ``` **验证:** - MinerU:`curl http://127.0.0.1:5282/health` 或访问 `/docs` - pdf_converter_v2:`curl http://127.0.0.1:4214/docs` ### 多卡(一键脚本,推荐) 使用 **start_multi_card.sh** 一次启动多张卡的 MinerU + 一个 pdf_converter_v2: ```bash cd /path/to/Clerk2.5 # 启动 2 卡(默认):MinerU 端口 5282、5283,再起 pdf_converter_v2 并设 API_URL / PADDLE_OCR_DEVICES bash pdf_converter_v2/scripts/start_multi_card.sh # 启动 3 卡 bash pdf_converter_v2/scripts/start_multi_card.sh 3 # 或通过环境变量 export MINERU_NUM_CARDS=2 bash pdf_converter_v2/scripts/start_multi_card.sh ``` 脚本会依次:起 N 个 MinerU(npu:0→5282, npu:1→5283, …)、等待端口就绪、设 `API_URL` 与 `PADDLE_OCR_DEVICES`、再起 pdf_converter_v2。 可选环境变量:`MINERU_NUM_CARDS`(卡数)、`MINERU_BASE_PORT`(起始端口,默认 5282)、`MINERU_WAIT_READY`(等待端口秒数,默认 120)。 ### 多卡(手动分终端起) **1. 每个卡起一个 MinerU(不同端口)** 终端 1: ```bash cd /path/to/Clerk2.5 export MINERU_DEVICE_MODE=npu:0 export MINERU_PORT=5282 sh pdf_converter_v2/scripts/start_mineru_in_container.sh ``` 终端 2: ```bash cd /path/to/Clerk2.5 export MINERU_DEVICE_MODE=npu:1 export MINERU_PORT=5283 sh pdf_converter_v2/scripts/start_mineru_in_container.sh ``` (脚本会按端口自动使用不同日志和 PID 文件:`mineru-api-5282.log` / `mineru-api-5283.log`。) **2. 起 pdf_converter_v2,指向多 MinerU** ```bash cd /path/to/Clerk2.5 export API_URL=http://127.0.0.1:5282,http://127.0.0.1:5283 # 若 Paddle 也多卡:export PADDLE_OCR_DEVICES=npu:0,npu:1 sh pdf_converter_v2/scripts/start_api_in_container.sh ``` --- ## 二、多卡(单任务用满所有卡,不用脚本时) 需要:**多个 MinerU API 实例**(每卡一个进程、不同端口),pdf_converter_v2 用 `API_URL` 逗号分隔;Paddle 多卡用 `PADDLE_OCR_DEVICES`。 ### 1. 启动多个 MinerU API(每卡一个) 示例:2 张卡,端口 5282、5283。 **终端 1(卡 0):** ```bash cd /path/to/Clerk2.5 export PYTHONPATH=/path/to/Clerk2.5 export MINERU_DEVICE_MODE=npu:0 export MINERU_PORT=5282 # NPU 需先加载 CANN:source /usr/local/Ascend/ascend-toolkit/set_env.sh sh pdf_converter_v2/scripts/start_mineru_in_container.sh ``` **终端 2(卡 1):** ```bash cd /path/to/Clerk2.5 export PYTHONPATH=/path/to/Clerk2.5 export MINERU_DEVICE_MODE=npu:1 export MINERU_PORT=5283 sh pdf_converter_v2/scripts/start_mineru_in_container.sh ``` (更多卡同理:`npu:2` + `MINERU_PORT=5284` 等。) ### 2. 启动 pdf_converter_v2(多 MinerU 地址 + 可选 Paddle 多卡) ```bash cd /path/to/Clerk2.5 export PYTHONPATH=/path/to/Clerk2.5 # 多 MinerU:逗号分隔,单次 PDF 会按页拆分并行发往各实例 export API_URL=http://127.0.0.1:5282,http://127.0.0.1:5283 # 若用 Paddle 多卡(备用/工况解析):单次 PDF 会按页拆分并行用各卡 export PADDLE_OCR_DEVICES=npu:0,npu:1 python3 pdf_converter_v2/api_server.py --host 0.0.0.0 --port 4214 ``` **验证:** 发一个多页 PDF 到 `/convert`,看日志应出现「拆成 N 段并行」之类输出。 --- ## 三、用 systemd 管理(生产环境) ### 1. 安装并改配置 ```bash sudo cp service/pdf-converter-v2.service /etc/systemd/system/ # 按本机路径修改 sudo sed -i 's|/mnt/win_d/Clerk2.5|/你的/Clerk2.5/路径|g' /etc/systemd/system/pdf-converter-v2.service # 若用虚拟环境,改 ExecStart 为:/path/to/Clerk2.5/.venv_paddleocr/bin/python3 /path/to/Clerk2.5/pdf_converter_v2/api_server.py ... ``` **多卡时** 在 service 里加环境变量(或建 override): ```ini Environment="API_URL=http://127.0.0.1:5282,http://127.0.0.1:5283" Environment="PADDLE_OCR_DEVICES=npu:0,npu:1" ``` ### 2. 启停、开机自启、看日志 ```bash sudo systemctl daemon-reload sudo systemctl start pdf-converter-v2 sudo systemctl enable pdf-converter-v2 # 开机自启 sudo systemctl status pdf-converter-v2 sudo journalctl -u pdf-converter-v2 -f # 看日志 ``` **注意:** MinerU API 需单独起(多个卡就起多个实例,见第二节),systemd 只管理 pdf_converter_v2 服务。 --- ## 四、常见问题 ### sklearn / paddlex:`cannot allocate memory in static TLS block` 报错类似: ```text ImportError: .../scikit_learn.libs/libgomp-d22c30c5.so.1.0.0: cannot allocate memory in static TLS block ``` 原因是 Paddle/sklearn 等库加载顺序导致 libgomp 的 static TLS 空间不足。**用脚本启动 MinerU 时**,`start_mineru_in_container.sh` 会自动设置 `LD_PRELOAD` 预加载 libgomp,一般可避免此问题。 若**未用脚本**(例如直接 `python3 -m uvicorn ...` 或 systemd),需在启动前设置: ```bash # 任选其一存在即可(路径按你本机 scikit-learn 安装位置调整) export LD_PRELOAD=/usr/local/lib/python3.10/dist-packages/scikit_learn.libs/libgomp-d22c30c5.so.1.0.0 # 或系统 libgomp export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libgomp.so.1 python3 -m uvicorn mineru.cli.fast_api:app --host 0.0.0.0 --port 5282 ``` systemd 服务可在 `Environment=` 里加上上述 `LD_PRELOAD`。 **手动运行 `paddleocr` 命令时**(排查或单测),也必须先设置 `LD_PRELOAD`,否则会报同样的 static TLS 错。**若使用 `doc_parser`**,还需设置 `FLAGS_use_stride_kernel=1`,否则加载 PaddleOCR-VL 时会报:`RuntimeError: kernel view_dtype (CPU, Undefined(AnyLayout), uint8) is not registered`(`ocr` 模式无此问题)。 ```bash export PADDLE_PDX_DISABLE_MODEL_SOURCE_CHECK=True export LD_PRELOAD=/usr/local/lib/python3.10/dist-packages/scikit_learn.libs/libgomp-d22c30c5.so.1.0.0 # 若上路径不存在,可试:export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libgomp.so.1 # doc_parser 必加,否则 VL 模型加载报 view_dtype kernel 未注册 export FLAGS_use_stride_kernel=1 paddleocr doc_parser -i /path/to/image.png --save_path /tmp/out --device npu:0 ... ``` 通过 pdf_converter_v2 API 调用时,子进程会自动带上上述环境变量,无需手动设置。 ### PaddleOCR doc_parser:`Exception from the 'cv' worker: too many values to unpack (expected 2)` VL 模型加载成功后,在 `predict` 阶段可能报: ```text RuntimeError: Exception from the 'cv' worker: too many values to unpack (expected 2) ``` **原因简述:** 当前 PaddleX 的 paddleocr_vl 管道中,对布局模型(如 PP-DocLayoutV3)的返回值按 2 个解包(如 boxes, labels),而 PP-DocLayoutV3 实际返回 3 个(boxes, labels, scores),导致版本不兼容。此为 PaddleOCR/PaddleX 已知问题,需等上游修复或版本对齐。 **建议:** 1. **仅需文字识别时**:改用 `ocr` 模式,例如 `paddleocr ocr -i 图片.jpg`,或通过 API 使用 `backend=mineru` 等不依赖 doc_parser 的路径。 2. **必须用 doc_parser 时**:先尝试 `pip install -U paddlex`;**即使已升级到最新版(如 3.4.1)该错误仍可能出现**,属上游 PaddleX 与 PP-DocLayoutV3 返回值格式未对齐。可关注 [PaddleOCR Issues](https://github.com/PaddlePaddle/PaddleOCR/issues) 与 [PaddleX Issues](https://github.com/PaddlePaddle/PaddleX/issues) 中 doc_parser / cv worker / PP-DocLayoutV3 相关讨论,待官方修复后再用 doc_parser。 ### MinerU(NPU):`TBE Subprocess[task_distribute] raise error[], main process disappeared!` 与 semaphore 泄漏 MinerU 日志中可能出现: ```text [ERROR] TBE Subprocess[task_distribute] raise error[], main process disappeared! resource_tracker: There appear to be 30 leaked semaphore objects to clean up at shutdown ``` **原因简述:** 在 Ascend NPU 上,CANN/TBE 会起子进程做推理;主进程退出(被 kill、OOM 或正常退出)时,若子进程尚未结束,会报 “main process disappeared”。同时 Python 的 multiprocessing 未正确回收子进程,就会报 “leaked semaphore objects”。 **建议:** 1. **并发与负载**:单实例 MinerU 尽量控制并发请求(如前端/网关限流),避免同一进程内同时跑太多 NPU 任务导致异常退出。 2. **优雅退出**:用 `kill -TERM ` 结束 MinerU 进程,给 uvicorn 几秒收尾,再视情况 `kill -9`,可减少 TBE 子进程“主进程已消失”的报错。 3. **定位是否 NPU 相关**:若频繁出现,可临时设 `MINERU_DEVICE_MODE=cpu` 启动 MinerU,若错误消失则多半与 NPU/CANN 子进程生命周期有关;再检查 CANN 版本、驱动与内存是否充足。 4. **semaphore 泄漏**:多为进程未正常 join/清理导致,一般出现在进程退出时,若不伴随业务失败可先观察;长期可关注 MinerU/Paddle/CANN 更新与 NPU 相关 issue。 --- ## 五、环境变量速查 | 作用 | 变量 | 示例 | |----------------|--------------------------|------| | MinerU 单地址 | `API_URL` | `http://127.0.0.1:5282` | | MinerU 多卡 | `API_URL`(逗号分隔) | `http://127.0.0.1:5282,http://127.0.0.1:5283` | | Paddle 单卡 | `PADDLE_OCR_DEVICE` | `npu:0` | | Paddle 多卡 | `PADDLE_OCR_DEVICES` | `npu:0,npu:1` | | MinerU 设备 | `MINERU_DEVICE_MODE` | `npu` / `npu:0` / `npu:1` | | 本服务端口 | 命令行 `--port` 或脚本 | 默认 4214 | | MinerU 端口 | `MINERU_PORT` | 默认 5282 | 更多见 [README.md](README.md) 中「环境变量配置」与「多 NPU 配置」小节。