Files
2026-06-23 18:22:32 +08:00

25 KiB
Raw Permalink Blame History

Docker 构建问题汇总

目标:Ubuntu 24.04 + ROCm 7.2.1 + vllm + MinerU Docker 镜像
环境:原生 Linux + RX 9070 (gfx1201) + Privoxy (127.0.0.1:8118)


1. 网络类

1.1 Docker Hub 拉基础镜像超时

现象:dial tcp [2a03:2880:...]:443 i/o timeout

原因:docker.io 被墙,IPv6 直连超时

解决:Docker daemon 配置代理 + 国内镜像加速器

# /etc/systemd/system/docker.service.d/http-proxy.conf
Environment="HTTP_PROXY=http://127.0.0.1:8118"
Environment="HTTPS_PROXY=http://127.0.0.1:8118"

# /etc/docker/daemon.json
{
    "registry-mirrors": ["https://docker.1panel.live", ...],
    "ipv6": false
}

1.2 容器内无法访问国内镜像

现象:Could not resolve 'mirrors.tuna.tsinghua.edu.cn'

原因:Docker 默认 bridge 网络无法路由到外网

解决:docker-compose.yml 构建时加 network: host(非代理,只是共享宿主机网络栈)

1.3 GitHub 直连失败

现象:git clone github.com → GnuTLS recv error / TLS connection non-properly terminated

原因:GitHub 在国内不通,无可靠国内镜像

解决:git/wget 通过 Privoxy 代理访问 GitHub(仅 GitHub,其他源用国内镜像)

ARG GIT_PROXY=http://127.0.0.1:8118
git config --global http.proxy ${GIT_PROXY}
# wget: export http_proxy=${GIT_PROXY}

1.4 git clone 代理断连

现象:RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL

原因:HTTP/2 通过代理传大仓库不稳定

解决:禁用 HTTP/2 + 加大 buffer

git config --global http.version HTTP/1.1
git config --global http.postBuffer 524288000

1.5 PyTorch ROCm wheels 下载中断

现象:IncompleteRead (pip 下载 .whl 到一半断开)

原因:PyTorch 官方 CDN (download.pytorch.org) 在国内直连不稳定

解决:下载 PyTorch 时设环境变量走代理

export http_proxy=http://127.0.0.1:8118 https_proxy=http://127.0.0.1:8118
pip install ... --pre torch==2.11.0+rocm7.2 ...

1.6 flash-attention 子模块代理递归断连

现象:--recursive 克隆 flash-attention 时子模块 cutlass (~200MB) 下载失败:RPC failed; curl 56 GnuTLS recv error

原因:3 个子模块(composable_kernel + cutlass + aiter)挤在一条代理链路上,大文件容易丢包

解决(可选):宿主机预克隆后 COPY 入镜像。或用 --depth 1 + 逐个 git submodule update --init --depth 1(断了一个可单独重试)


2. Dockerfile 语法类

2.1 ENV 行内注释导致解析失败

现象:Syntax error - can't find = in "\ ",行号为 HSA_ENABLE_SDMA=1 \ # 注释

原因:Docker ENV 不允许行内 # 注释

解决:删除行内注释,或移到单独 # 行

2.2 多行 python -c "..." 被误解析

现象:dockerfile parse error: unknown instruction: import / unknown instruction: from

原因:Docker 解析器把 Python -c 的多行字符串当作 Dockerfile 指令(from x import y → 误认为 FROM;import x → 误认为未知指令)

解决:复杂 Python 代码写成独立脚本,用 COPY 进入镜像后 python /opt/xxx.py 执行

涉及的文件:

  • scripts/apply_mineru_patches.py — MinerU RDNA 适配补丁
  • scripts/patch_vllm_platform.py — vllm 平台检测补丁

3. ROCm 兼容性类

3.1 版本号锁定失效

现象:Version '1.0.0.70201-38~24.04' for 'rocminfo' was not found

原因:AMD 仓库更新后精确版本号过期

解决:改用 apt pinning 策略,不锁死版本号

