Merge blocked
变更摘要
本 PR 为 norm_multiply_dropout 算子迁移系列的第 5 个 PR(P5),聚焦前向算子的测试与示例补齐:新增基于 pytest 的前向用例,覆盖非法参数校验、dropout_ratio/eps 合法与非法边界、dtype 与 shape 泛化组合,以及 dropout_ratio > 0 的前向冒烟验证;新增 aclnn 两段式接口调用示例与 torch 接口示例,便于 run_examples.sh --ops norm_multiply_dropout 自动发现执行;同时在 docs/zh/ops_rec_api.md 索引中补充该算子前反向说明与目录结构。本 PR 不含算子实现与构建接入改动,构建接入统一由 P6 完成。
主要改动
- 前向
pytest用例体系: 新增test_norm_multiply_dropout_forward.py,实现 CPU 公式杆、NPU 融合算子、NPU 小算子三方“双标杆”比对(compute_mare/compute_mere/compute_rmse及compare_data_with_double_pole),并对output/mean/var三个输出分别校验。 dtype白名单与平台适配: 以SUPPORT_DTYPES定义支持类型,通过_is_ascend_950()在 Ascend950 平台剔除float32,其余平台补充float32;torch_compiled在 Python 低于 3.12 时才走torch.compile。- 参数校验与边界用例: 通过
INVALID_PARAMS参数化覆盖不支持的dim0/dim1、非法dropout_ratio、非法eps、float64及weight/bias维度不一致场景,均预期抛RuntimeError;另补充非 2 维输入、维度不匹配、dim1非 512/1024、eps与dropout_ratio越界等独立用例,并验证dropout_ratio取0.0/1.0边界时可正常执行(1.0时输出恒为 0)。 mask语义与dropout行为校验: 用例中确认dropout_ratio > 0时第 4 输出mask为uint8位图且元素数为batch * col / 8,并断言 dropout 仅影响output而不影响mean/var;test_norm_multiply_dropout_graph以图模式fullgraph=True调用高层接口。aclnn与torch调用示例: 新增test_aclnn_norm_multiply_dropout_forward.cpp,演示aclnnNormMultiplyDropoutGetWorkspaceSize+aclnnNormMultiplyDropout两段式调用,x/u/weight/bias/output用float16、mean/var用float32,mask元素数按(batch*col+127)/128*128/8计算并在dropout_ratio <= 1e-10时退化为{1}占位;新增test_torch_norm_multiply_dropout_forward.py示例,分别演示高层接口ops_rec.ascendc.activation.norm_multiply_dropout与底层torch.ops.ops_rec.norm_multiply_dropout_forward的用法差异。- 测试标记与发现配置: 新增
test/pytest/pytest.ini声明ci与graph标记;主要用例均标注@pytest.mark.ci,满足 CI 流水线识别要求。
说明:
docs/zh/ops_rec_api.md的索引文档改动未在任务中提供 patch,仅依据 PR 描述说明其补充了norm_multiply_dropout前反向算子说明与目录结构。


