补充证据(同日,第三次独立印证)
在前两次通路(torch_npu torch.var_mean、aclnn 纯 C 直调)之外,又用按资料推导过出参 shape 的合法用例
跑了一遍支持面放行检查(250 条,dim 全部在 [-ndim, ndim-1] 内且不重复,出参 shape 全部按 keepdim 推导):
| dtype | 用例数 | PASS | REJECTED(161002) |
|---|---|---|---|
| fp32 | 84 | 84 | 0 |
| fp16 | 83 | 83 | 0 |
| bfloat16 | 83 | 0 | 83(100%) |
出参 shape 250/250 全部与推导一致,说明这批用例本身合法,不存在「参数构造错误导致被拒」的可能。
fp32 / fp16 是 100% 放行、bf16 是 100% 拒绝,二分得干干净净。
补充一条 plog 原文(CANN 自身打印,与源码 aclnn_var_mean.cpp L42-43 的常量完全对应):
AclNN_Parameter_Error(EZ1001): Tensor self not implemented for DT_BFLOAT16,
should be in dtype support list [DT_FLOAT,DT_FLOAT16,].
另外确认:同机同卡上 aclnnVar(单输出)的 bf16 通路正常,其 op_api/aclnn_var.cpp L43-51 用的是
soc 档位判据 GetDtypeSupportListV2(ASCEND910B_DTYPE_SUPPORT_LIST, ASCEND910_DTYPE_SUPPORT_LIST),
910B 档含 DT_BF16;而 aclnnVarMean 用的是 IsRegBase() 二分。两者判据不一致即为本问题的直接成因。


您好,感谢反馈!
问题分析
核对 cann/ops-math 固定版本 8c1f633e3679,可以确认入口类型校验与 A2 的资料支持范围存在不一致。aclnn_var_mean.cpp 中,只有 IsRegBase() 分支的类型列表包含 BF16,910B 对应的 DAV_2201 不在该分支内。CheckParams 因此在检查 self 的 dtype 时返回 ACLNN_ERR_PARAM_INVALID(161002),尚未进入 dim、输出 shape 检查及后续计算链。这与您正文及补充评论中的日志相符,合法参数下调整 dim、keepdim 或 correction 无法绕过这一类型限制。
同族 aclnnVar 使用 GetDtypeSupportListV2,其含 BF16 的列表覆盖 DAV_2201 及 RegBase 平台;两者的平台判据确实不同。接口资料 又明确支持 Atlas A2,并在输入及两个输出的数据类型中列出 BFLOAT16,现有入口限制与这一契约不一致。
还需区分两条计算路径:RegBase 分支使用 ReduceVar;910B 所在的非 RegBase 分支使用 ReduceMean、均值广播及 ReduceStdV2UpdateCorrection 组合。因此,ReduceVar 的 OpDef 和 arch35 tiling 声明支持 BF16,不能直接证明 910B 组合路径已经完成 BF16 验证。您提供的同机 Var、Mean 对照有助于缩小范围,但入口放行后的双输出计算仍需在目标环境核验。
处理方向
一个可行的方案是让 VarMean 的类型选择与 Var 使用相同的平台判据,为 DAV_2201 放行 BF16,同时保留旧平台的类型限制及现有 RegBase 支持范围。直接向所有非 RegBase 平台共用列表加入 BF16 会扩大旧平台支持面,需要避免。
该调整还需结合 910B 的实际组合路径核验两个输出的数值、keepdim=false 时的均值重算与广播、correction 边界及空张量处理,并检查原有 fp16/fp32 行为。当前已完成上述源码核查,目标设备上的运行验证尚未完成;我们会继续跟踪这一支持面差异。