# /etc/apt/preferences.d/rocm-pin-600
Package: *
Pin: release o=repo.radeon.com
Pin-Priority: 600

3.2 hipcc.pl 符号链接创建损坏链接

现象:cmake 报 Can't find CUDA or HIP installation(PyTorch 的 LoadHIP.cmake:179)

原因:ln -sf /usr/bin/hipcc.pl /opt/rocm/bin/hipcc,/usr/bin/hipcc.pl 在原生 Linux 上不存在,创建了损坏的符号链接

解决:条件创建,源文件不存在时跳过

([ -f /usr/bin/hipcc.pl ] && ln -sf /usr/bin/hipcc.pl /opt/rocm/bin/hipcc) || echo "hipcc.pl not found"

3.3 缺 rocm-cmake 导致 find_package(HIP) 失败

现象:PyTorch LoadHIP.cmake:179 调用 find_package_and_print_version 找不到 HIP

原因:未安装 rocm-cmake 包,缺少 HIP cmake 发现模块

解决:在阶段 6 加装 rocm-cmake

3.4 vllm mamba operator+ 补丁失效

现象:sed: can't read csrc/mamba/mamba_ssm/selective_scan.h: No such file or directory

原因:vllm 上游已移除 mamba 模块

解决:改为条件判断,文件不存在就跳过

if [ -f csrc/mamba/mamba_ssm/selective_scan.h ]; then sed ...; else echo "skipping"; fi

3.5 原生 Linux 需要 amdsmi + 平台检测补丁

现象(社区反馈):ModuleNotFoundError: amdsmi → current_platform = UnspecifiedPlatform → Device string must not be empty

原因:amdsmi 未安装,且 logger.warning_once() 触发 vllm 循环导入

解决:

  1. 安装 amdsmi(原生 Linux 上可用,WSL2 不需要)
  2. 补丁 6:platforms/__init__.py 加 torch.version.hip 兜底
  3. 补丁 7:platforms/rocm.py 中 logger.warning_once() → sys.stderr.write()

3.6 缺 hip_version.h 头文件

现象:Could not find hip/hip_version.h or rocm-core/rocm_version.h

原因:ROCm 7.2.1 的 apt 安装已将 hip_version.h 从默认路径移除,且 rocm-core 包未安装

解决:

  1. 安装 rocm-core 包(提供 rocm_version.h)
  2. 手动创建 /opt/rocm/include/hip/hip_version.h 兼容头文件
apt-get install -y rocm-core
# 兜底:手动生成 hip_version.h
printf '#define HIP_VERSION_MAJOR 7\n#define HIP_VERSION_MINOR 2\n...'

3.7 cmake 需显式设 HIP 编译器路径

现象:仅设 PATH + HIP_ROOT_DIR + ROCM_PATH 不足以让 cmake 发现 HIP

解决:显式指定

-DCMAKE_HIP_COMPILER=/opt/rocm/llvm/bin/clang++  # (非 hipcc,CMake 4.0 拒绝)
-DHIP_COMPILER=/opt/rocm/llvm/bin/clang++        # PyTorch LoadHIP 也需要
-DHIP_PATH=/opt/rocm
-DCMAKE_PREFIX_PATH="/opt/rocm;..."

3.8 PyTorch Caffe2Targets 缺失 cmake target(Docker 容器特有)

现象:cmake 反复报 hip::amdhip64 / hiprtc::hiprtc / roc::hipblas / roc::hipblaslt 等 target 未找到

原因:裸机部署时 ROCm 的 cmake 配置通过 /opt/rocm 完整安装,cmake 能自动发现所有 target。但 Docker 容器内 apt 安装的 dev 包缺少部分 cmake config 文件,PyTorch 的 Caffe2Targets.cmake 硬编码引用了这些 target

涉及 target 及修复:

报错 target 命名空间问题 最终 alias
hip::amdhip64 普通 target SHARED IMPORTED → libamdhip64.so
hiprtc::hiprtc 需双冒号命名空间 hiprtc::hiprtc ALIAS hip::hiprtc
roc::hipblas roc:: 而非 hip:: roc::hipblas ALIAS roc::rocblas
roc::hipblaslt 同上 roc::hipblaslt ALIAS hip::hipblaslt
roc::hiprand / roc::hipsolver 等 同上 各指向对应 roc::roc* target

