This commit is contained in:
2026-06-03 15:52:29 +08:00
parent 8a36630543
commit b92f26120e
2 changed files with 99 additions and 93 deletions
+11 -93
View File
@@ -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"]
+88
View File
@@ -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()