Closed
[Bug-Report|缺陷反馈]: aclnnMlaPreprocess cacheMode=0 按资料传空指针返回 161001,三个 tensor 实际被要求必填 #6582
liuhanwen8Add on  23 days agoClosed at  6 days ago
liuhanwen8
liuhanwen8
23 days ago Create

问题描述

接口资料 attention/mla_preprocess/docs/aclnnMlaPreprocess.md 对 cacheMode=0 明确写了三个张量不需要传:

  • kvCacheRope:「可选参数,支持传入空指针……cacheMode为0:不传入。」
  • qRopeOut:「cacheMode为0:不输出。」
  • krCacheOut:「cacheMode为0:不输出。」

但 A2 实测:cacheMode=0 时按资料把这三个参数传 nullptr,第一段接口直接返回 161001(ACLNN_ERR_PARAM_NULLPTR),
该模式按资料无法调用。把三者换成任意占位 tensor 后可以跑通,但三个缓冲区全程没有被写入(预填的哨兵值原样保留),
说明它们在该模式下确实不参与计算,只是被生成接口当成了必填项。

同时 cacheMode=1 下 ctkvScale / qNopeScale 传 nullptr 也返回 161001,而资料写的是「仅在 cacheMode 为 2 时传入」。

cacheMode 传 nullptr 的参数 资料口径 实测(A2)
0 kvCacheRope / qRopeOut / krCacheOut(三者同时) 不传入 / 不输出 第一段 161001
0 三者中任意一个为空、其余占位 同上 第一段 161001
0 三者全部传占位 tensor — 返回 0,但三者内容未被写入
1 ctkvScale / qNopeScale 仅 cacheMode=2 才传 第一段 161001

环境信息

  • 产品:Atlas A2 训练系列产品(910B2),单卡
  • CANN:9.2.0(npu-smi 26.1.1)
  • 调用方式:aclnn 两段式 C 直调(aclnnMlaPreprocessGetWorkspaceSize + aclnnMlaPreprocess)
  • 基线参数:tokenNum=8、hiddenSize=7168、headNum=32、blockNum=192、blockSize=128、wdqDim=1536、qRopeDim=kRopeDim=64

重现步骤

  1. 以 attention/mla_preprocess/examples/test_aclnn_mla_preprocess.cpp 为基线,把 cacheMode 改为 0。
  2. 输出形状按资料改成:qOut=[8,32,576]、kvCacheOut=[192,128,1,576](kvCache 与 kvCacheOut 传同一块内存)。
  3. 按资料把三个张量传空:
    ret = aclnnMlaPreprocessGetWorkspaceSize(
        input, gamma0, beta0, quantScale0, quantOffset0, wdqkv, deScale0, bias0,
        gamma1, beta1, quantScale1, quantOffset1, wuq, deScale1, bias1, gamma2,
        cos, sin, wuk,                       /* RoPE 正常传入 */
        kvCache,                             /* 与 kvCacheOut 同一块 GM */
        nullptr,                             /* kvCacheRope:资料要求 cacheMode=0 不传 */
        slotMapping, ctkvScale, qNopeScale,
        1536, 64, 64, 1e-5, 2, 2,
        true, true, true, /*cacheMode=*/0, 0, true, 1,
        qOut, kvCache,                       /* kvCacheOut = kvCache */
        nullptr,                             /* qRopeOut:资料要求 cacheMode=0 不输出 */
        nullptr,                             /* krCacheOut:资料要求 cacheMode=0 不输出 */
        &workspaceSize, &executor);
    // 实测返回 161001
  1. 把上面三个 nullptr 换成任意占位 aclTensor(形状 [192,128,1,64] / [8,32,64] / [192,128,1,64],内容随意),
    同样的调用返回 0;此时三个缓冲区内容与调用前逐字节一致(未被写入)。

预期结果

按资料写法在 cacheMode=0 下能成功执行,只写 qOut 与 kvCacheOut。

实际结果

第一段返回 161001;只有把三个模式内不参与计算的 tensor 都传成占位张量才能运行。

备注

  • 根因位置:attention/mla_preprocess/op_host/mla_preprocess_def.cpp 把 24 个输入与 4 个输出全部声明为
    ParamType(REQUIRED),其中包含 kv_cache_rope、q_rope_out、kr_cache_out、ctkv_scale、q_nope_scale;
    生成的两段式接口据此对空指针统一拦截,与资料给出的「可选 / 不输出 / 仅某模式传」语义冲突。
  • 修复方向(二选一):
    1. 把 kv_cache_rope、q_rope_out、kr_cache_out 以及 ctkv_scale、q_nope_scale 按资料改为 ParamType(OPTIONAL),
      由 tiling 按 cache_mode 决定是否使用;
    2. 若不打算支持可空,则修正资料,删除「不传入 / 不输出」的表述,并在资料中说明需传占位张量及其形状。
  • 与 #5792(MlaPreprocessV2 cacheMode=1 输出形状推导)不是同一问题:本条是 cacheMode=0 的参数可空性与资料不一致,不涉及形状推导。