注意:roc::hip* → 应直接指向底层 roc::roc*(不能通过 hip::hip* 中转,因为后者本身是 ALIAS,CMake 不允许链式 ALIAS)

3.9 rocm-core-dev → rocm-core 包名错误

现象:E: Unable to locate package rocm-core-dev

原因:ROCm 7.2.1 仓库中的包名为 rocm-core(无 -dev 后缀)

解决:s/rocm-core-dev/rocm-core/

3.10 -lMIOpen 链接失败

现象:/usr/bin/ld: cannot find -lMIOpen

原因:miopen cmake config 使用了 INTERFACE IMPORTED(无实际 .so 路径),链接器找不到 libMIOpen.so

解决:改为 SHARED IMPORTED + 指定 IMPORTED_LOCATION,并检查版本化目录的符号链接

# 错误
add_library(miopen INTERFACE IMPORTED)
# 正确
add_library(miopen SHARED IMPORTED)
set_target_properties(miopen PROPERTIES
    IMPORTED_LOCATION "/opt/rocm/lib/libMIOpen.so"
    INTERFACE_INCLUDE_DIRECTORIES "/opt/rocm/include")

3.11 printf 参数计数错误

现象:cmake 报 add_library 在第 11 行语法错误(hiprtc-config.cmake:11)

原因:生成 cmake config 的 shell printf 格式串含 13 个 %s,但只传了 12 个参数,最后一行 hip::%s 未替换

解决:减少单行 printf 参数,复杂结构拆成独立循环


4. Docker 缓存策略

4.1 vllm 编译+验证同层导致缓存丢失

现象:ninja 编译 30 分钟成功后被后面验证失败拖垮,全部重来

解决:拆为 8a(编译)和 8b(安装+验证)

层 内容 缓存行为
8a git clone + cmake + ninja 编译成功即缓存,永不丢失
8b pip install + PyTorch 修复 + 平台补丁 失败可重试,不影响 8a

4.2 缓存失效条件

任一 RUN 层的指令或上下文变化都会导致该层及之后所有层重建。修改 ARG、ENV、COPY 文件内容均会触发。

4.3 COPY 脚本在 RUN 引用之后

现象:阶段 8b 执行 python /opt/patch_vllm_platform.py → 文件不存在

原因:COPY scripts/patch_vllm_platform.py 在阶段 8.5(原序号),但阶段 8b 已引用该脚本——Dockerfile 中 COPY 位于引用它的 RUN 之后

解决:将 COPY 指令移到所有需要脚本的 RUN 之前(阶段 7.5)。规则:COPY 必须在引用它的 RUN 之前


5. 网络策略总览

资源 访问方式
Docker Hub daemon 代理 + 国内镜像加速器
Ubuntu apt 清华镜像 mirrors.tuna.tsinghua.edu.cn
PyPI pip 清华镜像 pypi.tuna.tsinghua.edu.cn/simple
AMD ROCm apt repo.radeon.com 直连
PyTorch ROCm wheels download.pytorch.org 直连
GitHub (git/wget) Privoxy 代理 127.0.0.1:8118(唯一例外)

6. 构建阶段类

6.1 阶段 8b pip install -e . 触发 cmake 配置失败

现象:阶段 8a(cmake + ninja 手动编译)成功,但阶段 8b 执行 pip install -e . --no-build-isolation --no-deps 时报错:

TorchConfig.cmake:62 (find_package)
  → CMakeLists.txt:95 (find_package)
    → Configuring incomplete, errors occurred!
  error: failed-wheel-build-for-install
  × Failed to build installable wheels for some pyproject.toml based projects
  ╰─> vllm

排查过程:

