From b92f26120e9ebbe60383d5626feaf39e304b16a9 Mon Sep 17 00:00:00 2001 From: chenjw28 <792430652@qq.com> Date: Wed, 3 Jun 2026 15:52:29 +0800 Subject: [PATCH] x --- docker/Dockerfile | 104 +++---------------------- docker/scripts/apply_mineru_patches.py | 88 +++++++++++++++++++++ 2 files changed, 99 insertions(+), 93 deletions(-) create mode 100644 docker/scripts/apply_mineru_patches.py diff --git a/docker/Dockerfile b/docker/Dockerfile index 405b19d..6ec1af6 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -165,17 +165,16 @@ RUN set -ex && \ torch==2.11.0+rocm7.2 torchvision pytorch-triton-rocm \ --index-url ${TORCH_INDEX} && \ # 最终验证 vllm 平台检测 - ${VENV}/bin/python -c " -from vllm.platforms import current_platform -print('Platform:', type(current_platform).__name__) -print('is_rocm:', current_platform.is_rocm()) -print('device_type:', current_platform.device_type) -assert current_platform.is_rocm(), 'vllm ROCm detection failed!' -print('vllm OK') -" && \ + ${VENV}/bin/python -c "from vllm.platforms import current_platform; print('Platform:', type(current_platform).__name__); print('is_rocm:', current_platform.is_rocm()); print('device_type:', current_platform.device_type); assert current_platform.is_rocm(), 'vllm ROCm detection failed!'; print('vllm OK')" && \ # 清理构建目录(减小镜像体积,约 3-5GB) rm -rf /opt/vllm_build +# =========================================================================== +# 阶段 8.5:复制辅助脚本(必须在 MinerU 安装前就位) +# =========================================================================== +COPY scripts/apply_mineru_patches.py /opt/apply_mineru_patches.py +COPY scripts/cache_warmer.py /opt/cache_warmer.py + # =========================================================================== # 阶段 9:安装 MinerU + RDNA 适配补丁 # =========================================================================== @@ -183,96 +182,15 @@ RUN set -ex && \ ${VENV}/bin/pip install --no-cache-dir 'mineru[core]' && \ # 验证 PyTorch 没被覆盖 ${VENV}/bin/python -c "import torch; v=torch.__version__; assert 'rocm' in v, f'PyTorch overwritten: {v}'; print('PyTorch OK:', v)" && \ - # 定位 mineru infer 目录 - MINERU_INFER_DIR=$(${VENV}/bin/python -c "import mineru.model.utils.tools.infer; import os; print(os.path.dirname(mineru.model.utils.tools.infer.__file__))") && \ - echo "MinerU infer dir: ${MINERU_INFER_DIR}" && \ - # --- Patch A: predict_rec.py imgW 对齐到 32 --- - ${VENV}/bin/python -c " -import re -f = '${MINERU_INFER_DIR}/predict_rec.py' -c = open(f).read() -# 在 imgW = max(min(... 之后插入 imgW = math.ceil(imgW / 32) * 32 -old = '(imgW = max\(min\(imgW, self\.limited_max_width\), self\.limited_min_width\)\n)' -new = r'\1 imgW = math.ceil(imgW / 32) * 32\n' -c2 = re.sub(old, new, c) -if c2 == c: - # 尝试找已经插入过的情况 - if 'math.ceil(imgW / 32)' not in c: - raise RuntimeError('Patch A: cannot find imgW line in predict_rec.py') - else: - print('Patch A: already applied') -else: - open(f, 'w').write(c2) - print('Patch A: imgW 32-align inserted') -" && \ - # --- Patch B: predict_rec.py 批次填充 --- - ${VENV}/bin/python -c " -f = '${MINERU_INFER_DIR}/predict_rec.py' -c = open(f).read() -# 在 norm_img_batch = np.concatenate(norm_img_batch) 前插入 padding 逻辑 -old = '( {8}norm_img_batch = np\.concatenate\(norm_img_batch\))' -new = ''' actual_batch_size = len(norm_img_batch) - if actual_batch_size < batch_num: - pad_size = batch_num - actual_batch_size - pad_img = np.zeros_like(norm_img_batch[0]) - for _ in range(pad_size): - norm_img_batch.append(pad_img) -\\1''' -import re -c2 = re.sub(old, new, c) -if c2 == c: - if 'actual_batch_size' not in c: - raise RuntimeError('Patch B: cannot find norm_img_batch concatenation') - else: - print('Patch B: already applied') -else: - open(f, 'w').write(c2) - print('Patch B: batch padding inserted') -# 修改 range(len(rec_result)) → range(actual_batch_size) -c3 = open(f).read() -c4 = re.sub(r'for rno in range\(len\(rec_result\)\):', ' for rno in range(actual_batch_size):', c3) -open(f, 'w').write(c4) -" && \ - # --- Patch C: predict_det.py contiguous 检查 --- - ${VENV}/bin/python -c " -f = '${MINERU_INFER_DIR}/predict_det.py' -c = open(f).read() -old = '( {8}inp = inp\.to\(self\.device\)\n)' -new = r'\1 if not inp.is_contiguous():\n inp = inp.contiguous()\n' -import re -c2 = re.sub(old, new, c) -if c2 == c: - if 'is_contiguous' not in c: - raise RuntimeError('Patch C: cannot find inp.to(device) line') - else: - print('Patch C: already applied') -else: - open(f, 'w').write(c2) - print('Patch C: contiguous check inserted') -" && \ - echo "All MinerU RDNA patches applied." + # 应用 MinerU RDNA 适配补丁 + ${VENV}/bin/python /opt/apply_mineru_patches.py # =========================================================================== -# 阶段 10:MIOpen 预热脚本 -# =========================================================================== -COPY scripts/cache_warmer.py /opt/cache_warmer.py - -# =========================================================================== -# 阶段 11:入口与最终设置 +# 阶段 10:入口与最终验证 # =========================================================================== RUN echo 'source /opt/mineru_venv/bin/activate' >> /etc/bash.bashrc && \ echo "MinerU Docker image built successfully." && \ - ${VENV}/bin/python -c " -import torch, vllm, mineru -print('='*50) -print('MinerU ROCm Docker Image Ready') -print(f' PyTorch : {torch.__version__}') -print(f' ROCm : {torch.version.hip}') -print(f' vllm : {vllm.__version__}') -print(f' MinerU : {mineru.__version__}') -print(f' Arch : ${ARCH}') -print('='*50) -" + ${VENV}/bin/python -c "import torch, vllm, mineru; print('='*50); print('MinerU ROCm Docker Image Ready'); print(f' PyTorch : {torch.__version__}'); print(f' ROCm : {torch.version.hip}'); print(f' vllm : {vllm.__version__}'); print(f' MinerU : {mineru.__version__}'); print(f' Arch : ${ARCH}'); print('='*50)" # 容器入口:默认 bash,用户可 override ENTRYPOINT ["/bin/bash", "-c"] diff --git a/docker/scripts/apply_mineru_patches.py b/docker/scripts/apply_mineru_patches.py new file mode 100644 index 0000000..77ed4a7 --- /dev/null +++ b/docker/scripts/apply_mineru_patches.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +"""MinerU RDNA 适配补丁 — 一键应用脚本""" + +import re +import os +import sys + + +def find_infer_dir(): + import mineru.model.utils.tools.infer + return os.path.dirname(mineru.model.utils.tools.infer.__file__) + + +def patch_a_predict_rec_imgw(infer_dir): + """predict_rec.py: imgW 对齐到 32""" + f = os.path.join(infer_dir, 'predict_rec.py') + c = open(f).read() + old = r'(imgW = max\(min\(imgW, self\.limited_max_width\), self\.limited_min_width\)\n)' + new = r'\1 imgW = math.ceil(imgW / 32) * 32\n' + c2 = re.sub(old, new, c) + if c2 == c: + if 'math.ceil(imgW / 32)' not in c: + raise RuntimeError('Patch A: cannot find imgW line') + print('Patch A: already applied') + else: + open(f, 'w').write(c2) + print('Patch A: imgW 32-align inserted') + + +def patch_b_predict_rec_batch(infer_dir): + """predict_rec.py: 批次填充""" + f = os.path.join(infer_dir, 'predict_rec.py') + c = open(f).read() + old = r'( norm_img_batch = np\.concatenate\(norm_img_batch\))' + new = ( + ' actual_batch_size = len(norm_img_batch)\n' + ' if actual_batch_size < batch_num:\n' + ' pad_size = batch_num - actual_batch_size\n' + ' pad_img = np.zeros_like(norm_img_batch[0])\n' + ' for _ in range(pad_size):\n' + ' norm_img_batch.append(pad_img)\n' + r'\1' + ) + c2 = re.sub(old, new, c) + if c2 == c: + if 'actual_batch_size' not in c: + raise RuntimeError('Patch B: cannot find norm_img_batch concatenation') + print('Patch B: already applied') + else: + open(f, 'w').write(c2) + print('Patch B: batch padding inserted') + # 修改 range(len(rec_result)) → range(actual_batch_size) + c3 = open(f).read() + c4 = re.sub( + r'for rno in range\(len\(rec_result\)\):', + ' for rno in range(actual_batch_size):', + c3 + ) + open(f, 'w').write(c4) + + +def patch_c_predict_det_contiguous(infer_dir): + """predict_det.py: contiguous 检查""" + f = os.path.join(infer_dir, 'predict_det.py') + c = open(f).read() + old = r'( inp = inp\.to\(self\.device\)\n)' + new = r'\1 if not inp.is_contiguous():\n inp = inp.contiguous()\n' + c2 = re.sub(old, new, c) + if c2 == c: + if 'is_contiguous' not in c: + raise RuntimeError('Patch C: cannot find inp.to(device) line') + print('Patch C: already applied') + else: + open(f, 'w').write(c2) + print('Patch C: contiguous check inserted') + + +def main(): + infer_dir = find_infer_dir() + print(f'MinerU infer dir: {infer_dir}') + patch_a_predict_rec_imgw(infer_dir) + patch_b_predict_rec_batch(infer_dir) + patch_c_predict_det_contiguous(infer_dir) + print('All MinerU RDNA patches applied.') + + +if __name__ == '__main__': + main()