已关闭
[RFC]: A5 代际 Dropout 反向算子数值对齐 PyTorch/GPU(aclnnDropoutV3Grad 接入 native_dropout_backward) #419
yucaopanmu创建于 20 天前关闭于 12 天前
20 天前 关联了里程碑:TorchNPU-v26.2.0
20 天前 添加了label:rfc
20 天前 关联了pull request:[fix] A5 代际 Dropout 反向随机数算子数值对齐 PyTorch/GPU
18 天前 关联了pull request:[fix] A5 代际 Dropout 反向随机数算子数值对齐 PyTorch/GPU
18 天前 关联了pull request:[fix] A5 代际 Dropout 反向随机数算子数值对齐 PyTorch/GPU
18 天前 删除了关联的pull request:[fix] A5 代际 Dropout 反向随机数算子数值对齐 PyTorch/GPU
18 天前 删除了关联的pull request:[fix] A5 代际 Dropout 反向随机数算子数值对齐 PyTorch/GPU
12 天前 关闭了 issue
11 天前 添加了label:resolved
10 天前 修改了issue 的描述
10 天前 修改了issue 的描述
状态(Status): Reviewing
作者(Authors): @yucaopanmu
创建日期(Created): 2026-08-15
更新日期(Updated): 2026-08-26
相关 Issue/PR: #5737
1. 概述
1.1 简介
本提案将新 CANN 算子
aclnnDropoutV3Grad接入 op-plugin 中native_dropout_backward的 A5(Ascend950)路径,使 A5 上 dropout 反向的数值结果对齐 PyTorch/GPU(H20)。核心改动是:A5 上把 PyTorch 语义的缩放因子scale直接透传给新算子,内核以纯乘法链gradX = gradY * mask * scale完成计算,消除旧链路中"宿主侧由 scale 换算 p(1 - 1/scale)、算子内部再由 p 还原缩放因子(1/(1-p))"两次浮点换算引入的精度误差。A5 上使用不支持新算子aclnnDropoutV3Grad的 CANN 版本则回退到之前的路径,A2/A3 代际调用路径与行为保持不变,对外 API 与语义不变。1.2 动机
native_dropout_backward)在宿主编排层把scale(PyTorch 语义scale = 1/(1-p))换算为p = 1 - 1/scale后下发给aclnnDropoutDoMask,算子在内部再还原缩放因子。1 - 1/scale与1/(1-p)两次浮点换算均存在舍入误差(如 p=0.3 时1 - 1/1.428571...无法精确表示),导致反向结果与 GPU 存在 ulp 级偏差;预训练多轮累积后偏差被放大,无法通过客户精度验收。gradX = gradY * mask * scale,无中间换算。NPU 要对齐 GPU,必须消除链路中多余的浮点计算。1.3 目标
目标:
native_dropout_backward反向数值结果对齐 PyTorch/GPU(H20),通过 UT 测试与 ATK 泛化精度验证。aclnnDropoutV3Grad的 CANN 版本则回退到之前的路径。非目标(边界说明):
native_dropout的精度/随机数序列对齐不在本提案范围内(前向路径不变)。torch.ops.aten.native_dropout_backward接口不变)。2. 用例分析
scale > 1的 dropout 反向,mask 为前向aclnnDropoutGenMaskV2生成的 UINT8 packed 位掩码scale == 1(p=0,无丢弃)、scale == 0(p=1,全部丢弃)、空 mask(numel==0)0 < scale < 1RuntimeError,报错信息与旧路径一致aclnnDropoutV3Grad的 CANN 版本约束与限制:
aclnnDropoutGenMaskV2产出),与旧路径输入约定一致。scale合法域为 0 或[1, +inf),与 PyTorch dropout 语义一致。GetSocVersion() >= Ascend950且 CANN 支持新算子aclnnDropoutV3Grad时生效。3. 方案设计
3.1 总体方案
整体思路:在 A5 上把 PyTorch 语义的
scale原值直达新 CANN 算子aclnnDropoutV3Grad,内核执行单步乘法链,从根因上消除旧链路两次浮点换算的精度损失。核心处理流程(
op_plugin/ops/opapi/NativeDropoutKernelNpuOpApi.cpp的native_dropout_backward):设计要点:
scale原值透传,内核一次乘法完成缩放,与 PyTorch CUDA 反向实现的计算链路完全一致。p==0、p==1、空 mask 三类退化场景在宿主侧短路,减少无效算子下发,同时保证极端入参下语义与 GPU 一致(GPU 侧同样短路)。注意p = 1 - 1/scale在宿主侧仅用于分支判定,p==0/p==1的判定对舍入误差不敏感(scale==1时1-1/1精确为 0;scale→+inf时结果精确趋向 1)。check_aclnn_kernel_available判定,对旧版本的 CANN 回退到之前的路径。GetSocVersion()判定,A2/A3 完整保留aclnnDropoutDoMask路径。3.2 技术选型
aclnnDropoutV3Grad直传 scalegradX = gradY * mask * scaleaclnnDropoutDoMask1/(1-p)还原换算,误差仅转移未消除,无法达成"与 GPU 完全一致"aclnnDropoutDoMask语义3.3 功能与性能设计
功能设计:
aclnnDropoutV3Grad下发(约 +31 行)。grad_output、mask、scale,输出与grad_output同 shape/dtype 的 tensor。性能设计:
aclnnDropoutDoMask计算量等价,理论无性能回退。scale==1/scale==0/空 mask 场景由宿主侧短路,省去算子下发与 kernel 启动开销,性能略有收益。影响范围: 仅
native_dropout_backward一个接口、A5 一个平台;native_dropout前向与dropout_backward不受影响。3.4 安全隐私与DFX设计
TORCH_CHECK报错文本)与旧路径一致。3.5 编程与调用设计
3.5.1 编程模型基本设计
aclnnDropoutV3Grad)。3.5.2 接口定义与设计
3.5.2.1 aclnnDropoutV3Grad(新增 CANN 算子接口)
gradX = gradY * mask * scale,纯乘法链,对齐 GPU 精度。aclnnStatus aclnnDropoutV3Grad(const aclTensor* gradOutput, const aclTensor* mask, double scale, aclTensor* result)(以 CANN 发布接口文档为准)。aclnnDropoutGenMaskV2生成1/(1-p)),原值透传scale==1、scale==0等退化场景由宿主侧短路,不下发该接口;非法 scale 由宿主侧TORCH_CHECK抛出RuntimeError。torch.ops.aten.native_dropout_backward的调用方无感知。if (c10_npu::GetSocVersion() >= c10_npu::SocVersion::Ascend950 && check_aclnn_kernel_available("aclnnDropoutV3Grad")) { // ... 参数校验与退化场景短路 ... at::Tensor result = at_npu::native::OpPreparation::apply_tensor_without_format(grad_output); EXEC_NPU_CMD(aclnnDropoutV3Grad, grad_output, mask, scale, result); return result; }3.5.3 编程手册设计
本提案不新增对外 API,
torch.ops.aten.native_dropout_backward调用方式与语义不变,无需新增《编程手册》。建议在已有native_dropout_backward相关文档中补充说明:A5 平台反向计算采用aclnnDropoutV3Grad,数值对齐 GPU。4. 测试设计
4.1 单元测试(UT)
已在
test/test_base_ops/test_native_dropout_backward.py中添加用例:test_native_dropout_backward_fp32/fp16(存量,补充设备注解)test_native_dropout_backward_scale_zeroscale==0→ 全零短路分支test_native_dropout_backward_scale_onescale==1→ clone 短路分支test_native_dropout_backward_scale_gt_one_fp32test_native_dropout_backward_scale_gt_one_fp16test_native_dropout_backward_scale_gt_one_bf16test_native_dropout_backward_empty_masktest_neg_scale_rangeRuntimeError校验测试要点:
_packed_bit_mask),并在 CPU 侧展开为 bool 掩码(_expand_bit_mask)计算 golden,保证 golden 语义与 GPU 一致。assertRtolEqual(output_cpu.float().numpy(), output_npu.cpu().float().numpy(), 0.004),比对前两侧转 float32,避免 bf16 直接比对引入的比对误差。4.2 泛化精度验证(ATK)
4.3 集成/端到端测试
5. 缺点和风险
aclnnDropoutV3Grad依赖新版 CANN,老版本不提供实现成本:宿主侧约 +31 行代码、单测约 +100 行,改动较小且集中在 2 个文件。
6. 现有技术
native_dropout_backward在 GPU 上直接以gradX = gradY * mask * scale单步乘法链计算,无中间换算——本提案的精度对齐目标即与其计算链一致。aclnnDropoutDoMask(A2/A3 在用)与aclnnDropoutV3/aclnnDropoutV3Grad代际接口,本提案复用 CANN 既有演进成果,宿主侧仅做接入。7. 未解决问题
aclnnDropoutV3Grad支持的 dtype 范围是否需进一步扩展(如 int8 量化场景),待 CANN 侧确认。附录
torch/_refs/nn/functional/dropout.py与 ATennative_dropout_backwardCUDA kernelc10_npu::SocVersion::Ascend950aclnnDropoutGenMaskV2生成1/(1-p)欢迎加入社区,感谢您对社区的贡献 🎉!