Dockerfile 设计为阶段 8a 手动执行 cmake -S ... -B ... -G Ninja(携带完整 -D 参数)编译 vllm C++ 扩展并复制 .abi3.so 文件,阶段 8b 再用 pip install -e . 注册 Python 包。但 pip install -e . 通过 vllm 的 setuptools 构建扩展再次触发 cmake,且 vllm 内部的 cmake 调用与手动 cmake 在以下方面不可控:

  1. 尝试一(ENV 透传):在 Dockerfile ENV 块中添加 CMAKE_PREFIX_PATH、CMAKE_HIP_COMPILER、ROCM_PATH 等 8 个 cmake 环境变量,期望 pip 触发的 cmake 继承这些值。无效——vllm 的 cmake_build_ext 内部会独立构造 cmake 参数,不完全依赖环境变量。
  2. 错误始终出现在 TorchConfig.cmake:62 调用 find_package(Caffe2) 时,Caffe2 targets 引用的 ROCm cmake 目标无法被 pip 触发的 cmake 解析。

结论:pip install -e . 触发的 cmake 构建过程与阶段 8a 的手动 cmake 不在同一个可控环境中,且阶段 8b 的 pip install -e . 本质上是冗余的——C++ 扩展已在阶段 8a 编译完成。

最终解决:跳过 pip install -e .,手动创建 vllm editable package 元数据。

核心思路:阶段 8a 负责所有 C++ 编译(.abi3.so),阶段 8b 只负责 Python 包注册(不触发 cmake)。

具体改动(Dockerfile 阶段 8b):

# 替换前(会触发 cmake,失败):
cd /opt/vllm && \
${VENV}/bin/pip install -e . --no-build-isolation --no-deps && \

# 替换后(手动创建 egg-info,不触发 cmake):
cd /opt/vllm && \
mkdir -p vllm.egg-info && \
cat > vllm.egg-info/PKG-INFO << 'VLLM_EOF' && \
Metadata-Version: 2.1
Name: vllm
Version: 0.0.0
Summary: A high-throughput and memory-efficient inference and serving engine for LLMs
VLLM_EOF
echo "vllm" > vllm.egg-info/top_level.txt && \
touch vllm.egg-info/dependency_links.txt && \
touch vllm.egg-info/requires.txt && \
find vllm -name "*.py" -type f 2>/dev/null | sort > vllm.egg-info/SOURCES.txt && \
echo "vllm egg-info created (cmake build skipped, C++ extensions from stage 8a)" && \

手动创建的 egg-info 包含以下文件:

文件 内容 用途
PKG-INFO Name: vllm + Version: 0.0.0 pip freeze / importlib.metadata 识别
top_level.txt vllm 声明顶层包名
SOURCES.txt 所有 .py 文件列表 包文件索引
dependency_links.txt 空文件 依赖链接(无)
requires.txt 空文件 运行依赖(由后续 pip install -r 安装)

import vllm 的路径解析由现有的 .pth 文件保证:

echo "/opt/vllm" > ${VENV}/lib/python${PYTHON_VER}/site-packages/vllm.pth

附:ENV 块新增的 cmake 变量(保留,对阶段 8a 和其他 cmake 调用有益):

ENV ... \
    CMAKE_PREFIX_PATH=/opt/rocm \
    CMAKE_HIP_COMPILER=/opt/rocm/llvm/bin/clang++ \
    HIP_COMPILER=/opt/rocm/llvm/bin/clang++ \
    HIP_PATH=/opt/rocm \
    HIP_ROOT_DIR=/opt/rocm \
    HIP_INCLUDE_DIR=/opt/rocm/include \
    HIP_PLATFORM=amd \
    ROCM_PATH=/opt/rocm

效果:

  • 阶段 8b 不再触发 cmake,消除了冗余编译(节省约 30 分钟)
  • C++ 扩展只在阶段 8a 编译一次,职责清晰
  • pip list / pip freeze 正常显示 vllm
  • import vllm 在所有 Python 进程中正常工作

7. 运行时类

7.1 vllm _version.py 缺失导致 InvalidVersion: 'dev'

现象:镜像构建成功,WebUI 启动正常,但解析任务全部失败:

