Closed
[Bug-Report|缺陷反馈]: aclnnMoeGatingTopKBackward 错误码表把 out 的 dtype 约束写成「与 xNorm 一致」,实测按「与 gradY 一致」校验(out=fp32 返回 161002) #6712
liuhanwen8Add on  15 days agoClosed at  9 days ago
liuhanwen8
liuhanwen8
15 days ago Create

现象

aclnnMoeGatingTopKBackward 的资料内部对 out 的 dtype 约束给了两套互相冲突的说法:

位置 原文 含义
参数表「使用说明」 out「数据类型与gradY需要保持一致」 out 必须等于 gradY 的 dtype
错误码表 161002 子项 「out的数据类型与xNorm不一致」 out 必须等于 xNorm 的 dtype

xNorm 只支持 FLOAT32,gradY 支持 FLOAT16/BFLOAT16/FLOAT32,两者无法同时满足。
实测实现按参数表口径校验(out 必须与 gradY 一致):out=fp32 + gradY=fp16 + xNorm=fp32
(即「错误码表口径」下应当合法的组合)第一段直接返回 161002。

期望

错误码表 161002 的第 2 条子项应改为「out的数据类型与gradY不一致」,与参数表和实现保持一致;
否则调用方按错误码表"对齐 xNorm"构造 fp32 输出时会被 161002 拒绝。

环境

  • 硬件:Atlas A3 系列(Ascend 910)
  • CANN:9.2.0
  • 仓库:ops-transformer,master 5d75099700459eaae3291ae331fcc288269d2825(2026-10-25 fetch)
  • 接口:aclnnMoeGatingTopKBackward(moe/moe_gating_top_k_backward/docs/aclnnMoeGatingTopKBackward.md)

复现步骤

  1. 用下方编译命令编译单文件程序 repro_out_dtype.cpp(只依赖 CANN 头文件与 libascendcl/libopapi)。
  2. 运行 ./repro_out_dtype。
  3. 观察两行输出:out=fp16 == gradY 返回 0;out=fp32 == xNorm 返回 161002。

复现脚本

#include <cstdio>
#include <vector>
#include "acl/acl.h"
#include "aclnnop/aclnn_moe_gating_top_k_backward.h"

