Pull Request已成功合入, 合并人@CANN-robot
(感谢 zhang-song-rui 的贡献)变更摘要
本改动主要面向 DAV_3510(Ascend950)平台,去除向量算子在 SSBUF 场景下冗余的系统 workspace 预留。核心是新增 norm/norm_common/op_host/vector_workspace.h,提供 Ops::NN::GetVectorSystemWorkspaceSize:当 NPU 架构为 NpuArch::DAV_3510 时返回 0,其余平台仍返回 GetLibApiWorkSpaceSize()。大量 norm 类算子(batch_norm*、layer_norm*、rms_norm*、group_norm*、add_layer_norm*、softmax 等)的 tiling 将原先固定预留的系统 workspace(如 GetLibApiWorkSpaceSize()、各 MINIMAL_WORKSPACE/DEFAULT_WORKSPACE_SIZE 常量)改为 0 或改为调用该 helper;对应 kernel 在 __NPU_ARCH__ == 3510 下直接使用 workspace 而非 AscendC::GetUserWorkspace,并去掉 workspace == nullptr 的提前返回;同时补充 ascend950/ascend350 的 SoC 名映射与 JIT wrapper 的编译依赖。
主要改动
- 新增向量 workspace 辅助接口: 新增
vector_workspace.h中的Ops::NN::GetVectorSystemWorkspaceSize,按NpuArch::DAV_3510判定系统 workspace 预留,成为各算子 tiling 的统一入口。 - norm 类算子系统 workspace 置零/切换: 各算子 tiling 将
GetLibApiWorkSpaceSize()或固定常量(如MINIMAL_WORKSPACE、DEFAULT_WORKSPACE_SIZE、BNG_WORKSPACE_RESERVED、LNV3_MINIMAL_WORKSPACE等)改为 0 或改调GetVectorSystemWorkspaceSize,使workspaceSize_与currentWorkspace[0]不再包含冗余系统预留。 - kernel 侧 workspace 获取方式调整:
add_layer_norm_quant、batch_norm_grad(_v3)、layer_norm_grad(_v3)、group_norm_grad等在__NPU_ARCH__ == 3510下直接以workspace作为usrWorkspace,非 3510 仍走AscendC::GetUserWorkspace。 - 移除空 workspace 提前返回与冗余参数:
group_norm_v2、layer_norm_v3/v4、add_rms_norm_dynamic_mx_quant等去掉workspace == nullptr/userWS == nullptr的早返回,并删除Init中的workspace形参及传入;group_norm_grad将空 tensor 分支前移并调整 tiling key 顺序。 - 构建与平台映射配套:
opdesc_parser.py新增ascend950、ascend350、ascend950pr_9599的 SoC 映射,gen_ops_info.cmake将opdesc_parser.py与custom_compile_options.ini加入 JIT wrapper 生成依赖,保证编译选项变更能触发重新生成。
此外 batch_norm_elemt 以 AllocScalar/ConvertToTensor 广播标量 1 替代 l0op::OnesLike,group_norm_v2 两趟 kernel 增加了 V_MTE2 同步。
🧩 本次 Review 已使用自定义 Skill:




The MR can not be merged, because of CodeReview discussion not resolved
If you want to solve this problem, you can click here to do it in the FAQs.


Pull Request 已合并或已关闭。
If you want to solve this problem, you can click here to do it in the FAQs.