File ".../mineru/backend/vlm/utils.py", line 88, in set_default_gpu_memory_utilization
    if version.parse(vllm_version) >= version.parse("0.11.0") and gpu_memory <= 8:
       │       │     └ 'dev'
packaging.version.InvalidVersion: Invalid version: 'dev'

日志开头同时有信号:

/opt/vllm/vllm/__init__.py:7: RuntimeWarning: Failed to read commit hash:
No module named 'vllm._version'
vllm runtime import OK: dev, platform=UnspecifiedPlatform

原因:阶段 8b 跳过了 pip install -e .(见 6.1 节),而 setuptools_scm 正是在 pip install -e . 时生成 vllm/_version.py。该文件缺失后,vllm 的 version.py 回退成 __version__ = 'dev'。'dev' 不是合法 PEP 440 版本号,mineru 调 packaging.version.parse('dev') 即抛 InvalidVersion,导致每个解析任务必失败。

解决:阶段 8b 手写 vllm/_version.py,替代 setuptools_scm 生成:

# 阶段 8b(egg-info 创建之后):
printf '__version__ = "0.11.0"\n__version_tuple__ = (0, 11, 0)\n' > /opt/vllm/vllm/_version.py

同时在 patch_vllm_platform.py 的 ensure_vllm_dist_info() 中对 vllm.__version__ 做 PEP 440 合法性校验,非法时回退安全值 0.11.0 并回写 vllm.__version__(兜底,防止上游 version.py 再改回退逻辑)。

版本号选 0.11.0 的理由:

  • 合法 PEP 440,packaging.version.parse 不报错
  • 满足 mineru[vllm] 的约束 >=0.10.1.1,<0.22.0
  • mineru 代码 version.parse(vllm_version) >= version.parse("0.11.0") 走新分支(更合理的 GPU 显存策略)

注意:mineru[core](Dockerfile 阶段 9 安装的)= vlm + pipeline + gradio,不包含 mineru[vllm],因此 vllm 版本约束不会触发 pip 依赖冲突——editable 注册的假版本号只要功能上不被校验即可,而 0.11.0 恰好让校验逻辑走正确分支。

7.2 amdsmi 缺失导致 Device string must not be empty

现象:7.1 修复后(vllm runtime import OK: 0.11.0),解析任务在模型初始化阶段失败:

File ".../vllm/config/device.py", line 78, in __post_init__
    self.device = torch.device(self.device_type)
RuntimeError: Device string must not be empty

启动日志里同时有:

WARNING [rocm.py:39] Failed to import from amdsmi: No module named 'amdsmi'
vllm runtime import OK: 0.11.0, platform=UnspecifiedPlatform
WARNING: vLLM platform detection returned UnspecifiedPlatform.

原因:vllm main 的 ROCm 平台检测依赖 amdsmi。检测链:

  1. resolve_current_platform_cls_qualname() 遍历 builtin_platform_plugins,调用 rocm_platform_plugin()
  2. rocm_platform_plugin() 内部 import amdsmi → 失败(except)→ is_rocm=False → 返回 None
  3. 无任何 builtin plugin 激活 → platform_cls_qualname = "vllm.platforms.interface.UnspecifiedPlatform"
  4. current_platform.device_type = '' → torch.device('') 抛 Device string must not be empty

amdsmi 缺失的根因:阶段 6.5 的条件安装 if [ -d /opt/rocm/share/amd_smi ],ROCm 7.2 的 apt 包不再提供该目录(pip list 无 amdsmi、/opt/rocm/share/amd_smi 不存在、dpkg 无 amdsmi 包),安装被跳过。

注:rocm_platform_plugin 定义在 platforms/__init__.py(第 111 行附近),不是 platforms/rocm.py。早期补丁脚本尝试 from vllm.platforms.rocm import rocm_platform_plugin 注册 entry_point,路径错误导致 ImportError——这是 entry_point 注册失败的根因,但本方案不依赖 entry_point,改走 builtin plugin 修复。

