Singularity运行含Numba/Numpy的Docker镜像时RuntimeError的排查与解决
Numba+Numpy软件在Singularity HPC环境运行报错的排查与解决
问题描述
我开发的Python软件依赖Numba与Numpy,通过Docker镜像troder/scoary-2分发。有用户在HPC的Singularity环境中运行时出现以下错误:
$ singularity pull docker://troder/scoary-2 $ singularity run scoary-2_latest.sif scoary2 --help Traceback (most recent call last): File "/usr/local/bin/scoary2", line 5, in <module> from scoary.scoary import main File "/usr/local/lib/python3.10/site-packages/scoary/__init__.py", line 1, in <module> from .scoary import scoary File "/usr/local/lib/python3.10/site-packages/scoary/scoary.py", line 7, in <module> from .analyze_trait import analyze_trait, worker File "/usr/local/lib/python3.10/site-packages/scoary/analyze_trait.py", line 7, in <module> from fast_fisher.fast_fisher_numba import odds_ratio, test1t as fisher_exact_two_tailed File "/usr/local/lib/python3.10/site-packages/fast_fisher/fast_fisher_numba.py", line 5, in <module> cc = CC('fast_fisher_compiled') File "/usr/local/lib/python3.10/site-packages/numba/pycc/cc.py", line 65, in __init__ self._toolchain = Toolchain() File "/usr/local/lib/python3.10/site-packages/numba/pycc/platform.py", line 78, in __init__ self._raise_external_compiler_error() File "/usr/local/lib/python3.10/site-packages/numba/pycc/platform.py", line 121, in _raise_external_compiler_error raise RuntimeError(msg) RuntimeError: Attempted to compile AOT function without the compiler used by `numpy.distutils` present. If using conda try: #> conda install gcc_linux-64 gxx_linux-64
但我的HPC Singularity环境可以正常运行该软件,需要排查环境差异并解决问题。
环境差异分析
- Singularity绑定策略差异:你的环境可能默认绑定了宿主系统的编译器目录(如
/usr/bin/gcc、/usr/lib64),而用户的Singularity配置限制了默认绑定范围,仅允许绑定用户数据目录,导致容器内无法访问宿主编译器。 - Docker镜像缺失编译工具:你构建镜像时可能依赖本地宿主编译器完成Numba AOT编译,但镜像内未预装gcc/g++。你的环境因绑定宿主编译器可正常运行,用户环境无绑定则触发报错。
- Singularity版本差异:不同版本的Singularity对Docker镜像转换逻辑、默认绑定规则不同,旧版本可能默认绑定更多系统目录,新版本收紧权限后减少了默认绑定。
- 宿主编译器可用性差异:你的HPC宿主系统预装了Numba兼容的gcc版本(通常需gcc 7+),而用户的HPC要么无编译器,要么版本过低,即使绑定也无法被识别。
调试步骤
- 验证绑定目录的影响
让用户执行以下命令测试手动绑定编译器目录是否能解决问题:singularity run --bind /usr/bin,/usr/lib64 scoary-2_latest.sif scoary2 --help - 检查容器内编译器状态
让用户进入容器查看是否有可用编译器:singularity shell scoary-2_latest.sif # 在容器内执行 which gcc gcc --version - 对比Singularity配置
对比本地与用户环境的/etc/singularity/singularity.conf中bind选项的差异,确认默认绑定目录是否一致。 - 模拟受限环境测试
在本地用以下命令模拟用户的受限环境,复现报错:singularity run --cleanenv --no-home scoary-2_latest.sif scoary2 --help
解决办法
方案1:修改Docker镜像预装编译工具
在Dockerfile中添加编译工具安装步骤,确保容器内自带编译器:
# 基于python:3.10-slim的示例 RUN apt-get update && apt-get install -y --no-install-recommends gcc g++ \ && rm -rf /var/lib/apt/lists/*
重新构建并推送镜像,用户拉取后即可直接运行,无需依赖宿主环境。
方案2:预编译Numba AOT模块
在构建镜像时提前完成Numba模块编译,避免运行时编译需求:
# 在安装依赖后添加预编译命令 RUN python -c "from fast_fisher.fast_fisher_numba import odds_ratio, fisher_exact_two_tailed"
镜像内将包含已编译的模块,运行时不再需要编译器。
方案3:指导用户调整Singularity运行参数
若用户无法更换镜像,可让其手动绑定宿主编译器目录:
singularity run --bind /usr/bin/gcc,/usr/bin/g++,/usr/lib64 scoary-2_latest.sif scoary2 --help
或加载宿主编译器模块后运行:
module load gcc/9.3.0 singularity run scoary-2_latest.sif scoary2 --help
内容的提问来源于stack exchange,提问作者MrTomRod
相关产品推荐
相关产品推荐