代码审查
审查结论
发现清单(7 条)
P1(1 条)
test/pytest/test_norm_multiply_dropout_forward.py:175-179— golden 的mean/var直接取分段求和结果,未除以归一化维度;既与同文件 236-237 行小算子标杆(真实 mean/var)自相矛盾,又让compare_data_with_double_pole的比值断言恒成立,导致 output/mean/var 三条比对都无法发现 kernel 数值错误。
P2(1 条)
test/pytest/test_norm_multiply_dropout_forward.py:352-359— 泛化用例 dim0 最大 1e6、col 1024、且 fp32 输入会升到 float64 做 golden,单 case 峰值主机内存十余 GB、设备侧数 GB,典型环境会 OOM 或超时。
P3(5 条)
test_norm_multiply_dropout_forward.py:379-388— 15 个新增用例(含全部非法参数校验、dropout_ratio 边界)缺@pytest.mark.ci,CI 按标记选择时不会执行。test_norm_multiply_dropout_forward.py:143-145—two_level_sum_with_grouped小维度分支缺keepdim=True,与分段分支形状不一致,dim1<64 时 golden 广播错位/报错。test_norm_multiply_dropout_forward.py:53-56—torch_compiled在 Python≥3.12 静默返回未编译模型,标了graph的用例退化为 eager,图模式回归无法发现。examples/aclnn/test_aclnn_..._forward.cpp:113-128— 错误分支裸return,不释放已申请的 device 内存/stream、不aclFinalize,与成功路径的完整释放不一致。examples/aclnn/test_aclnn_..._forward.cpp:52-53—CreateAclTensor的hostData应改为 const 引用(可选改进)。
逐文件复核
examples/aclnn/test_aclnn_norm_multiply_dropout_forward.cpp— 已复核(2 条 P3:错误路径资源泄漏、const 引用);mask 对齐公式、strides 推导、字节数计算与 shape/host 数据一致,未发现越界或窄化问题。examples/torch/test_torch_norm_multiply_dropout_forward.py— 已复核,no issues(两个接口返回值解包与参数个数正确)。test/pytest/pytest.ini— 已复核,no issues(ci/graph标记注册与用例使用一致)。test/pytest/test_norm_multiply_dropout_forward.py— 已复核(1 P1 + 1 P2 + 3 P3)。
总体风险判断
整体为示例 + 用例 + ini 的新增,对生产代码无直接影响,合入风险可控;但测试侧存在一处高优先级缺陷——golden 未做归一化,使这套“双标杆”用例实际上不具备判别力,会给出虚假的正确性保证,建议与本 PR 一并修正后再合入。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 1 |
| 🟡 建议 | 1 |
⛔ 需要修改


Thanks for your pull-request.
The full list of commands accepted by me can be found at here.
You can get sig-info at here.
You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
PR Approval Progress
⚠️ This PR does not yet meet the following requirements:lgtm (requires ≥ 2 person(s) per module)、approve (requires ≥ 1 person(s) per module)
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| repo-Ascend/ops-rec | ❌ (0/2)(You can also ask: zhoucy998, Z_Ling, 文一晴, huhaoliang26, imhandsome1) | ❌ (0/1)(You can also ask: 李雄, 黄诗磊, imhandsome1, FngSeven, tqy1998) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
huiyangpeng, thanks for your pull request. All authors of the commits have signed the CLA. 👍


ascend docs pipeline is running...


❌ 文档门禁未通过!
| 检查项 | 检查结果 | 详情 |
|---|---|---|
| markdownlint | ✅ 已通过 | 查看详情 |
| link-validity-check | ❌ 未通过 | 查看详情 |
| resource-existence-check | ✅ 已通过 | 查看详情 |
| tag-closed-check | ✅ 已通过 | 查看详情 |
💡 本次检查出 2 项错误,详情内容如下:
| 序号 | 错误详情 |
|---|---|
| 1 | [文件路径]:docs/zh/ops_rec_api.md [检查类型]:link-validity-check [错误位置]:第 44 行 [错误信息]:本地路径链接无法访问 [错误内容]: ../../ascendc/activation/norm_multiply_dropout/norm_multiply_dropout_forward/docs/torch_norm_multipl... |
| 2 | [文件路径]:docs/zh/ops_rec_api.md [检查类型]:link-validity-check [错误位置]:第 45 行 [错误信息]:本地路径链接无法访问 [错误内容]: ../../ascendc/activation/norm_multiply_dropout/norm_multiply_dropout_backward/docs/torch_norm_multip... |


🟡 Medium Priority
变更行(test_norm_multiply_dropout_forward.py:352-355):dim0 参数包含 927750、DIM0_MAX(1e6),并交叉 col ∈ [512, 1024]、dtype ∈ SUPPORT_DTYPES(非 950 平台含 float32)。
影响链与失败模式:
- 结果:典型 CI/开发机(主机内存 32~64 GB、单卡 32 GB HBM)会 MemoryError 或触发 OOM killer;即便不 OOM,42 个参数组合在大规模 float64 计算下也极易超时。该用例又未打
@pytest.mark.ci,问题只会在开发者本地全量跑 pytest 时暴露,表现为“莫名 OOM/超时”而非明确断言失败。
建议:把 dim0 ≥ 262144 的极大组合单独拆分为少量用例(固定 col=512),或在 fixture 中依据设备/主机可用内存 skip,避免 1e6×1024 在 float64 golden 下产生十余 GB 峰值内存导致 OOM/超时。


