deepseek-pynative 网络开启 mHC + 融合算子训练,运行时报:
ImportError: Python version mismatch: module was compiled for Python 3.10, but the interpreter version is incompatible: 3.12.10
报错对应的 .so 是 hyper-parallel 提供的预编译 mindspore 自定义算子库(hyper_parallel_custom_ops_ms.so 等)。用户安装的是 OpenEuler 上由 Python 3.10 编出的 hyper-parallel whl,在 Python 3.12 环境执行时报错。
hyper_parallel_custom_ops_ms.so
hyper-parallel 的 setup.py 没有把"自身是平台相关包"这件事告诉 setuptools,导致 wheel 出包时被默认标为纯 Python 包:
setup.py
hyper_parallel-0.1.0-py3-none-any.whl
has_ext_modules
bdist_wheel
package_data
libpython3.X.so
py3-none-any
同时仓内不同 .so 链路的 host C++ _GLIBCXX_USE_CXX11_ABI 设置不一致:
_GLIBCXX_USE_CXX11_ABI
libaclshmem_symmetric_memory_kernel.so
=0
libaclshmem_ms.so
hyper_parallel_mega_moe_ms.so
libaclshmem_torch.so
hyper_parallel_mega_moe_pta.so
=1
ABI 不一致时表现:跨 .so 边界传 std::string / std::list 等 STL 类型时,链接成功但运行时崩溃于 STL 析构,或直接 undefined symbol: _ZNSt7__cxx11...。
std::string
std::list
undefined symbol: _ZNSt7__cxx11...
BinaryDistribution
has_ext_modules()=True
BdistWheel
root_is_pure=False
cpXY-cpXY-linux_{aarch64|x86_64}
python_requires
[3.10, 3.13)
_GLIBCXX_USE_CXX11_ABI=0
_GLIBCXX_USE_CXX11_ABI=1
cmake/intf_pub.cmake
scripts/check_gcc_version.sh
mindspore/CMakeLists.txt:5-8
build_py
BuildPy.run()
copy_tree
不做(明确范围外):
manylinux
hyper_parallel/platform/{torch,mindspore}/__init__.py
build.sh
python setup.py bdist_wheel
C++11 标准对 std::string(禁止 COW、要求线程安全)和 std::list::size()(要求 O(1))提出了新要求。GCC 4.x 实现的是 C++98 时代的旧布局;GCC 5 起为兼容老二进制引入双 ABI 共存机制。
std::list::size()
std::basic_string<...>
std::__cxx11::basic_string<...>
_ZNSt7__cxx1112basic_string...
.so
典型崩溃模式:A.so 用 =0 编、B.so 用 =1 编。A 暴露 void f(std::string),B 调用它。链接时 B 找的是 f(std::__cxx11::basic_string...),A 提供的是 f(std::basic_string...) → undefined symbol。少数情况下符号靠 extern "C" 或纯 POD 接口绕过,但 A/B 内部 std::string 类型不一致仍可能踩坏堆。
void f(std::string)
f(std::__cxx11::basic_string...)
f(std::basic_string...)
undefined symbol
extern "C"
框架站队:
mindspore/CMakeLists.txt:28
.ci/manywheel/build_common.sh:115
setup.py:55
hyper-parallel 同时跨 mindspore 和 PyTorch 两个生态,唯一稳的做法就是"按链路分 ABI",公共层走 CANN 同款"POD 接口屏蔽"模式。
dist/hyper_parallel-0.1.0-py3-none-any.whl
pip install dist/hyper_parallel-0.1.0-py3-none-any.whl
import hyper_parallel.<...mindspore custom ops...>
关联 PR:mindspore/hyper-parallel#775(fix-wheel-platform-tag 分支)。
该问题是怎么引起的?
deepseek-pynative 网络开启 mHC + 融合算子训练,运行时报:
报错对应的 .so 是 hyper-parallel 提供的预编译 mindspore 自定义算子库(
hyper_parallel_custom_ops_ms.so等)。用户安装的是 OpenEuler 上由 Python 3.10 编出的 hyper-parallel whl,在 Python 3.12 环境执行时报错。现状(根因分析)
hyper-parallel 的
setup.py没有把"自身是平台相关包"这件事告诉 setuptools,导致 wheel 出包时被默认标为纯 Python 包:hyper_parallel-0.1.0-py3-none-any.whlhas_ext_modulesbdist_wheelcmdclasspackage_data引入 host 编出的多个 .solibpython3.X.so)、特定 CPU 指令集(aarch64/x86_64)、特定 libstdc++ / glibc 下限py3-none-anytag 直接通过,运行时 dlopen 失败同时仓内不同 .so 链路的 host C++
_GLIBCXX_USE_CXX11_ABI设置不一致:libaclshmem_symmetric_memory_kernel.so(公共层)=0=0(对外是 POD 接口,安全)libaclshmem_ms.so/hyper_parallel_custom_ops_ms.so/hyper_parallel_mega_moe_ms.so=0)=0libaclshmem_torch.so/hyper_parallel_mega_moe_pta.so=1)、torch_npu(=1)=1ABI 不一致时表现:跨 .so 边界传
std::string/std::list等 STL 类型时,链接成功但运行时崩溃于 STL 析构,或直接undefined symbol: _ZNSt7__cxx11...。修复方案
setup.py引入BinaryDistribution(has_ext_modules()=True)+ 自定义BdistWheel(root_is_pure=False),产出cpXY-cpXY-linux_{aarch64|x86_64}形态文件名。python_requires收窄到[3.10, 3.13),classifier 同步清理。_GLIBCXX_USE_CXX11_ABI=0_GLIBCXX_USE_CXX11_ABI=1libaclshmem_symmetric_memory_kernel.so)保持=0,对外仅暴露 POD 接口(与 CANN ops-transformercmake/intf_pub.cmake同款政策)scripts/check_gcc_version.sh,三个 build 脚本顶部 source;setup.py也加同口径校验。强制 GCC ∈ [7.3.0, 11.3.0],与mindspore/CMakeLists.txt:5-8对齐。build_py的写入目录变化,导致 symmetric_memory .so 漏装;在BuildPy.run()加copy_tree兜底。不做(明确范围外):
manylinux转换 / docker 发布镜像(靠 README 文档化 glibc 要求兜底)hyper_parallel/platform/{torch,mindspore}/__init__.py里加 ABI 运行时校验(会让 platform 模块对 torch 产生强 import 依赖)build.sh(坚持现有python setup.py bdist_wheel入口)附录:
_GLIBCXX_USE_CXX11_ABI=0vs=1标准库数据结构差异C++11 标准对
std::string(禁止 COW、要求线程安全)和std::list::size()(要求 O(1))提出了新要求。GCC 4.x 实现的是 C++98 时代的旧布局;GCC 5 起为兼容老二进制引入双 ABI 共存机制。=0(old ABI)=1(new ABI / "cxx11")std::string实现std::list::size()std::string在符号里的命名std::basic_string<...>std::__cxx11::basic_string<...>,mangled 为_ZNSt7__cxx1112basic_string...std::string、std::list等是不同类型,跨.so边界传 = UB典型崩溃模式:A.so 用
=0编、B.so 用=1编。A 暴露void f(std::string),B 调用它。链接时 B 找的是f(std::__cxx11::basic_string...),A 提供的是f(std::basic_string...)→undefined symbol。少数情况下符号靠extern "C"或纯 POD 接口绕过,但 A/B 内部std::string类型不一致仍可能踩坏堆。框架站队:
=0(mindspore/CMakeLists.txt:28)=1(.ci/manywheel/build_common.sh:115)=1(setup.py:55,注释明写"change to use cxx11.abi in default since 2.7")=0,对外仅暴露 C / POD 接口屏蔽内部 ABIhyper-parallel 同时跨 mindspore 和 PyTorch 两个生态,唯一稳的做法就是"按链路分 ABI",公共层走 CANN 同款"POD 接口屏蔽"模式。
重现步骤
python setup.py bdist_wheeldist/hyper_parallel-0.1.0-py3-none-any.whlpip install dist/hyper_parallel-0.1.0-py3-none-any.whl成功import hyper_parallel.<...mindspore custom ops...>触发 .so 加载 → 报上面的 ImportError报错信息
关联 PR:mindspore/hyper-parallel#775(fix-wheel-platform-tag 分支)。