CANN graph-autofusion SK 算子编译与打包指南:从 SK bind 产物到可发布 Wheel
【免费下载链接】graph-autofusionGraph-autofusion 是一个面向昇腾(Ascend)芯片的轻量级、解耦式组件集合,旨在通过自动融合技术加速模型执行。 目前已开源 SuperKernel 组件和 Autofuse 组件,未来将持续开放更多自动融合相关模块。项目地址: https://gitcode.com/cann/graph-autofusion
导读
sk-operator-build-package是 CANN graph-autofusion 仓库中负责"编译与打包"环节的 Skill,它把已经完成适配(adapted)或聚合(aggregated)的 SK bind 产物,进一步转换为可构建、可发布、可验证的工程交付物:包括受控的 SK 源码 CMake 构建链、基于 pybind11 的 native wheel,以及不依赖 torch/torch_npu 的 standalone 差分可执行程序。读完本文,你将掌握该 Skill 的全部子命令用法、输入产物契约、在run-sk-pipeline总流水线中的位置与 profile 差异,以及无 CANN 环境、无 NPU 等常见场景下的降级处理方式。
工具定位:编译打包环节的守门人
在 SuperKernel 的算子自动化生产链路中,sk-operator-codegen负责"生成 SK 源码与 bind 绑定",sk-operator-build-package则承接其后,完成从源码到交付物的最后一公里:
- 输入:单个算子的 adapted output、多个算子的
_aggregateoutput、或已有的 standalone compare output,均来自sk-operator-codegen; - 输出:通过 CMake/pip 构建得到的 pybind 绑定工程、native wheel、standalone 可执行程序,以及对应的 JSON manifest 和构建日志。
该 Skill 的核心入口脚本位于 .claude/skills/sk-operator-build-package/scripts/operator_build_package.py,统一入口形式为:
python3 <skills_root>/sk-operator-build-package/scripts/operator_build_package.py <subcommand> ...其中<skills_root>是运行环境中 Skills 集合的根目录占位符;在本仓库内,对应实际路径为.claude/skills。若直接使用本仓库代码,可将其替换为仓库内的.claude/skills/sk-operator-build-package/scripts/operator_build_package.py。
端到端场景优先使用
sk-operator-pipeline run-sk-pipeline串联整条链路;本工具更适合定位 pybind、wheel 或 standalone 构建问题时做定点排查。
输入要求与失败保留机制
输入产物一般来自sk-operator-codegen,包括以下三种形态:
| 输入形态 | 说明 |
|---|---|
| 单个算子的 adapted output | 单个算子完成 SK 适配后的输出目录,内含operator-sk-adapted/包树 |
多个算子的_aggregateoutput | 多算子聚合后的输出,包含operator-sk-adapted.json聚合清单 |
| 已有 standalone compare output | 已生成好operator-sk-standalone-verify/工程、仅需编译的执行输入 |
如果输入目录缺少 manifest、源码或构建配置,本工具不会静默跳过,而是在传入目录内保留失败记录(如operator-sk-native-wheel.json中记录status: failed与return_code),方便回到生成阶段修复后再重试。这一点对流水线的可回溯性至关重要。
structural fake toolchain 的语义约定
本 Skill 支持"显式结构化工具链"模式(通过环境变量SK_OPERATOR_STRUCTURAL_TOOLCHAIN=1启用),仅用于开发期结构检查:
- 相关 manifest 会记录
structural-passed,表明产物结构检查通过; - 但子命令返回码必须为非 0(见 operator_build_package.py 中
status == "structural-passed"时return 1的逻辑),避免被当作真实的发布或 CI 构建成功信号。
同样,standalone 的 structural executable placeholder 也遵循该规则:JSON 可记录 structural 状态,但进程必须返回非 0。
三类构建能力
该 Skill 在 SKILL.md 中明确提供了三类互补的构建能力,可按交付形态选用。
1. SK 源码构建链(CMake 受控构建)
针对生成的 SK source scaffold 或导出的 source version tree 做受控 CMake 构建,相关子命令如下:
| 子命令 | 作用 |
|---|---|
run-sk-build-validation <scaffold_dir> | 对operator-sk-source-scaffold/执行 CMake configure/build |
prepare-sk-source-version <scaffold_dir> | 导出已通过构建验证的 SK source version tree |
validate-sk-source-version <scaffold_dir> | 在导出的 source-version tree 上重新执行 CMake 验证 |
prepare-validated-sk-source-version <asset> | 从转换分析到 validated source version 的一键编排 |
从源码实现看,构建验证包含一组固定检查项SK_BUILD_VALIDATION_CHECK_NAMES,依次为:sk_source_scaffold_generated(脚手架已生成)、copied_sources_current(拷贝源码为当前版本)、cmake_command_available(cmake 可用)、cmake_contract_current(CMake 契约有效)、build_dir_available(构建目录可用)、cmake_configure、cmake_build。CMake 执行有 120 秒超时上限(CMAKE_EXECUTION_TIMEOUT_SECONDS = 120),构建日志中如果出现linker input file unused because linking not done这类告警,会触发未编译源码的告警检测(UNCOMPILED_SOURCE_WARNING)。
2. pybind 绑定与 native wheel
generate-pybind-binding消费 codegen 生成的 aclgraph-canonicaloperator-sk-adapted/包树,做结构校验后输出绑定清单;build-native-wheel再基于该清单构建包含 native extension 的 Python wheel。
3. Standalone 差分可执行程序
build-standalone-executable消费operator-sk-standalone-verify/工程,直接用 CMake 构建 standalone 对比可执行文件,不依赖 pybind、torch、torch_npu 或 wheel,是 fast profile 下做算子差分验证的主力路径。
常用命令实战
生成 pybind 绑定
python3 <skills_root>/sk-operator-build-package/scripts/operator_build_package.py generate-pybind-binding \ build/examples/sk-codegen/aggregate该子命令读取operator-sk-adapted.json,校验 codegen 负责的 aclgraph-canonical 布局(实现见 sk_pybind_lib.py):
operator-sk-adapted/ csrc/<op>.asc csrc/pybind11.asc csrc/pybind11_<op>.asc op_extension/__init__.py op_extension/_arch_selector.py op_extension/_torch_library.py setup.py校验要点:
- manifest 中
pybind_layout必须为aclgraph-canonical,否则要求重跑codegen.adapt-sk-from-global; csrc/下每个 entry 必须存在对应的<entry>_<module>.asc与公共的pybind11.asc;- 缺少任一文件都会以
aclgraph-canonical binding tree incomplete: ...形式报错并列出缺失清单。
输出为operator-sk-pybind-binding.json,其中记录package_name、python_package、extension_modules_by_entry(按 entry 拆分的扩展模块名)、supported_arches_by_entry(各 entry 支持的 arch 列表)以及written_files清单。注意:如果该 JSON 已存在,命令会直接报错拒绝覆盖(pybind binding manifest already exists),这是为了避免污染既有构建记录。
构建 native wheel
python3 <skills_root>/sk-operator-build-package/scripts/operator_build_package.py build-native-wheel \ build/examples/sk-codegen/aggregate \ --jobs 4底层执行的是(见 operator_build_package.py):
python3 -I -B -m pip --isolated wheel --no-deps --no-build-isolation --no-cache-dir \ --wheel-dir operator-sk-native-wheel-build/wheels <pybind_root>setup.py使用setuptools.Extension(language="asc")与AscendBuildExtension.build_extension()调用bisheng编译器;- 环境变量
TORCH_DEVICE_BACKEND_AUTOLOAD=0会被默认注入,避免 torch 后端自动加载干扰构建; --jobs N会写入SK_BISHENG_JOBS,用于build_ext并行;--target-chip会写入SK_TARGET_CHIPS;- 构建过程有 600 秒超时,完整输出落盘为
pip-wheel.log。
arch 选择规则(构建期与运行期分离):
| 时机 | 优先级来源 | 说明 |
|---|---|---|
| 构建期 | SK_NPU_ARCHS | 优先使用该环境变量声明的 arch 集合 |
| 运行时 | SK_ACLGRAPH_NPU_ARCH | 由_arch_selector.py在运行时选择 |
| 未显式指定 | 仅允许有来源支撑的当前环境/SoC 映射 | 不能静默选择唯一.so或默认dav-2201 |
输出 wheel 包含三类内容:op_extension/<entry>_<arch_suffix>*.so(native 扩展,按 entry/arch 拆分)、_arch_selector.py(运行时 arch 选择器)、_torch_library.py(torch library 注册)。构建结果写入 manifestoperator-sk-native-wheel.json,其中extension_count会根据SK_TARGET_CHIPS/SK_NPU_ARCHS与各 entry 的supported_arches计算期望的扩展数量,并实际解包 wheel 统计.so/.pyd数量做交叉核对。
构建 standalone executable
python3 <skills_root>/sk-operator-build-package/scripts/operator_build_package.py build-standalone-executable \ build/examples/sk-codegen/standalone \ --target-chip ascend-910b执行逻辑为:
cmake -S operator-sk-standalone-verify -B operator-sk-standalone-verify/build cmake --build operator-sk-standalone-verify/build输出产物:
operator-sk-standalone-build.json:构建结果 manifest;build-log.txt:完整 configure/build 日志(含执行的命令原文);executable-path.txt:可执行程序路径记录。
前置要求是输入目录中存在operator-sk-standalone-verify.json(由codegen.generate-standalone-compare生成)以及对应的CMakeLists.txt和runtime_compare.asc运行时代码。configure 与 build 分别有 300 秒与 600 秒超时。默认要求构建出的可执行文件真实存在;若设置SK_OPERATOR_ALLOW_STANDALONE_MOCK_EXECUTABLE=1才允许 mock 可执行文件占位(仍会以 structural 语义标记状态)。
查看完整命令
python3 <skills_root>/sk-operator-build-package/scripts/operator_build_package.py --help这也是 README 推荐的快速验证命令。从源码的 argparse 注册看,完整子命令集还包括run-sk-build-validation、prepare-sk-source-version、validate-sk-source-version、prepare-validated-sk-source-version(SK 源码构建链)以及build-baseline(基线构建,需配合--entry-name、--backend等参数)。
在总流水线中的位置
run-sk-pipeline(来自sk-operator-pipeline)会把相关产物落到以下目录:
deliverables/wheels/<asset>/ deliverables/pybind-projects/<asset>/ artifacts/sk-extensions/<asset>/ work/stage-work/<asset>/05-generate-pybind-binding/{inputs,outputs} work/stage-work/<asset>/06-build-and-verify/{inputs,standalone,wheel,verify}fastprofile(开发验证路径):默认跑01,02,03,06阶段,跳过 wheel 构建,以 standalone 差分验证为主,不依赖 pybind/torch 环境;releaseprofile(交付默认路径):保留 Stage 05(pybind 生成),进入 pybind 与 wheel 构建路径,在deliverables/wheels/<asset>/构建或复用聚合 wheel;- 通过
--wheel-mode never|cache|always控制 wheel 构建/复用策略,通过--build-cache-dir DIR保存可复用的构建缓存; --reuse-wheel WHL可直接复用已有 wheel 跳过重新构建;--no-package默认停在检查阶段,只有显式--stages 06时才进入构建验证。
相关参数说明见 .claude/skills/sk-operator-pipeline/README.md 与流水线状态机文档 .claude/skills/sk-operator-pipeline/references/pipeline-state-machine.md。
构建缓存机制
sk_build_cache_lib.py提供基于内容 hash 的构建缓存能力(实现见 .claude/skills/sk-operator-build-package/scripts/sk_build_cache_lib.py):
hash_paths():对参与构建的文件逐个计算 SHA-256;cache_key(payload):对结构化 payload 做规范化 JSON 序列化(sort_keys=True)后取 SHA-256 作为缓存键;lookup_cache()/store_cache():按cache_dir/namespace/key布局存取缓存目录,写入时先写临时目录再原子替换,保证缓存一致性;command_version():记录构建工具版本(如cmake --version),避免工具链变化时误命中旧缓存。
流水线 Stage 06 会在pipeline-state.json里记录cache_key、cache_hit、reused_from三个字段,使"本次构建是否命中缓存、复用了哪次结果"完全可审计。
常见问题与排查
| 场景 | 处理建议 |
|---|---|
| 没有 CANN 或编译器环境 | 优先用--no-package跑前置阶段,或只保留生成结果(结构检查),不进入真实编译 |
| 没有 NPU | 构建可继续完成,运行校验阶段会进入skipped-no-npu状态,构建结果不受影响 |
| wheel 已经存在 | 在总流水线中使用--reuse-wheel WHL直接复用,或使用--wheel-mode cache走缓存 |
| standalone 缺少运行输入 | 先用sk-operator-sample-gen生成 runtime fixture 再回填 |
| pybind 绑定树不完整 | 按aclgraph-canonical binding tree incomplete报错列出的缺失文件回到sk-operator-codegen阶段修复 |
| 输入目录缺 manifest/构建配置 | 工具在传入目录内保留失败记录,依据失败记录回到生成阶段修复 |
扩展点与下游交付
该 Skill 设计了清晰的扩展边界:
- 包树 contract 变化:修改 .claude/skills/sk-operator-build-package/scripts/sk_pybind_lib.py;
- bisheng 编译命令或额外 flag:修改
sk-operator-codegen/scripts/sk_codegen_lib.py中的 renderer。
下游交付方面:wheel 交给下游安装或发布;运行时正确性验证由sk-operator-sample-gen负责,在具备 NPU 的环境中,runner 可以 import 构建好的 package 并执行实际验证,从而把"能构建"与"算得对"两件事闭环起来。
验证
安装或使用后,可通过以下命令确认 CLI 可用:
python3 <skills_root>/sk-operator-build-package/scripts/operator_build_package.py --help正常输出应展示所有子命令及参数说明。结合--help、构建产物 manifest(operator-sk-pybind-binding.json、operator-sk-native-wheel.json、operator-sk-standalone-build.json)以及build-log.txt/pip-wheel.log,即可对一次 SK 算子编译打包全过程进行完整核验。
【免费下载链接】graph-autofusionGraph-autofusion 是一个面向昇腾(Ascend)芯片的轻量级、解耦式组件集合,旨在通过自动融合技术加速模型执行。 目前已开源 SuperKernel 组件和 Autofuse 组件,未来将持续开放更多自动融合相关模块。项目地址: https://gitcode.com/cann/graph-autofusion
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考