likedislike
liuhanwen8liuhanwen8
23 days ago Added label: bug-report
周云飞
周云飞Collaborators
23 days ago Comments:

感谢提供详细的复现步骤和逐项对照,尤其是单独置空与占位张量的测试结果。

问题分析

您报告的两组现象都指向参数可空性与资料说明不一致:一组是 cacheMode=0 下的 kvCacheRope、qRopeOut、krCacheOut,另一组是 cacheMode=1 下的 ctkvScale、qNopeScale。按您引用的资料,这些参数在对应模式下不需要提供,但在 A2、CANN 9.2.0 环境中,传入 nullptr 会在 aclnnMlaPreprocessGetWorkspaceSize 阶段返回 161001,阻止后续执行。

您观察到占位张量未被写入,这支持“该测试条件下未使用这些输出缓冲区”的判断,但还不能据此保证任意形状、类型的占位张量都安全可用。关于 ParamType(REQUIRED) 导致生成接口拦截空指针的判断,目前还需结合相关参数声明和内部接口校验确认,不能仅凭返回码确定具体拦截位置。本条关注的是参数可空性,与您提到的 #5792 输出形状推导问题应分开分析。

处理方向

如果以资料描述的按模式可空行为为准,一个可行方向是调整相关参数声明,并同步检查接口校验、形状推导和 tiling 对空参数的处理:不使用这些张量的模式应允许为空,实际依赖它们的模式仍需检查非空及形状、类型。仅把声明改成 OPTIONAL,还不足以保证后续流程能正确处理空参数。

如果接口确实要求始终传入张量,则需要明确区分“不参与计算”和“允许传空指针”,并在资料中说明占位张量的类型、形状和使用限制。您提供的环境与步骤已足够作为继续定位的起点,我们会继续确认这两组参数的可空条件及其与资料的差异。

likedislike
liuhanwen8
liuhanwen8
23 days ago Comments:

同根因在 aclnnMlaPreprocessV2 上同样成立,补充实测证据(A2 / CANN 9.2.0)。

  • 代码侧:attention/mla_preprocess_v2/op_host/mla_preprocess_v2_def.cpp 中 ParamType(OPTIONAL) 出现 0 次,
    ParamType(REQUIRED) 出现 29 次(含 kv_cache_rope、ctkv_scale、q_nope_scale、q_rope_out、kr_cache_out),与 V1 同构。
  • 行为侧(两段式直调,其余参数取资料示例合法值):
    • cacheMode=0 + kvCacheRope/qRopeOut/krCacheOut 全传 nullptr → 第一段返回 161001;
    • 三者全传占位张量 → 两段均 0,但三者内容与调用前逐字节一致(未被写入);
    • cacheMode=1 + ctkvScale/qNopeScale 传 nullptr → 第一段 161001。
  • V2 新增的 qDownOutFlag/qDownOut 行为正常:flag=true 时 qDownOut 被写入(12288 个元素全部非哨兵),
    flag=false 时保持调用前内容,不受本条影响。
likedislike
游震Collaborators
23 days ago Comments:

/assign @chaotang233

likedislike
CANN-robotCANN-robotCollaborators
23 days ago Assign chaotang233 as responsible person
唐唐超Collaborators
23 days ago Assign yolic as responsible person
唐唐超Collaborators
23 days ago Removed responsible person chaotang233
liyuanqiang
9 days ago Comments:

/assign

likedislike
CANN-robotCANN-robotCollaborators
9 days ago Assign liyuanqiang as responsible person
Lliyuanqiang
9 days ago Associated pull request
CANN-robotCANN-robotCollaborators
6 days ago Close issue
CANN-robotCANN-robotCollaborators
6 days ago changed custom state from 进行中 to 已完成
CANN-robotCANN-robotCollaborators
6 days ago Added label: resolved
周云飞
周云飞Collaborators
5 days ago Comments:

已通过 PR #15457 修正 MlaPreprocess 和 MlaPreprocessV2 的参数文档及接口注释,未修改算子执行逻辑。

  • cacheMode=0 时,kvCacheRope、qRopeOut 和 krCacheOut 均不可传空指针,需传入占位张量;其中 kvCacheRope 不读取,两个输出不写入。
  • ctkvScale 和 qNopeScale 也为必填参数,仅在 cacheMode=2 时参与计算,其他模式需传入形状为 [1] 的占位张量。

关联 PR:PR #15457

likedislike