解决:在 patch_vllm_platform.py 的补丁 6 中,向 rocm_platform_plugin() 的 return 语句前注入 torch.version.hip 兜底:

# __init__.py 中 rocm_platform_plugin 的 return 前:
    if not is_rocm:
        try:
            import torch as _torch
            if _torch.version.hip is not None:
                is_rocm = True
        except Exception:
            pass
    return "vllm.platforms.rocm.RocmPlatform" if is_rocm else None

amdsmi 缺失时 is_rocm=False,补丁用 torch.version.hip 翻转为 True → 返回 RocmPlatform → device_type='cuda' → 错误消失。

关键实现细节(补丁 6 多次失效的教训):

  • 不能用精确字符串匹配。vllm main 频繁重构,引号风格、空格、行结构都会变。早期补丁用 old = " return 'vllm.platforms.rocm.RocmPlatform' if is_rocm else None"(单引号)匹配,但实际文件是双引号,导致 pattern not found。
  • 改用语义定位:遍历行,找同时含 RocmPlatform + return + is_rocm 的行作为注入点,取该行缩进对齐。兼容单/双引号。
  • 幂等:注入前检查文件内是否已有 torch.version.hip is not None,避免重复注入。

验证:

docker exec mineru-gradio /opt/mineru_venv/bin/python -c "
from vllm.platforms import current_platform
print('platform:', type(current_platform).__name__)
print('device_type:', repr(current_platform.device_type))
"
# 期望:platform: RocmPlatform / device_type: 'cuda'

放弃的方案:sitecustomize.py 运行时强制注入 current_platform。失败原因:current_platform 是 lazy init(首次访问才 resolve),sitecustomize 在 Python 启动最早期执行时触发提前 resolve,而那时补丁 6 尚未应用(或被 except: pass 吞错),赋值后可能被后续逻辑覆盖。改 builtin plugin 本体(补丁 6)才是 vllm 官方检测路径,最干净。

7.3 热修复与镜像固化的操作流程

容器运行中(不重建镜像)热修复时注意:

  1. ./scripts:/opt/scripts:ro 是只读卷挂载(见 docker-compose.yml)。docker cp 写 /opt/scripts 会报 mounted volume is marked read-only。但容器内 /opt/scripts 直接映射宿主机 ./scripts,改宿主机文件即生效,无需 docker cp。
  2. /opt/vllm 在镜像层(非只读挂载),可直接 docker exec 写入,重启不丢失。
  3. 补丁脚本幂等且检测 already applied,重启容器重跑 entrypoint 不会撤销已注入的改动。

完整固化流程(让修复进入镜像):

  • 修改 Dockerfile 阶段 8b(写 _version.py + egg-info 用 0.11.0)
  • 修改 scripts/patch_vllm_platform.py(补丁 6 语义定位 + PEP 440 校验)
  • 重建镜像(8a 的 ninja 编译层有缓存,几分钟):
    docker compose build && docker compose --profile gradio up -d --force-recreate
    

7.4 模型架构 inspect 失败(triton 版本过旧)

现象:7.1、7.2 修复后(platform=RocmPlatform),解析任务在 vllm 加载模型阶段失败:

1 validation error for ModelConfig
  Value error, Model architectures ['Qwen2VLForConditionalGeneration'] 
  failed to be inspected. Please check the logs for more details.

真实根因(gradio 的 ClickException 吞掉了 vllm 内部栈,需手动复现 inspect_model_cls 捕获完整 traceback):

inspect_model_cls(['Qwen2VLForConditionalGeneration'])
  → import vllm.model_executor.models.qwen2_vl
    → from ...attention import MMEncoderAttention
      → fa_utils.py: from flash_attn import flash_attn_varlen_func
        → flash_attn_interface.py: from aiter.ops.triton... import flash_attn_2
          → aiter/__init__.py: from .ops.attention import *
            → aiter/ops/attention.py: from aiter.ops.triton.gluon.pa_decode_gluon import ...
              → gluon/__init__.py:
RuntimeError: aiter gluon kernels require triton>=3.6.0, found 3.5.1

