使用 start_mineru_in_container.sh 和 start_api_in_container.sh 时,先起 MinerU,再起 pdf_converter_v2。
1. 启动 MinerU API(端口 5282)
在 Clerk2.5 项目根目录 执行:
# 若项目不在 /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 项目根目录 执行:
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 API,端口 5282,日志默认 $CLERK_ROOT/logs/mineru-api.log已后台启动 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=/你的路径 后再执行脚本。
在项目根目录(Clerk2.5)执行:
# 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
或使用虚拟环境直接起:
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
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
或使用脚本后台启动:
sh pdf_converter_v2/scripts/start_api_in_container.sh
验证:
curl http://127.0.0.1:5282/health 或访问 /docscurl http://127.0.0.1:4214/docs使用 start_multi_card.sh 一次启动多张卡的 MinerU + 一个 pdf_converter_v2:
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:
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:
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
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。
示例:2 张卡,端口 5282、5283。
终端 1(卡 0):
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):
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 等。)
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 段并行」之类输出。
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):
Environment="API_URL=http://127.0.0.1:5282,http://127.0.0.1:5283"
Environment="PADDLE_OCR_DEVICES=npu:0,npu:1"
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 服务。
cannot allocate memory in static TLS block报错类似:
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),需在启动前设置:
# 任选其一存在即可(路径按你本机 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 模式无此问题)。
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 调用时,子进程会自动带上上述环境变量,无需手动设置。
Exception from the 'cv' worker: too many values to unpack (expected 2)VL 模型加载成功后,在 predict 阶段可能报:
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 已知问题,需等上游修复或版本对齐。
建议:
ocr 模式,例如 paddleocr ocr -i 图片.jpg,或通过 API 使用 backend=mineru 等不依赖 doc_parser 的路径。pip install -U paddlex;即使已升级到最新版(如 3.4.1)该错误仍可能出现,属上游 PaddleX 与 PP-DocLayoutV3 返回值格式未对齐。可关注 PaddleOCR Issues 与 PaddleX Issues 中 doc_parser / cv worker / PP-DocLayoutV3 相关讨论,待官方修复后再用 doc_parser。TBE Subprocess[task_distribute] raise error[], main process disappeared! 与 semaphore 泄漏MinerU 日志中可能出现:
[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”。
建议:
kill -TERM <pid> 结束 MinerU 进程,给 uvicorn 几秒收尾,再视情况 kill -9,可减少 TBE 子进程“主进程已消失”的报错。MINERU_DEVICE_MODE=cpu 启动 MinerU,若错误消失则多半与 NPU/CANN 子进程生命周期有关;再检查 CANN 版本、驱动与内存是否充足。| 作用 | 变量 | 示例 |
|---|---|---|
| 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 中「环境变量配置」与「多 NPU 配置」小节。