Closed
[Bug-Report|缺陷反馈]: aclnnVarMean 对 bfloat16 一律返回 161002(资料/OpDef/tiling 三方声明支持,910B3 上同族 aclnnVar 的 bf16 正常) #4172
liuhanwen8Add on  16 days agoClosed at  10 days ago
liuhanwen8
liuhanwen8
16 days ago Create

[Bug-Report|缺陷反馈]: aclnnVarMean 对 bfloat16 一律返回 161002(资料/OpDef/tiling 三方声明支持,910B3 上同族 aclnnVar 的 bf16 正常)

一、环境

项 值
硬件 Ascend 910B3(Atlas A2 训练系列),8 卡
CANN 9.2.0(/usr/local/Ascend/ascend-toolkit)
框架 torch 2.12.0+cpu / torch_npu 2.12.0.post3
算子仓 cann/ops-math master,math/reduce_var
资料 math/reduce_var/docs/aclnnVarMean.md(415 行)

二、现象

aclnnVarMean 在 bfloat16 输入下,第一段接口 aclnnVarMeanGetWorkspaceSize 一律返回 161002(ACLNN_ERR_PARAM_INVALID)。fp32 / fp16 同参数正常。

plog 原文(CANN 自身打印,非推测):

AclNN_Parameter_Error(EZ1001): Tensor self not implemented for DT_BFLOAT16,
  should be in dtype support list [DT_FLOAT,DT_FLOAT16,].

三、最小复现

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:

dtype torch.var_mean torch.var torch.mean
float32 OK OK OK
float16 OK OK OK
bfloat16 FAIL 161002 OK OK

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.cpp L41-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.cpp L43-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.cpp L18:dataType = {DT_FLOAT16, DT_FLOAT, DT_BF16}
  • op_host/arch35/reduce_var_tiling.cpp L91:supDtypes = {DT_FLOAT16, DT_BF16, DT_FLOAT}
  • docs/aclnnVarMean.md L93:self 数据类型列写明 FLOAT、FLOAT16、BFLOAT16;L172 只把 910 / 310p 排除 bf16(910B3 不在其中)

三方声明支持,唯 aclnn 层 gate 不支持。

六、影响

  • A2 / 910B 系列上 aclnnVarMean 完全无法处理 bf16,用户必须退化成 torch.var + torch.mean 两次调用(多一次 kernel 下发与一次全量读,且两者结果不再来自同一次遍历,长尾分布下 mean 与 var 的舍入基准可能不一致)。
  • 该接口是 PyTorch torch.var_mean 在 NPU 上的唯一落地通路,等于 bf16 场景整体不可用。
  • 属于 FP-B06-3「平台分支不对称」:同一 soc 上同族接口一个放行一个拒绝。

七、期望

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 因本缺陷无法进入上述判定。

likedislike
liuhanwen8
liuhanwen8
16 days ago Comments:

补充证据(同日,第三次独立印证)

在前两次通路(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() 二分。两者判据不一致即为本问题的直接成因。

likedislike
陈思
陈思Collaborators
16 days ago Comments:

您好,感谢反馈!

问题分析

核对 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 行为。当前已完成上述源码核查,目标设备上的运行验证尚未完成;我们会继续跟踪这一支持面差异。

likedislike
陈思陈思Collaborators
16 days ago Assign chen_0715 as responsible person
陈思陈思Collaborators
16 days ago Added label: pending-confirmation
CchenyifengCollaborators
15 days ago Assign gcw_SUaZx3UQ as responsible person
CchenyifengCollaborators
15 days ago Removed responsible person chen_0715
Zzhangqijia1Collaborators
11 days ago Associated pull request
CANN-robotCANN-robotCollaborators
10 days ago Close issue
CANN-robotCANN-robotCollaborators
10 days ago Added label: resolved