vllm main 的 Qwen2VL 加载链一路 import 到 aiter,aiter 的 gluon kernels 要求 triton ≥ 3.6.0,但 import triton 实际得到 3.5.1。 整个 import 链断裂 → Qwen2VL 类加载失败 → failed to be inspected。

排查弯路:曾怀疑是 vllm registry 访问 model_config.model_impl(transformers v5 字段,v4 缺失)导致,写了补丁 9 给 10 处访问加 getattr 兜底。但补丁 9 应用后 7.4 依旧——说明 model_impl 不是根因。补丁 9 无害(vllm ModelConfig 有该属性时透传,transformers config 缺时兜底 "auto"),保留,但真正解决 7.4 的是 triton 版本。

triton 版本现状(pip list 有 4 个相关包,容易误判):

包 版本 说明
pytorch-triton-rocm 3.5.1 torch 依赖的 ROCm triton,import triton 实际加载的是这个
triton 3.7.0 原生 triton(满足 ≥3.6.0,但被 pytorch-triton-rocm 覆盖)
triton-rocm 3.6.0 另一个 ROCm triton
triton_kernels 1.0.0+amd 缺 matmul_ogs 模块(非致命)

关键陷阱:import triton 返回 3.5.1 而非 pip 显示的 3.7.0——因为 pytorch-triton-rocm 把自己注册成 triton 顶层包,覆盖了原生 triton。所以 pip list 看版本会误导,必须看 import triton; triton.__version__。

解决:设环境变量 AITER_USE_SYSTEM_TRITON=1。aiter 的 gluon __init__.py 检测逻辑:

if int(os.environ.get("AITER_USE_SYSTEM_TRITON", 0)):
    warnings.warn(...)   # 仅警告,import 继续
else:
    raise RuntimeError(...)   # 阻断 import

设 1 后 RuntimeError 降级为 warning,import 链不再阻断,Qwen2VL 类正常加载。这是 aiter 官方提供的逃生口。

固化进 docker-compose.yml(gradio / worker0 / worker1 都要加):

environment:
  - AITER_USE_SYSTEM_TRITON=1

验证:

docker exec -e AITER_USE_SYSTEM_TRITON=1 mineru-gradio /opt/mineru_venv/bin/python -c "
from vllm.config.model import ModelConfig
from vllm.model_executor.models.registry import ModelRegistry
mp='/opt/models/modelscope/models/OpenDataLab/MinerU2.5-Pro-2605-1.2B'
cfg = ModelConfig(model=mp, tokenizer=mp, trust_remote_code=True, dtype='auto', seed=0)
print(ModelRegistry.inspect_model_cls(cfg.architectures, cfg))
"
# 期望输出:(..., 'Qwen2VLForConditionalGeneration')

遗留隐患(非阻塞):

  • AITER_USE_SYSTEM_TRITON=1 只是不阻断 import,triton 3.5.1 实际可能不支持 gluon kernel 的某些 API。实测 Qwen2VL 推理跑通(142 页 PDF 解析成功),说明推理路径未真正调用 gluon kernel——只是 import 链被牵连。
  • 若未来某模型真用 gluon kernel 且 triton 3.5.1 API 不够,需真正升级 ROCm triton 到 ≥3.6.0(注意 pytorch-triton-rocm 与 torch 版本绑定,升级有风险,见 1.5 节)。

7.5 _version.py 与 force-recreate 的坑

现象:docker compose up -d --force-recreate 后,Invalid version: 'dev'(7.1)复发。

原因:热修复时用 docker exec 写入 /opt/vllm/vllm/_version.py,这只存在于运行容器的可写层,不在镜像层。--force-recreate 重建容器后丢失。补丁 6/7/9 是 entrypoint 跑脚本应用的,会自动重应用;但 _version.py 是 Dockerfile 阶段 8b 写的,镜像里如果 Dockerfile 没改,重建即丢。

解决:把 _version.py 写入固化进 Dockerfile 阶段 8b(见 6.1/7.1 节)。固化前用 docker restart(保留容器层),不要 --force-recreate。


最后更新: 2026-06-23