描述
减少 NN Vector 路径冗余的系统 workspace,保留原有用户空间申请。
整改策略:原来额外申请了 userworkspace 的分支,保留系统预留和用户空间;没有额外 userworkspace 且不依赖 KFC 的分支,将系统空间申请量清零,并在 kernel 入口适配零 workspace。保留内部 kernel 参数和调用形式;无需用户空间的路径不调用 GetUserWorkspace,需要用户空间的路径保留正确的地址转换。
混合分支在入口按 tilingKey 或既有模板模式处理用户空间转换;适配集中在 _apt.cpp。AddRmsNormDynamicQuant/V2 没有对应 _apt.cpp,使用现有入口 .cpp,仅 SPLIT 模式转换用户地址。
AddLayerNormQuant 保留非空路径原有申请;FullLoad 动态量化按原 useWs_ 条件转换用户地址,Welford 动态量化保留转换,空输入零空间路径跳过转换。
AddRmsNormCast、AddRmsNormDynamicQuant 在写入总申请量前检查用户空间大小:为 0 时清零系统预留,否则保持原申请。
AddRmsNorm、InplaceAddRmsNorm、RmsNorm 保留原有用户空间及系统预留。LpNormV2 不在本次修改范围内,保留原公共 Reduce 行为。
BatchNormGrad、BatchNormGradV3 的 batch_norm_grad_tiling.cpp、batch_norm_grad_v3_tiling.cpp 各仅将文件内 BNG_WORKSPACE_RESERVED 常量设为 0,各自四处赋值仍引用原常量;Split 分支其他文件的独立同名常量及申请不变。
内部计算 kernel 的 workspace 参数和原有调用形式保持不变;本 PR 不包含 BatchNormElemt API 改写或 GroupNormV2 额外同步修改。
GroupNormGrad 将空输入分支前置,完成 dgamma/dbeta 初始化后返回;非空路径统一调用一次 GetUserWorkspace,保留原有 20 个模板分发及调用,删除分支内重复转换,不保留 workspace 判空返回。
对仅服务于已清零路径的 workspace 常量,统一保留原赋值引用、将常量值设为 0。覆盖 AddRmsNormDynamicQuant 空输入、BatchNormGrad/V3 推理、GroupNormGrad 空输入、GroupNormV2、LayerNormGrad/V3 重计算、LayerNormV3/V4 对应路径以及 RmsNormGrad 空输入和 Regbase 路径,共 17 处赋值。需要用户空间的分支及其独立常量保持不变。
验证
2026-10-17 常量收敛后重新完成 NN Host 构建,现有 UT 388/388 通过。完成常量作用域和引用检查、GroupNormGrad 普通分支与基线一致性检查,以及按原文件行尾格式的 diff 检查。Host UT 不替代设备侧编译和执行验证;本次未重新进行设备验证,下方设备数据仅为历史版本结果。
依赖及构建
本 PR 无 CMake 改动,无新增 SSBUF 或芯片支持编译选项。opbase PR 1007 合入后,再更新对应远程依赖 commit。
关联
未关联独立 Issue。相关 opbase PR 1007、Math PR 6242、Transformer PR 13661。
AI/Agent生成声明
历史版本验证记录(不作为当前提交的设备验证结论)
前一轮设备验证(2026-10-15,57018e2 提交)
环境:Ascend950PR_9579,CANN 9.2.0(20260909),默认固定 opbase 0c5e257。设备运行前确认 npu-smi 无运行进程,/proc 中无设备句柄占用。
前一轮 140 项输出字节与 workspace 实测结果(非最终申请量)
前一轮提交与检查
基于上游
4bf3e9c010b15eb99962160db2089cb13f368d11,保持一个整改提交57018e2e8e183e92b7d0a4ee33172961757cf210。Host 构建、打包、diff 检查及上述设备回放通过。文档更新
本 PR 未增加仓内文档。
类型标签
AI/Agent生成声明
历史分类验证结果(2026-10-13,旧 SSBUF 方案)
验证环境:Ascend950PR_9579,CANN 9.2.0(20260909)。这里的“二进制一致”指相同输入下输出张量的原始字节一致,不是编译产物文件一致。基线输入固定回放,独立检查输出元数据和原始字节。
范围限制:全量结果来自变基前联调版本(原依赖对照、opbase 6dc960b 加公共补丁);不能替代 opbase PR 1007 合入、更新远程固定 commit 后的默认构建复测。当前该依赖接入仍待完成。2026-10-13 AddRmsNormCast 空归约专项使用当时 NN 提交 884dc23ad,单独标明。
【输出】二进制一致
固定输入 kernel 回放:407/407 项输出逐字节一致。新增大规模候选:73/75 项直接与最初基线输出一致,实际基线 ≥20 μs 的用例 74 项。
另外:BatchNorm 跨核 16/16、组合 API 29/29 输出字节一致;GroupNorm 分块边界 12/12 在配套同步修复的对照下字节一致;2026-10-13 空归约 14/14 输出字节一致,workspace 从 16 MiB 降到 0。各测试集有重叠,不应将计数相加作为去重总数。新增 75 项中两项基线差异详见下一节。
固定输入逐用例结果(展开)
【精度标准】与修改前一致
除以下两项基线差异外,已测固定输入按输出字节一致验收。两项不能表述为“与最初旧版本完全一致”:
2026-10-13 空归约 14 项另作独立 NPY 检查:rstd 全为 NaN,其他输出为空,NaN 位模式在修改前后逐字节一致;两版越界检查均通过。
精度控制实验:独立数学参考及最终 GroupNorm 回归
{ "independent_reference": { "method": "NumPy float32 mean/population variance, eps=1e-5, channel affine; separate diagnostic from byte-comparison gates", "case": "group_norm_v2_large_outer", "records": [ { "variant": "original", "max_abs_error": 5.846162796020508, "elements_abs_error_above_0_01": 155403 }, { "variant": "original_self", "max_abs_error": 5.846162796020508, "elements_abs_error_above_0_01": 151284 }, { "variant": "workspace_before_sync_fix", "max_abs_error": 5.787575721740723, "elements_abs_error_above_0_01": 158699 }, { "variant": "sync_probe", "max_abs_error": 0.0019512176513671875, "elements_abs_error_above_0_01": 0 }, { "variant": "final", "max_abs_error": 0.0019512176513671875, "elements_abs_error_above_0_01": 0 } ] }, "final_regression": { "total": 8, "identical": 8, "cases": [ { "case": "group_norm_v2_00_small", "identical": true, "reference": "original frozen baseline" }, { "case": "group_norm_v2_00_large_r", "identical": true, "reference": "original frozen baseline" }, { "case": "group_norm_v2_00_large_m", "identical": true, "reference": "original frozen baseline" }, { "case": "group_norm_v2_01_small", "identical": true, "reference": "original frozen baseline" }, { "case": "group_norm_v2_02_small", "identical": true, "reference": "original frozen baseline" }, { "case": "group_norm_v2_03_small", "identical": true, "reference": "original frozen baseline" }, { "case": "group_norm_v2_04_small", "identical": true, "reference": "original frozen baseline" }, { "case": "group_norm_v2_large_outer", "identical": true, "reference": "synchronized original control" } ] } }【性能标准】与修改前一致
按约定判定:基线 <20 μs 的小 shape 允许 1 μs 波动;大 shape 允许 <5% 波动。性能改善单列为改善,不算退化。计时来自 CANN 硬件任务记录,不使用主机墙钟。下表保留原始首轮数据;超阈值项目以明确列出的复测结论评估。
原始性能对照:57 项
新增大规模候选:75 项(含少量实际 <20 μs 的候选)
首轮超阈值复测:BatchNorm 大归约首轮 +6.91%。采用 修改前 → 修改后 → 修改后 → 修改前 顺序,每轮 100 次,两轮中位数合并结果如下,复测满足 <5% 阈值。
API 计时为一次调用内硬件核心任务时长之和,不含主机时间和任务间隔,不代表端到端时延。
组合 API:29 项字节及性能结果
GroupNorm 同步修复后边界对照:12 项
2026-10-13 空归约:14 项,每项 100 次,最大绝对波动 0.139 μs
验证边界与待办
历史联调已覆盖大小 shape;当前变基后的全量设备回归和最终远程依赖版本默认构建未完成。Ascend350 仅有配置/源码审查,未做硬件验证。此附件发布已有结果,不代表专项已完成最终交付。
排版检查(2026-10-27)
对本 PR 全部 60 个改动文件运行 pre-commit,修正 7 个文件的缩进、空行及文件末尾换行。已核对修正前后去除空白字符的内容完全一致,未改变计算或 workspace 分配逻辑。修正后 pre-commit 全部适用检查通过;这是本地检查结果,线上流水线结果以最新提交为准。
Host UT workspace 边界断言修正(2026-10-27)
AddRmsNorm 的性能模板边界用例中,SplitAR(key=3000)保留“系统空间+实际 partial 用户空间”的检查,其余 key 的 workspace 期望更新为 0,与当前 tiling 申报一致。本次只调整算子 UT 一行,不修改生产代码、公共 UT 或 CMake。
本地使用 CANN 9.2.0,通过当前仓库实际选择参数配置并构建 UT:先复现相同的断言失败,再修正该断言并重建对象、归档和最终可执行文件。失败边界用例修正后通过;本次选入的 Host UT 为 44/44 通过;全部 60 个 PR 文件 pre-commit 通过。当前 CANN 9.3.0 线上结果以新流水线为准。
AddLayerNormQuant 的用户地址传递已核对 asc-devkit 标准包装器:包装器先计算 usrWorkspace,再传给原始 kernel。该处沿用传入用户地址,Host 动态量化仍保留原申请策略。源码依据已回复对应检视线程。
主干同步与修改范围核对(2026-10-27)
已同步主干 a90fa6a3529c,当前仍为一次提交。唯一内容冲突位于 RmsNorm arch35 tiling:主干新增 SplitAR、Transpose、空归约模板,已在普通 RmsNorm 路径设置 workspace=0,并在 SplitAR 路径保留系统预留与 partial 用户空间申请。本 PR 沿用该主干实现,不重复加入入口清零,不覆盖新增模板或其用户空间申请。
逐文件核对原提交:其余 59 个文件的实质增删行保持不变;3 个文件的末尾换行修正已由主干包含。因此当前差异为 59 个文件,无新增修改路径。全部当前改动文件 pre-commit 通过,生产/公共测试 CMake 未新增改动。
AddRmsNorm 刚修正的 workspace UT 断言和 AddLayerNormQuant 用户地址传递实现均保留。GroupNormV2 的 Host、Kernel 及本算子 CMake 与同步前版本逐字节一致,当前隔离包验证不受此次变基影响。此处不将已有测试结果表述为全仓重新验证。