static aclTensor* Mk(void** dev, const std::vector<int64_t>& s, aclDataType dt)
{
    int64_t n = 1; for (auto d : s) n *= d;
    size_t bytes = (size_t)n * aclDataTypeSize(dt);
    aclrtMalloc(dev, bytes, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMemset(*dev, bytes, 0, bytes);
    return aclCreateTensor(s.data(), s.size(), dt, nullptr, 0, ACL_FORMAT_ND,
                           s.data(), s.size(), *dev);
}

static int Run(aclDataType outDt, const char* name)
{
    const int64_t M = 4, N = 8, K = 2;
    void *dx = nullptr, *dg = nullptr, *di = nullptr, *do2 = nullptr;
    aclTensor* xNorm = Mk(&dx, {M, N}, ACL_FLOAT);
    aclTensor* gradY = Mk(&dg, {M, K}, ACL_FLOAT16);
    aclTensor* idx = Mk(&di, {M, K}, ACL_INT32);
    aclTensor* out = Mk(&do2, {M, N}, outDt);
    uint64_t ws = 0; aclOpExecutor* ex = nullptr;
    aclnnStatus ret = aclnnMoeGatingTopKBackwardGetWorkspaceSize(
        xNorm, gradY, idx, 0, 1, 2.5, 1e-20, out, &ws, &ex);
    printf("%-42s phase1 ret=%d\n", name, (int)ret);
    if (ret != ACL_SUCCESS) printf("    errmsg: %.160s\n", aclGetRecentErrMsg());
    aclDestroyTensor(xNorm); aclDestroyTensor(gradY); aclDestroyTensor(idx);
    aclDestroyTensor(out);
    for (void* p : {dx, dg, di, do2}) if (p) aclrtFree(p);
    return (int)ret;
}

int main()
{
    aclInit(nullptr);
    aclrtSetDevice(0);
    Run(ACL_FLOAT16, "out=fp16 == gradY(fp16)  [param table]");
    Run(ACL_FLOAT,   "out=fp32 == xNorm(fp32) [error table]");
    aclFinalize();
    return 0;
}

编译命令:

g++ -std=c++17 repro_out_dtype.cpp -o repro_out_dtype \
  -I$ASCEND_HOME_PATH/include -I$ASCEND_HOME_PATH/include/aclnnop \
  -L$ASCEND_HOME_PATH/lib64 -lascendcl -lopapi -lnnopbase

实测输出:

out=fp16 == gradY(fp16)  [param table]     phase1 ret=0
out=fp32 == xNorm(fp32) [error table]      phase1 ret=161002
    errmsg: Failed to execute operator MoeGatingTopKBackward_0.
    details of parameter are xNorm(DT_FLOAT, ND), gradY(DT_FLOAT16, ND),
    expertIdx(DT_INT32, ND), out(DT_FLOAT, ND).
    Supported dtype list: ... gradY(DT_FLOAT16, ND), out(DT_FLOAT16, ND)

影响

按资料错误码表实现调用方的框架(例如按 xNorm 的 dtype 分配输出)会在第一段拿到 161002,
且错误信息只报「dtype 与原型不一致」,无法定位到「out 应对齐 gradY」。
半精梯度场景(gradY=fp16、xNorm=fp32)是本接口的主要用法,命中概率高。

建议

把错误码表 161002 的第 2 条子项改为「out的数据类型与gradY不一致」;
或在参数表补一句「out 的 dtype 必须与 gradY 相同,与 xNorm 无关」。

likedislike
liuhanwen8liuhanwen8
15 days ago Added label: documentation
周云飞
周云飞Collaborators
15 days ago Comments:

感谢提供详细的对照说明和复现结果。

您报告的两处描述确实存在冲突:当 gradY=FLOAT16、xNorm=FLOAT32 时,out 无法同时与两者的数据类型保持一致。您提供的 CANN 9.2.0 实测结果显示,out=FLOAT16 时 aclnnMoeGatingTopKBackwardGetWorkspaceSize 返回 0,而 out=FLOAT32 时返回 161002;日志列出的支持组合也要求该场景下 out 为 FLOAT16。这支持参数表中“out 的数据类型与 gradY 保持一致”的说明,而不是错误码表中的“与 xNorm 一致”。当前调用可按参数表分配输出:gradY 为 FLOAT16 时,out 也使用 FLOAT16,xNorm 保持 FLOAT32。

针对您指出的文档冲突,可行的调整是将错误码 161002 的对应子项改为“out 的数据类型与 gradY 不一致”,并在参数说明中明确“out 的数据类型须与 gradY 相同,不要求与 xNorm 相同”。这属于文档说明的修正方向,不应为了符合错误码表的现有措辞而改变接口行为。

目前这些判断依据您提供的文档摘录和实测日志;该结果反映的是第一阶段的类型校验,不代表已验证第二阶段执行或其他数据类型组合。我们会继续确认该文档项与接口类型约束的一致性。

likedislike
liuhanwen8liuhanwen8
15 days ago Change title to "[Bug-Report|缺陷反馈]: aclnnMoeGatingTopKBackward 错误码表把 out 的 dtype 约束写成「与 xNorm 一致」,实测按「与 gradY 一致」校验(out=fp32 返回 161002)", originally titled "[Bug-Report|缺陷反馈]: [Documentation|文档反馈]: aclnnMoeGatingTopKBackward 错误码表把 out 的 dtype 约束写成「与 xNorm 一致」,实测按「与 gradY 一致」校验(out=fp32+gradY=fp16 返回 161002)".
YanWenkai
14 days ago Comments:

/assign @wkyan

likedislike
CANN-robotCANN-robotCollaborators
14 days ago Assign wkyan as responsible person
CANN-robotCANN-robotCollaborators
9 days ago Close issue
CANN-robotCANN-robotCollaborators
9 days ago Added label: resolved