mindspore-ai / mindspore-ai/hyper-parallel

[Bug] whl 包名为 py3-none-any 导致跨 Python 版本/架构错装;host C++ CXX11 ABI 不一致

Open
#701 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
53
Forks
63
Avg merge
23h 45m
Merged PRs (30d)
63

Description

该问题是怎么引起的?

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 的 setup.py 没有把"自身是平台相关包"这件事告诉 setuptools,导致 wheel 出包时被默认标为纯 Python 包:

现状
Wheel 文件名 tag hyper_parallel-0.1.0-py3-none-any.whl
是否声明 has_ext_modules
是否注册 bdist_wheel cmdclass
实际打包内容 通过 package_data 引入 host 编出的多个 .so
这些 .so 依赖什么 特定 CPython ABI(链接 libpython3.X.so)、特定 CPU 指令集(aarch64/x86_64)、特定 libstdc++ / glibc 下限
pip 安装时 py3-none-any tag 直接通过,运行时 dlopen 失败

同时仓内不同 .so 链路的 host C++ _GLIBCXX_USE_CXX11_ABI 设置不一致:

子库 现状 实际链接的框架 该用哪个 ABI
libaclshmem_symmetric_memory_kernel.so(公共层) 硬编码 =0 被两个链路同时链接 保持 =0(对外是 POD 接口,安全)
libaclshmem_ms.so / hyper_parallel_custom_ops_ms.so / hyper_parallel_mega_moe_ms.so 未控制(跟编译器默认) mindspore(=0 =0
libaclshmem_torch.so / hyper_parallel_mega_moe_pta.so 未控制(跟编译器默认) PyTorch ≥ 2.7(=1)、torch_npu(=1 =1

ABI 不一致时表现:跨 .so 边界传 std::string / std::list 等 STL 类型时,链接成功但运行时崩溃于 STL 析构,或直接 undefined symbol: _ZNSt7__cxx11...

修复方案
  1. wheel 文件名升级setup.py 引入 BinaryDistributionhas_ext_modules()=True)+ 自定义 BdistWheelroot_is_pure=False),产出 cpXY-cpXY-linux_{aarch64|x86_64} 形态文件名。python_requires 收窄到 [3.10, 3.13),classifier 同步清理。
  2. 按链路统一 CXX11 ABI
    • mindspore 链路所有 .so 强制 _GLIBCXX_USE_CXX11_ABI=0
    • torch 链路所有 .so 强制 _GLIBCXX_USE_CXX11_ABI=1
    • 公共层(libaclshmem_symmetric_memory_kernel.so)保持 =0,对外仅暴露 POD 接口(与 CANN ops-transformer cmake/intf_pub.cmake 同款政策)
  3. GCC 版本校验:新增 scripts/check_gcc_version.sh,三个 build 脚本顶部 source;setup.py 也加同口径校验。强制 GCC ∈ [7.3.0, 11.3.0],与 mindspore/CMakeLists.txt:5-8 对齐。
  4. README 声明:明确 wheel 产出与 host glibc 强绑定的事实,给出最低 glibc 要求。
  5. 构建产物兜底:非纯 wheel 切换后 setuptools build_py 的写入目录变化,导致 symmetric_memory .so 漏装;在 BuildPy.run()copy_tree 兜底。

不做(明确范围外):

  • 不引入 manylinux 转换 / docker 发布镜像(靠 README 文档化 glibc 要求兜底)
  • 不做 CANN / torch / mindspore 版本运行时绑定
  • 不在 hyper_parallel/platform/{torch,mindspore}/__init__.py 里加 ABI 运行时校验(会让 platform 模块对 torch 产生强 import 依赖)
  • 不引入顶层 build.sh(坚持现有 python setup.py bdist_wheel 入口)
附录:_GLIBCXX_USE_CXX11_ABI=0 vs =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 实现 COW(写时复制),引用计数 SSO(短串栈上存)+ 不可 COW,线程安全
std::list::size() O(N) O(1)
std::string 在符号里的命名 std::basic_string<...> std::__cxx11::basic_string<...>,mangled 为 _ZNSt7__cxx1112basic_string...
兼容性 兼容 GCC ≤ 4.9 编的旧二进制 现代默认,性能更好
同进程内可否共存 可以;但两边的 std::stringstd::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 类型不一致仍可能踩坏堆。

框架站队:

  • MindSpore:全栈 =0mindspore/CMakeLists.txt:28
  • PyTorch:官方 manywheel 自 2.7 起默认 =1.ci/manywheel/build_common.sh:115
  • torch_npu:默认 =1setup.py:55,注释明写"change to use cxx11.abi in default since 2.7")
  • CANN(含 ops-transformer):host 侧统一 =0,对外仅暴露 C / POD 接口屏蔽内部 ABI

hyper-parallel 同时跨 mindspore 和 PyTorch 两个生态,唯一稳的做法就是"按链路分 ABI",公共层走 CANN 同款"POD 接口屏蔽"模式。

重现步骤
  1. 在 Python 3.10 + aarch64 + 已 source CANN 的环境编 wheel:python setup.py bdist_wheel
  2. 文件落到 dist/hyper_parallel-0.1.0-py3-none-any.whl
  3. 切到 Python 3.12 环境,pip install dist/hyper_parallel-0.1.0-py3-none-any.whl 成功
  4. import hyper_parallel.<...mindspore custom ops...> 触发 .so 加载 → 报上面的 ImportError
报错信息
ImportError: Python version mismatch: module was compiled for Python 3.10,
but the interpreter version is incompatible: 3.12.10

关联 PR:mindspore/hyper-parallel#775(fix-wheel-platform-tag 分支)。

schema_version: 1
source: gitcode
gitcode_repo: mindspore/hyper-parallel
gitcode_issue: 199
source_url: https://gitcode.com/mindspore/hyper-parallel/issues/199

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the linked PR and the existing setup.py, build scripts, scripts/check_gcc_version.sh proposal, and referenced CMakeLists.txt ABI settings. Reproduce the Python 3.10 wheel installation under Python 3.12, then verify that the built wheel has platform-specific tags, the intended artifacts are included, ABI checks cover each build path, and the README states the host requirements.

Written by the indexing model from the issue text.

Assessment

Tech stack
cmake, cpp, python, shell
Domain
build-system, devtools
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.