🟠 High Priority
变更行(test_norm_multiply_dropout_forward.py:175-176):
求和计算
mean = two_level_sum_with_grouped(x)
var = two_level_sum_with_grouped((x - mean).pow(2))
two_level_sum_with_grouped(135-163 行)沿最后一维只做分段求和,没有任何除以 n 的归一化,但调用侧把结果当作 mean/var 使用:178-179 行 std = sqrt(var + EPS)、x_hat = (x - mean) / std。
影响链:
- 数学语义错误:真实 layer-norm 需要
mean = sum/n、var = sum((x-mean)^2)/n;当前 golden 的 mean 量级是真实均值的 512/1024 倍(x~U(-1,1) 时 sum 量级约 ±13,均值量级约 ±0.04),std 也不是标准差而是平方偏差和,因此y_golden与算子真实结果完全不同。 - 同文件 236-237 行的「小算子标杆」用的是
x.float().mean(dim=1)/.var(dim=1, unbiased=False)(真实均值/方差),与 golden 相互矛盾;243-244 行compare_data_with_double_pole(msg, mean_fused.cpu(), mean_npu.cpu(), mean_golden.reshape(-1))把 sum 当作 golden 去和真实 mean 比较,同一断言里两个参考量本身相差约 dim1 倍,二者必有一个错——按名字与本文件用法可确认错的是 golden。 - 失败模式:
compare_data_with_double_pole只比较mare_fused / mare_npu(以及 mere/rmse 的比值)是否 ≤ 阈值。由于 golden 偏差远大于算子误差,mare_fused ≈ mare_npu ≈ 1,比值恒 ≈1 必然 ≤ 5,断言恒通过;即 mean/var/output 三条比对都无法发现 kernel 的真实数值错误(例如 kernel 直接输出 0 也照样通过),用例给出虚假的正确性保证。
建议:把两次分段求和的结果除以归一化维长度(x.shape[-1],即本算子的 dim1),使 golden 的 mean/var 与 236-237 行的小算子标杆(mean/var(dim=1))语义一致;否则 mean/var/y 三条双标杆断言比值恒约等于 1,永远无法发现 kernel 数值错误。


已有相同的PR在排队列表中,不再重复排队


ascend docs pipeline is running...


❌ 文档门禁未通过!
| 检查项 | 检查结果 | 详情 |
|---|---|---|
| markdownlint | ✅ 已通过 | 查看详情 |
| link-validity-check | ❌ 未通过 | 查看详情 |
| resource-existence-check | ✅ 已通过 | 查看详情 |
| tag-closed-check | ✅ 已通过 | 查看详情 |
💡 本次检查出 2 项错误,详情内容如下:
| 序号 | 错误详情 |
|---|---|
| 1 | [文件路径]:docs/zh/ops_rec_api.md [检查类型]:link-validity-check [错误位置]:第 44 行 [错误信息]:本地路径链接无法访问 [错误内容]: ../../ascendc/activation/norm_multiply_dropout/norm_multiply_dropout_forward/docs/torch_norm_multipl... |
| 2 | [文件路径]:docs/zh/ops_rec_api.md [检查类型]:link-validity-check [错误位置]:第 45 行 [错误信息]:本地路径链接无法访问 [错误内容]: ../../ascendc/activation/norm_multiply_dropout/norm_multiply_dropout_backward/docs/torch_norm_multip... |


| 阶段 | 任务名 | 状态 | 详情 |
|---|---|---|---|
| 编译构建 | PR-build-SAST-check | ✅ COMPLETED | >>> |
| Build-2.7.1_arm | ✅ COMPLETED | >>> | |
| Build-2.10.0_arm | ✅ COMPLETED | >>> | |
| Build-2.7.1_X86 | ✅ COMPLETED | >>> | |
| Build-2.10.0_X86 | ✅ COMPLETED | >>> | |
| 恶意代码检查 | Antipoison | ✅ COMPLETED | >>> |
| 编码安全与规范检查 | pre-commit | ✅ COMPLETED | >>> |
| clang-tidy | 🟨 CANCELED | >>> | |
| 开源片段检查 | SCA | ✅ COMPLETED | >>> |
| 开发者测试 | presmoke | ✅ COMPLETED | >>> |
| 流水线 | PR-pipeline_ops-rec | 🟨 CANCELED | >>> |
- compile : 运行流水线
- retry : 重试流水线所有失败子任务
- retry <任务名> : 仅重试指定失败子任务
- stop : 停止流水线