[Bug-Report|缺陷反馈]: aclnnVarMean 对 bfloat16 一律返回 161002(资料/OpDef/tiling 三方声明支持,910B3 上同族 aclnnVar 的 bf16 正常)
一、环境
/usr/local/Ascend/ascend-toolkit)master,math/reduce_varmath/reduce_var/docs/aclnnVarMean.md(415 行)二、现象
aclnnVarMean在 bfloat16 输入下,第一段接口aclnnVarMeanGetWorkspaceSize一律返回 161002(ACLNN_ERR_PARAM_INVALID)。fp32 / fp16 同参数正常。plog 原文(CANN 自身打印,非推测):
三、最小复现
source /usr/local/Ascend/ascend-toolkit/set_env.sh # 通路 1:torch_npu python3 -c " import torch, torch_npu x = torch.arange(8, dtype=torch.float32).reshape(2,4) v,m = torch.var_mean(x.to(torch.bfloat16).npu(), dim=[1], correction=1, keepdim=True) print(v, m) " # → NPU function error: call aclnnVarMean failed, error code is 161002 # 通路 2:aclnn 纯 C 直调(不经过 torch 层) python3 -c " import sys; sys.path.insert(0,'<work-toolkit>/skills/ascend-op-determinism/scripts') " # 走 run_determinism.py --op aclnn:VarMean --backend npu # → AclnnOpError: aclnnVarMeanGetWorkspaceSize 返回错误码 161002两条互不经过对方代码的通路返回同一个码,排除 torch 插件层问题。
四、控制变量矩阵(唯一变量 = dtype)
同一份输入
x = arange(8).reshape(2,4)、同一dim=[1]、correction=1、keepdim=True:var与mean两个单输出接口在 bf16 下都正常,只有var_mean双输出接口被拒 → 不是 kernel 不支持 bf16,是aclnnVarMean的入参校验把它挡掉了。规模放大复测:402 条精度用例中 bf16 共 134 条,134/134 全部 161002;110 条确定性用例中 bf16 10 条,10/10 全部 161002。无一例外。
五、根因(代码锚点)
math/reduce_var/op_api/aclnn_var_mean.cppL41-56:// 算子支持的所有dtype static const std::initializer_list<op::DataType> DTYPE_SUPPORT_LIST = {op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16}; static const std::initializer_list<op::DataType> ARCH3510_DTYPE_SUPPORT_LIST = { op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_BF16}; static const std::initializer_list<DataType>& GetDtypeSupportList() { if (IsRegBase()) { return ARCH3510_DTYPE_SUPPORT_LIST; // 只有 RegBase(arch35/3510)才允许 BF16 } else { return DTYPE_SUPPORT_LIST; // 910B / A2 落到这里 → 无 BF16 } }同一算子族的单输出接口
math/reduce_var/op_api/aclnn_var.cppL43-51 用的是另一套判据:static const std::initializer_list<op::DataType> ASCEND910_DTYPE_SUPPORT_LIST = {DT_FLOAT, DT_FLOAT16}; static const std::initializer_list<op::DataType> ASCEND910B_DTYPE_SUPPORT_LIST = {DT_FLOAT, DT_FLOAT16, DT_BF16}; auto DTYPE_SUPPORT_LIST = GetDtypeSupportListV2(ASCEND910B_DTYPE_SUPPORT_LIST, ASCEND910_DTYPE_SUPPORT_LIST);即:
aclnnVar按 soc 档位(910 / 910B)选支持面,aclnnVarMean按 IsRegBase() 二分。910B3 不是 RegBase,于是被误落到不含 BF16 的分支。而算子本体与资料都声明支持 bf16:
op_host/reduce_var_def.cppL18:dataType = {DT_FLOAT16, DT_FLOAT, DT_BF16}op_host/arch35/reduce_var_tiling.cppL91:supDtypes = {DT_FLOAT16, DT_BF16, DT_FLOAT}docs/aclnnVarMean.mdL93:self 数据类型列写明FLOAT、FLOAT16、BFLOAT16;L172 只把 910 / 310p 排除 bf16(910B3 不在其中)三方声明支持,唯 aclnn 层 gate 不支持。
六、影响
aclnnVarMean完全无法处理 bf16,用户必须退化成torch.var+torch.mean两次调用(多一次 kernel 下发与一次全量读,且两者结果不再来自同一次遍历,长尾分布下 mean 与 var 的舍入基准可能不一致)。torch.var_mean在 NPU 上的唯一落地通路,等于 bf16 场景整体不可用。七、期望
GetDtypeSupportList()改为与aclnn_var.cpp一致的 soc 档位判定(GetDtypeSupportListV2(ASCEND910B_DTYPE_SUPPORT_LIST, ASCEND910_DTYPE_SUPPORT_LIST)),或在非 RegBase 分支的DTYPE_SUPPORT_LIST中补入DT_BF16,使 910B 系列的行为与aclnnVar/aclnnMean及资料声明一致。八、备注
本轮同时复核了该接口的其他契约面:错误码表 5 条子项(161001 ×1、161002 ×4)在 fp32/fp16 下全部与资料一致;110 条确定性用例 × 3 种开关腿(none/torch/acl)共 330 次判定,fp32/fp16 的 300 次全部 bit-exact 一致,与资料「默认确定性实现」声明相符。bf16 因本缺陷无法进入上述判定。