CAM 模块编译系统与部署分析
分析范围:
build/cam/、src/cam/comm_operator/、docker/cam/、umdk.spec、src/cam/third_party/、RELEASE-NOTES.md分析日期:2026-07-21 项目根:/Users/backyes/work/claude_workspace/umdk_research/umdk
1. 编译系统完整链路分析
CAM 的编译系统采用 三层 shell 脚本 + CMake + 华为 CANN npu_op_* 构建框架 的架构,从顶层入口到内核编译的完整调用链如下:
build/cam/build.sh ← 顶层入口,解析 module 名 + 转发 -c/-a/-q/-p/-r
└─ build/cam/comm_operator/build.sh ← 模块级构建,管理编译阶段开关
├─ build/cam/comm_operator/compile_ascend_proj.sh ← 单 SOC 编译主流程
│ ├─ select_ops.py ← 算子选择(registry 解析 + 互斥规则)
│ ├─ set_conf.py ← 修改 CMakePresets.json(build_type/vendor)
│ ├─ msopgen gen ← CANN 工具:生成 SOC 特定算子工程骨架
│ ├─ cmake -S . -B build_out --preset=default
│ └─ cmake --build build_out --target binary/package
└─ build/cam/comm_operator/build_pybind.sh ← Python whl 包构建
└─ src/cam/comm_operator/pybind/setup.py ← NpuExtension + bdist_wheel
└─ pytorch_extension/bdist_wheel_build.py ← auditwheel repair 封装
1.1 顶层入口 build/cam/build.sh
关键设计:
- 通过 getopts ":dhc:" 仅解析 -d(Debug)、-c(SOC 类型)、-h(help),其余选项(-a/-q/-p/-r)原样转发给子模块脚本。
- 导出全局路径变量:ROOT_PATH、SRC_PATH、BUILD_OUT_PATH、SCRIPTS_PATH、TEST_PATH、BUILD_PATH、CAM_THIRD_PARTY_PATH。
- 通过 CPATH 注入 catlass 头文件路径:export CPATH=${CAM_THIRD_PARTY_PATH}:${CAM_THIRD_PARTY_PATH}/catlass/include:${CPATH}。
- prepare_cam_third_party() 负责初始化 catlass 子模块(git submodule update --init --recursive)。
- 模块分发逻辑:all/comm_operator 走 comm_operator 构建;all/nda 且 -c ascend950 走 nda 构建。
关键代码(build.sh:137-156):
if [[ "$MODULE_NAME" == "all" || "$MODULE_NAME" == "comm_operator" ]]; then
if [[ -z "${SOC_TYPE}" || "${SOC_TYPE}" == "ascend910_93" ]]; then
IS_MODULE_EXIST=1
if ! prepare_cam_third_party "${CAM_THIRD_PARTY_PATH}"; then
exit 1
fi
${SCRIPTS_PATH}/comm_operator/build.sh $@
fi
fi
1.2 模块级构建 build/cam/comm_operator/build.sh
编译阶段开关(互斥设计):
| 变量 | 默认值 | 含义 |
|---|---|---|
ENABLE_SRC_BUILD |
1 | 编译 .run 算子包 |
ENABLE_PYBIND_BUILD |
1 | 编译 .whl Python 包 |
ENABLE_UT_BUILD |
0 | 编译单元测试 |
ENABLE_RUN_ONLY |
0 | 仅编译 run 包(-r) |
USE_W4A8 |
0 | 选择 w4a8 量化变体(-q) |
OP_SELECT |
"" | 算子选择列表(-a) |
互斥规则:
- -r(run only)和 -p(pybind only)互斥,同时指定会 exit 1。
- -a 要求先指定 -c(SOC 版本),因为算子选择需要 SOC 上下文。
- -q 也依赖 -c,因为 w4a8 变体是 SOC 相关的。
关键转发(build.sh:107-108):
export CAM_OP_SELECT="$OP_SELECT"
export CAM_USE_W4A8="$USE_W4A8"
1.3 单 SOC 编译主流程 compile_ascend_proj.sh
这是最核心的编译脚本,完成从算子选择到 .run 包产出的全过程:
核心函数链:
list_soc_versions()— 从operator_registry.json读取所有注册的 SOC 版本。resolve_ops()— 调用select_ops.py解析最终算子列表。copy_ops_include()— include-list 模式:仅拷贝选中算子的op_host/op_kernel/op_api到目标工程目录(区别于旧的 full-copy + exclude-list 模式,避免同名算子文件覆盖)。build_ascend_proj()— 单 SOC 编译主函数。
build_ascend_proj() 关键步骤:
# 1. 调用 msopgen 生成 SOC 特定算子工程
msopgen gen -i ./ascend_kernels/AddCustom.json -c ai_core-${soc_version} -f pytorch -lan cpp -out ${MODULE_BUILD_PATH}/${proj_name}
# 2. 删除模板自带的 AddCustom 示例算子
rm -rf ${MODULE_BUILD_PATH}/${proj_name}/op_host/add_custom*
rm -rf ${MODULE_BUILD_PATH}/${proj_name}/op_kernel/add_custom*
# 3. 拷贝 CMakeLists.txt 和 cmake_files/
cp ./ascend_kernels/CMakeLists.txt ${MODULE_BUILD_PATH}/${proj_name}/
cp ./ascend_kernels/cmake_files/op_host/CMakeLists.txt ${MODULE_BUILD_PATH}/${proj_name}/op_host/
cp ./ascend_kernels/cmake_files/op_kernel/CMakeLists.txt ${MODULE_BUILD_PATH}/${proj_name}/op_kernel/
cp -rf ./ascend_kernels/cmake_files/cmake ${MODULE_BUILD_PATH}/${proj_name}/
# 4. 修改 CMakePresets.json(build_type、ENABLE_SOURCE_PACKAGE、vendor_name)
python3 $SCRIPTS_PATH/comm_operator/set_conf.py ${MODULE_BUILD_PATH}/${proj_name}/CMakePresets.json $build_type True CAM
# 5. 配置 CANN 包路径
export ASCEND_CANN_PACKAGE_PATH="${ASCEND_TOOLKIT_HOME}" # 默认 /usr/local/Ascend/ascend-toolkit/latest
# 6. 推导 CATLASS_HOME_PATH(从 CPATH 解析)
export CATLASS_HOME_PATH=$(echo "${CPATH}" | tr ':' '\n' | grep "catlass" | sed 's|/include||')
# 7. CMake configure + build
cmake -S . -B build_out --preset=default -DCMAKE_BUILD_TYPE=$build_type
cmake --build build_out --target binary -j${BUILD_JOBS}
cmake --build build_out --target package -j${BUILD_JOBS}
# 8. 产出 .run 包
cp build_out/*.run ${BUILD_OUT_PATH}/comm_operator/run/CAM_${soc_version}_${os_id}_${arch}.run
关键 patch 机制(compile_ascend_proj.sh:177-192):
由于 npu_op_* 构建系统的 simple_kernel_compile 不读取 custom_compile_options.ini,脚本通过 sed 直接 patch .make 文件来注入 SHMEM/CATLASS 的 include 路径:
KERNEL_COMPILE_OPTS=""
if [ -n "${SHMEM_HOME_PATH}" ]; then
KERNEL_COMPILE_OPTS="-I${SHMEM_HOME_PATH}/shmem/include -I${SHMEM_HOME_PATH}/shmem/src/device"
fi
if [ -n "${CATLASS_HOME_PATH}" ]; then
KERNEL_COMPILE_OPTS="${KERNEL_COMPILE_OPTS} -I${CATLASS_HOME_PATH}/include"
fi
find build_out/op_kernel/CMakeFiles -name "build.make" -exec sed -i "s|--compile-options=\"\"|--compile-options=\\\"${KERNEL_COMPILE_OPTS}\\\"|g" {} +
1.4 Python whl 包构建 build_pybind.sh
build_pybind() {
local build_tmp_dir="${MODULE_BUILD_PATH}/pybind"
local wheel_out_dir="${MODULE_BUILD_OUT_PATH}/dist"
rm -rf "${build_tmp_dir}" "${wheel_out_dir}"
mkdir -p "${wheel_out_dir}" "$(dirname "${build_tmp_dir}")"
cp -r $MODULE_SRC_PATH/pybind "${build_tmp_dir}"
export MAX_JOBS=${CAM_BUILD_JOBS:-8}
cd "${build_tmp_dir}"
python3 setup.py bdist_wheel --dist-dir="${wheel_out_dir}"
}
注意: cp -r $MODULE_SRC_PATH/pybind "${build_tmp_dir}" 仅在 build_tmp_dir 不存在时才会将 pybind 目录内容直接拷贝到 build_tmp_dir(即 build_tmp_dir/setup.py)。如果 build_tmp_dir 已存在,会嵌套一层 pybind/pybind/。脚本通过 rm -rf "${build_tmp_dir}" 确保每次都是干净构建。
2. 算子选择机制
2.1 算子注册表 operator_registry.json
{
"soc_versions": {
"ascend910_93": [
"dispatch_layout",
"fused_deep_moe",
"moe_combine_normal",
"moe_dispatch_normal",
"notify_dispatch"
]
},
"operator_meta": {
"fused_deep_moe": { "requires_shmem": false, "family": "fused_deep_moe", "variant": "base" },
"dispatch_layout": { "requires_shmem": false },
"moe_combine_normal": { "requires_shmem": false },
"moe_dispatch_normal": { "requires_shmem": false },
"notify_dispatch": { "requires_shmem": false }
}
}
设计要点:
- 算子身份 = 源码目录名(ascend_kernels/<op_name>/)。
- soc_versions 定义每个 SOC 支持的算子列表(当前仅注册 ascend910_93)。
- operator_meta 存储构建元数据(requires_shmem、family、variant)。
- 注释说明:要支持新 SOC 只需在 soc_versions 添加条目;要添加算子只需在对应 SOC 列表追加目录名。
2.2 算子选择逻辑 select_ops.py
解析流程:
- 加载注册表 →
load_registry() - 获取 SOC 支持列表 →
get_soc_list() - 解析用户 -a 列表 →
split_ops()(分号分隔,禁止空条目) - 验证用户选择 →
validate_user_ops()(每个 -a 条目必须在 SOC 支持列表中) - resolve() 核心规则:
互斥规则(fused_deep_moe 家族):
- fused_deep_moe(base)和 fused_deep_moe_w4a8 共享相同的源码文件名(fused_deep_moe.*),因此互斥——同一 run 包只能编译其中一个。
- --quant(-q)选择 w4a8 变体,此时 base 被禁止。
- fused_deep_moe_fwk 是独立算子(文件名为 fused_deep_moe_fwk.*),不受互斥约束。
- 全量构建(无 -a)时默认保留 base,丢弃 w4a8(带 NOTE 提示)。
SHMEM 过滤:
- 当 SHMEM_HOME_PATH 未设置时,自动丢弃 requires_shmem=true 的算子。
确定性排序: - 最终列表按注册表中的顺序排列,确保构建可复现。
输出格式:
- 每行一个算子目录名,由 compile_ascend_proj.sh 通过 tr '\n' ' ' 转为空格分隔列表。
3. 编译依赖分析
3.1 核心依赖矩阵
| 依赖项 | 版本 | 用途 | 来源 |
|---|---|---|---|
| CANN | 8.5 / 9.0 | 华为 Ascend 算子开发工具包(msopgen、npu_op_*、ACL) | 官方 .run 安装包 |
| torch | 2.8.0 | PyTorch 框架(pybind 编译需要) | pip |
| torch-npu | 2.8.0.post2 (CANN 8.5) / 2.8.0.post4 (CANN 9.0) | 华为 PyTorch NPU 适配(NpuExtension、NpuBridge) | 华为 gitcode 发布 |
| gtest | 1.16.0 | 单元测试框架 | GitHub 源码编译 |
| OpenMPI | 5.0.7 | 多线程测试(MPI 接口) | 官方源码编译 |
| nlohmann/json | 3.12.0 | JSON 解析(测试/配置) | GitHub 源码编译 |
| catlass | v1-stable(pin) | 华为 CANN 模板库(GEMM/Epilogue 模板) | git submodule |
| Python | 3.11 | 构建脚本 + pybind | Miniconda |
| cmake | ≥3.16 | 构建系统 | 系统包 |
| gcc/g++ | - | C++17 编译 | 系统包 |
3.2 CANN 版本与 torch-npu 版本匹配
| CANN 版本 | torch-npu wheel | 来源 |
|---|---|---|
| 8.5.T63 | torch_npu-2.8.0.post2-cp311-cp311-manylinux_2_28_aarch64.whl |
gitcode Ascend/pytorch v7.3.0-pytorch2.8.0 |
| 9.0.0 | torch_npu-2.8.0.post4-cp311-cp311-manylinux_2_28_aarch64.whl |
gitcode Ascend/pytorch v26.0.0-pytorch2.8.0 |
3.3 catlass 子模块
.gitmodules 配置:
[submodule "src/cam/third_party/catlass"]
path = src/cam/third_party/catlass
url = https://gitcode.com/cann/catlass.git
branch = catlass-v1-stable
catlass 在编译中的作用:
- 提供 fused_deep_moe 算子的 GEMM/Epilogue 模板(grouped_matmul_slice_m_per_token_dequant_*.h、block_epilogue_*.hpp 等)。
- 通过 CPATH 环境变量注入(${CAM_THIRD_PARTY_PATH}/catlass/include)。
- 在 compile_ascend_proj.sh 中自动推导 CATLASS_HOME_PATH 并 patch 到 kernel compile options。
3.4 pybind 编译依赖
setup.py 中的 include 路径:
include_dirs=[
os.path.join(torch_npu_path, "include"),
os.path.join(torch_npu_path, "include/third_party/acl/inc/acl/"),
os.path.join(torch_npu_path, "include/third_party/acl/inc"),
os.path.join(os.environ["ASCEND_HOME_PATH"], f"{arch}-linux", "include"),
os.path.join(os.environ["ASCEND_HOME_PATH"], f"{arch}-linux", "include", "hccl"),
os.path.join(os.environ["ASCEND_HOME_PATH"], f"{arch}-linux", "include", "experiment", "runtime"),
os.path.join(os.environ["ASCEND_HOME_PATH"], f"{arch}-linux", "include", "experiment", "msprof"),
os.path.join(torch_path, "include"),
os.path.join(os.path.dirname(__file__), "./", "pytorch_extension")
]
链接库:
libraries=["torch_npu", "gcov", "runtime", "torch", "ascendcl", "profapi"]
FP8/FP4 探测机制:
- setup.py 中的 _acl_has_fp8_fp4() 函数通过编译探测 acl_base.h 是否声明了 ACL_FLOAT8_E5M2/ACL_FLOAT8_E8M0/ACL_FLOAT4_E2M1 枚举值。
- 如果支持,定义 -DCAM_ACL_HAS_FP8_FP4,使 pytorch_npu_helper.hpp 填充低精度 dtype 表。
- 这是为了兼容不同 CANN 版本(CANN 8.5 的 acl_base.h 枚举到 BF16 为止,CANN 9.0+ 才包含 FP8/FP4)。
4. Docker 部署环境完整分析
4.1 Dockerfile 多阶段构建
基础阶段(base):
- 镜像:ubuntu:24.04
- 系统依赖:vim git cmake net-tools wget gcc g++ make iputils-ping iproute2 libnuma-dev + 开发库(zlib1g-dev libbz2-dev libssl-dev 等)
- Miniconda 安装到 /opt/conda
- pip 镜像:https://pypi.tuna.tsinghua.edu.cn/simple
- Python 环境:conda create -n cam_py311_pt28 python=3.11
- Python 包:attrs cython numpy==1.24.0 decorator sympy cffi pyyaml pathlib2 psutil protobuf==3.20 scipy requests absl-py pybind11 pytest setuptools_scm ninja
- gtest 1.16.0:从 GitHub 源码编译安装到 /usr/local
- OpenMPI 5.0.7:源码编译,prefix /usr/local/openmpi-5.0.7,启用 --enable-orterun-prefix-by-default
- nlohmann/json 3.12.0:源码编译安装到 /usr
CANN 阶段(二选一):
| 阶段名 | CANN 版本 | 安装内容 |
|---|---|---|
config_a3_8.5_open |
8.5.T63 | Ascend-cann_8.5.0_linux-aarch64.run + Ascend-cann-A3-ops_8.5.0_linux-aarch64.run |
config_a3_9.0_open |
9.0.0 | Ascend-cann-toolkit_9.0.0_linux-aarch64.run + Ascend-cann-A3-ops_9.0.0_linux-aarch64.run |
最终阶段(final):
- SHMEM 1.3.0:从 gitcode.com/cann/shmem.git 源码构建 whl + 安装到 /usr/local/Ascend/shmem/latest/
- 环境变量注入 /etc/bashrc:
- GTEST_ROOT=/usr/local
- PATH 添加 OpenMPI bin
- LD_LIBRARY_PATH 包含 OpenMPI、CANN lib64、CANN devlib
- 自动 source CANN set_env.sh + SHMEM set_env.sh
- 默认激活 cam_py311_pt28 conda 环境
4.2 docker-compose.yml
services:
cam-dev:
image: ${IMAGE_NAME}
container_name: ${CONTAINER_NAME}
privileged: true # 必须特权模式(NPU 设备访问)
tty: true
stdin_open: true
command: /bin/bash
volumes:
- /home:/home
- /ssd_0:/ssd_0
- /mnt:/mnt
- /sys:/sys
- /usr/local/Ascend/driver:/usr/local/Ascend/driver # NPU 驱动挂载
- /usr/local/bin/npu-smi:/usr/local/bin/npu-smi # NPU 管理工具
- /etc/ascend_install.info:/etc/ascend_install.info # NPU 安装信息
- /etc/localtime:/etc/localtime
devices:
- /dev/vfio/vfio # SR-IOV VF 设备
- /dev/uio0 ~ /dev/uio7 # UIO 设备(8 卡 NPU)
关键部署约束:
- privileged: true 是 NPU 设备访问的硬性要求。
- 挂载 /usr/local/Ascend/driver 使容器内可见宿主机的 NPU 驱动。
- devices 列表暴露 VFIO 和 UIO 设备给容器(用于直通 NPU 设备)。
- 默认网络为 bridge(cam-net)。
4.3 .env 配置
COMPOSE_PROJECT_NAME=cam90
IMAGE_NAME=cam-dev:a3_9.0_open
CONTAINER_NAME=my_cam_dev
注意: 注释提醒 COMPOSE_PROJECT_NAME 和 CONTAINER_NAME 在多容器同机部署时必须全局唯一。
5. .run 安装包与 .whl 打包机制
5.1 .run 包(算子运行时包)
产出路径:
output/cam/comm_operator/run/CAM_${soc_version}_${os_id}_${arch}.run
# 例如:CAM_ascend910_93_ubuntu24.04_aarch64.run
安装方式:
./CAM_ascend910_93_ubuntu24.04_aarch64.run --install-path=/usr/local/Ascend/ascend-toolkit/latest/opp
source /usr/local/Ascend/ascend-toolkit/latest/opp/vendors/CAM/bin/set_env.bash
内部结构(npu_op_* 构建系统生成):
- packages/vendors/CAM/op_impl/ai_core/tbe/ — 算子实现目录
- kernel/${compute_unit}/ — 编译好的内核二进制
- config/${compute_unit}/ — 算子配置 JSON
- ${vendor_name}_impl/dynamic/ — 动态 shape 实现(如果启用)
- framework/pytorch/ — npu_supported_ops.json(支持的算子列表)
5.2 .whl 包(Python 接口包)
产出路径:
output/cam/comm_operator/dist/umdk_cam_op_lib-${version}-cp311-cp311-linux_aarch64.whl
版本号格式: V_version.R_version.C_version.B_version(默认 209.0.0.B001,通过 CAM_WHL_VERSION 环境变量覆盖)。
安装方式:
pip install --force-reinstall ./output/cam/comm_operator/dist/umdk_cam_op_lib-*.whl
whl 构建关键机制:
- 使用 torch_npu.utils.cpp_extension.NpuExtension(华为扩展的 CMake 构建)。
- bdist_wheel_build.py 在构建后调用 auditwheel repair 修复 manylinux 标签,并排除 PyTorch 内部 so(libc10.so、libtorch.so 等)。
- 链接的 so:torch_npu、runtime、torch、ascendcl、profapi、gcov。
6. RPM spec 分析
6.1 总体结构
umdk.spec 是 UMDK 项目的顶层 RPM 打包规范,CAM 模块本身不单独打包 RPM,而是作为 UMDK 源码的一部分存在。
关键宏定义:
| 宏 | 默认值 | 含义 |
|---|---|---|
with_64kb |
aarch64 下可通过 -with_64kb 启用 |
64KB 页大小内核支持 |
build_all |
1 | 全量构建开关 |
with_urma/with_urpc/with_dlock/with_ums |
0 | 各子模块开关 |
kernel_version |
自动检测 | 内核版本(用于 kmod 构建) |
6.2 构建流程
%build
cmake ./src/ -DCMAKE_INSTALL_PREFIX=/usr \
-DBUILD_DATE=%{rpm_build_date} \
-DASAN="enable" # 仅 with asan
-DTSAN="enable" # 仅 with tsan
-DCODE_COVERAGE="enable" # 仅 with gcov
-DRELEASE_ENABLE="enable" # 仅 with release_enable
-DURMA_TEST="enable" # 仅 with test
-DBUILD_ALL="enable" # build_all
-DBUILD_URMA="enable" # build_all 或 with urma/urpc
-DBUILD_URPC="enable" # build_all 或 with urpc
-DBUILD_UMS="enable" # with ums
-DBUILD_DLOCK="enable" # with dlock
make %{?_smp_mflags}
6.3 子包划分
| 子包 | 内容 |
|---|---|
umdk-urma-lib |
liburma.so.*、liburma_common.so.*、liburma_ubagg.so.* |
umdk-urma-devel |
liburma.so、头文件 urma_*.h |
umdk-urma-tools |
urma_admin、urma_ping、urma_perftest |
umdk-urma-bin |
libtpsa.so、TPSA 配置 |
umdk-urpc-framework |
liburpc_framework.so.* |
umdk-urpc-umq |
libumq.so.*、libumq_buf.so.*、libumq_ub.so.* |
umdk-dlock-lib |
libdlockm.so.*、libdlocks.so.*、libdlockc.so.* |
umdk-ums |
ums.ko(内核模块) |
umdk-ums-tools |
libums-preload.so、ums_run |
umdk-ums-agent |
ums_agent 守护进程 + systemd service |
6.4 UMS 内核模块特殊处理
- 支持 64KB 页大小内核(
umdk-ums-64kb子包)。 %pre阶段检查运行时页大小是否匹配。%post阶段处理 weak-modules 兼容(内核版本不一致时)。- 自动排除 dracut(
omit_drivers+=" ums ")。
7. 第三方依赖(catlass submodule)
7.1 catlass 的角色
catlass(CANN Template Library for Ascend)是华为提供的 AscendC 内核模板库,为 fused_deep_moe 算子提供高性能 GEMM/Epilogue 实现。
7.2 目录结构(pin 在 v1-stable 分支)
src/cam/third_party/catlass/
└── include/ ← 头文件(通过 CPATH 注入)
7.3 在 fused_deep_moe 中的使用
fused_deep_moe 的 op_kernel/fused_deep_moe/ 目录包含大量基于 catlass 的模板:
| 文件 | 功能 |
|---|---|
grouped_matmul_slice_m_per_token_dequant_multistage_workspace.h(24KB) |
基础 grouped GEMM(per-token dequant) |
grouped_matmul_slice_m_per_token_dequant_swiglu_quant_multistage_workspace.h(78KB) |
SwiGLU + 量化融合 GEMM |
post_swiglu_dynamic_quant.h(12KB) |
SwiGLU 后动态量化 |
block_mmad_preload_async_with_callback_resident_a.h(20KB) |
MMAD 预取 + resident A 优化 |
block_epilogue_per_token_dequant.hpp(21KB) |
per-token dequant epilogue |
block_epilogue_per_token_dequant_swiglu.h(17KB) |
SwiGLU dequant epilogue |
tile_stride_binary.h(5KB) |
tile stride 二元操作 |
tile_stride_muls.h(3KB) |
tile stride 乘法 |
7.4 编译注入路径
- 顶层 build.sh:
export CPATH=${CAM_THIRD_PARTY_PATH}/catlass/include:${CPATH} - compile_ascend_proj.sh:从 CPATH 解析
CATLASS_HOME_PATH - op_kernel/CMakeLists.txt:
npu_op_kernel_options("" ALL OPTIONS -I${CATLASS_HOME_PATH}/include) - op_host/CMakeLists.txt:
npu_op_code_gen(COMPILE_OPTIONS -I${CATLASS_HOME_PATH}/include) - build.make patch:
sed -i "s|--compile-options=\"\"|--compile-options=\"-I${CATLASS_HOME_PATH}/include\"|g"
8. 构建产物与安装路径
8.1 构建产物清单
| 产物 | 路径 | 说明 |
|---|---|---|
.run 算子包 |
output/cam/comm_operator/run/CAM_<soc>_<os>_<arch>.run |
单 SOC 完整算子包 |
.whl Python 包 |
output/cam/comm_operator/dist/umdk_cam_op_lib-*.whl |
pybind 接口 |
| 解压的 run 包 | output/cam/comm_operator/extract/<soc>/ |
通过 -x 触发 |
| 中间工程 | build/cam/build_master/comm_operator/ascend_kernels_<soc>_proj/ |
msopgen 生成的工程 |
8.2 安装路径
| 组件 | 安装路径 |
|---|---|
| 算子包 | /usr/local/Ascend/ascend-toolkit/latest/opp/vendors/CAM/ |
| Python 包 | site-packages/umdk_cam_op_lib/ |
| SHMEM | /usr/local/Ascend/shmem/latest/ |
| CANN | /usr/local/Ascend/ascend-toolkit/latest/ |
| OpenMPI | /usr/local/openmpi-5.0.7/ |
| gtest | /usr/local/ |
8.3 环境变量
# CANN
export ASCEND_HOME_PATH=/usr/local/Ascend/ascend-toolkit/latest
export ASCEND_CANN_PACKAGE_PATH=/usr/local/Ascend/ascend-toolkit/latest
source /usr/local/Ascend/ascend-toolkit/set_env.sh
# SHMEM
export SHMEM_HOME_PATH=/usr/local/Ascend/shmem/latest
source /usr/local/Ascend/shmem/latest/set_env.sh
# OpenMPI
export PATH=/usr/local/openmpi-5.0.7/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/openmpi-5.0.7/lib:...:${LD_LIBRARY_PATH}
# catlass(构建时)
export CPATH=${CAM_THIRD_PARTY_PATH}/catlass/include:${CPATH}
9. 关键设计洞察
9.1 include-list vs exclude-list 演进
compile_ascend_proj.sh 的注释明确说明了从 full-copy + exclude-list 到 include-list 的迁移原因:
Unlike the old full-copy + exclude_list approach, only the operators resolved by select_ops.py are copied here, which fundamentally avoids same-name operators (the fused_deep_moe family) overwriting each other's files.
这是 fused_deep_moe / fused_deep_moe_w4a8 共享文件名的直接后果——全量拷贝会导致文件覆盖。
9.2 build.make patch 的必要性
npu_op_ 构建系统的 simple_kernel_compile 不读取 custom_compile_options.ini,因此 --compile-options="" 默认为空。华为选择通过 sed patch .make 文件来注入 SHMEM/CATLASS 路径,这是一种非侵入式的 workaround*,避免了修改 CANN 构建系统源码。
9.3 算子身份 = 源码目录名
整个算子选择机制的核心设计是算子身份与源码目录名一一对应:
- operator_registry.json 中的列表项 = ascend_kernels/ 下的目录名
- select_ops.py 输出 = 目录名列表
- copy_ops_include() 按目录名拷贝
这种设计使得添加新算子只需:创建目录 → 在 registry 中添加条目 → 完成。
9.4 版本匹配的脆弱性
CANN ↔ torch-npu 的版本匹配是硬编码在 Dockerfile 中的: - CANN 8.5 → torch_npu 2.8.0.post2 - CANN 9.0 → torch_npu 2.8.0.post4
升级 CANN 必须同步修改 Dockerfile 中的 wheel URL。setup.py 的 FP8/FP4 探测机制部分缓解了运行时版本差异,但构建时依赖仍需人工维护。
9.5 CAM 不单独打包 RPM
CAM 的 .run 和 .whl 包是独立于 UMDK RPM 体系的。umdk.spec 中的 RPM 打包仅覆盖 URMA/URPC/DLock/UMS 等子模块,CAM 通过独立的安装脚本(run --install-path + pip install)部署。
10. 相关文件索引
| 文件 | 作用 |
|---|---|
build/cam/build.sh |
顶层构建入口 |
build/cam/comm_operator/build.sh |
comm_operator 模块构建 |
build/cam/comm_operator/compile_ascend_proj.sh |
单 SOC 编译主流程 |
build/cam/comm_operator/select_ops.py |
算子选择逻辑 |
build/cam/comm_operator/set_conf.py |
CMakePresets.json 修改 |
build/cam/comm_operator/build_pybind.sh |
whl 包构建 |
src/cam/comm_operator/ascend_kernels/operator_registry.json |
算子注册表 |
src/cam/comm_operator/ascend_kernels/CMakeLists.txt |
顶层 CMake |
src/cam/comm_operator/ascend_kernels/cmake_files/op_host/CMakeLists.txt |
host 库 CMake |
src/cam/comm_operator/ascend_kernels/cmake_files/op_kernel/CMakeLists.txt |
kernel 库 CMake |
src/cam/comm_operator/ascend_kernels/cmake_files/cmake/func.cmake |
自定义 CMake 函数 |
src/cam/comm_operator/ascend_kernels/cmake_files/cmake/util/ascendc_impl_build.py |
AscendC 内核编译生成器 |
src/cam/comm_operator/pybind/setup.py |
pybind whl 构建配置 |
src/cam/comm_operator/pybind/pytorch_extension/bdist_wheel_build.py |
auditwheel 修复 |
docker/cam/Dockerfile |
多阶段构建(CANN 8.5/9.0) |
docker/cam/docker-compose.yml |
容器编排 |
docker/cam/.env |
容器配置 |
umdk.spec |
UMDK RPM 打包规范 |
.gitmodules |
catlass 子模块配置 |
src/cam/third_party/catlass/ |
CANN 模板库(submodule) |
RELEASE-NOTES.md / RELEASE-NOTES.ch.md |
版本发布说明 |