ascend docs pipeline is running...


✅ 跳过 docs ci 检查,没有需要检查的文档文件


| 阶段 | 任务名 | 状态 | 详情 |
|---|---|---|---|
| 编译构建 | PR-build-SAST-check | ✅ COMPLETED | >>> |
| Build-2.7.1_arm | ✅ COMPLETED | >>> | |
| Build-2.10.0_arm | ✅ COMPLETED | >>> | |
| Build-2.7.1_X86 | ✅ COMPLETED | >>> | |
| Build-2.10.0_X86 | ✅ COMPLETED | >>> | |
| 恶意代码检查 | Antipoison | ✅ COMPLETED | >>> |
| 编码安全与规范检查 | pre-commit | ✅ COMPLETED | >>> |
| clang-tidy | ✅ COMPLETED | >>> | |
| 开源片段检查 | SCA | ✅ COMPLETED | >>> |
| 开发者测试 | presmoke | ✅ COMPLETED | >>> |
| 流水线 | PR-pipeline_ops-rec | ✅ COMPLETED | >>> |
- compile : 运行流水线
- retry : 重试流水线所有失败子任务
- retry <任务名> : 仅重试指定失败子任务
- stop : 停止流水线


[P2] torch_compiled 在 Python≥3.12 静默退化为 eager,图模式用例假通过(模式 1.12,ops-rec #74 同型复发)
问题
L53-56 def torch_compiled(model, **kwargs): if sys.version_info < (3, 12, 0): return torch.compile(...); return model——py≥3.12 时返回未编译原函数。test_norm_multiply_dropout_graph(L324 @pytest.mark.graph)经该 helper 调用,编译被静默跳过后用例仍 PASS,dynamo/Meta 注册(#233 的 NormMultiplyDropoutForwardInterMeta)零验证。
影响
本系列新增的 Meta/inductor 支持(前向 InterMeta、plugin schema)在 py≥3.12 环境(新 torch 标配)完全没有回归保护;后续改动破坏入图能力不会有任何用例失败。#235 反向 test_norm_multiply_dropout_backward.py L59-62 同款 helper 同病(两 PR 合并计 4 处图用例)。
建议
py≥3.12 分支改为 pytest.skip("torch.compile gate for py>=3.12") 显式跳过(让"未验证"可见),或直接启用编译;并在编译路径加"确实入图"证据断言,如 torch._dynamo.utils.counters["frames"]["ok"] > 0。


[P2] 13 处 pytest.raises(RuntimeError) 全部无 match=,负例校验归属不可证(模式 1.9)
问题
本文件 13 处负例(INVALID_PARAMS 10 组 + dim1/eps/ratio/dtype/mask 单点用例)均为裸 with pytest.raises(RuntimeError):,全文 match= 零命中。op_host TilingFunc 有 eps/dropout_ratio/dim0/dim1/dtype/shape 一致性/ mask numel 等多条独立校验。
影响
任何 RuntimeError(更早触发的另一条校验、aclnn 加载失败、甚至 #234 aclnn 用例数据问题)都会让负例"通过"。实例:INVALID_PARAMS 里 (1, 512, 1e-5, -0.2, ...) 意图验证 dropout_ratio 下界,若 dim0=1 先触发别的校验分支,测试同样绿——新增的 mask numel 校验(#230 L176-182)在该文件中无任何带 match 的针对性负例。
建议
逐条补 match=re.escape("...")(OPS_LOG_E 消息片段即可,如 match="dropout_ratio must in range"、match="mask numel must be"),并为 mask numel 校验补正/负各一条用例(numels/8 与 numels/8±1、ratio=0 时 numel=1 占位)。


合入来源
问题/功能描述
norm_multiply_dropout 算子迁移(系列 PR 4/6):新增前向算子测试用例与 aclnn/torch 调用示例。
修改方案描述
@pytest.mark.ci标记、set_device 默认 0):非法参数校验、dropout_ratio/eps 合法与非法边界、泛化 shape/dtype(dtype 白名单按平台自动适配)、dropout>0 前向+backward 冒烟run_examples.sh --ops norm_multiply_dropout自动发现执行是否涉及UT/ST
开发自检