开发者
下载
[object Object][object Object][object Object]undefined
[object Object]
  • 接口功能​:aclnnBSASelectBlockMask是BSA(BlockSparseAttention)的前置算子,负责根据Query和Key的内容动态生成blockSparseMask,使BSA的调用链从"手动提供掩码"变为"根据Q/K内容自适应选择稀疏模式"。

  • 计算公式​:

    设blockShape = [blockShapeX, blockShapeY],Sq是query最大序列长度,Skv是key最大序列长度, 则压缩后块数:

    Xblocks=Sq/blockShapeX,Yblocks=Skv/blockShapeYXblocks = \lceil Sq / blockShapeX \rceil,\quad Yblocks = \lceil Skv / blockShapeY \rceil

    Step1:均值池化压缩 (Mean Pooling Compression)

    当actualBlockLenQuery / actualBlockLenKey为null时(完整压缩):

    q_compressed[b,n,x,d]=1blockShapeXi=0blockShapeX1query[b,n,xblockShapeX+i,d]q\_compressed[b, n, x, d] = \frac{1}{blockShapeX} \sum_{i=0}^{blockShapeX-1} query[b, n, x \cdot blockShapeX + i, d] k_compressed[b,n,y,d]=1blockShapeYj=0blockShapeY1key[b,n,yblockShapeY+j,d]k\_compressed[b, n, y, d] = \frac{1}{blockShapeY} \sum_{j=0}^{blockShapeY-1} key[b, n, y \cdot blockShapeY + j, d]

    当actualBlockLenQuery / actualBlockLenKey非null时(部分压缩),仅对每个block内前actualBlockLen个token取均值:

    q_compressed[b,n,x,d]=1actualBlockLenQ[b,x]i=0actualBlockLenQ[b,x]1query[b,n,xblockShapeX+i,d]q\_compressed[b, n, x, d] = \frac{1}{actualBlockLenQ[b,x]} \sum_{i=0}^{actualBlockLenQ[b,x]-1} query[b, n, x \cdot blockShapeX + i, d] k_compressed[b,n,y,d]=1actualBlockLenK[b,y]j=0actualBlockLenK[b,y]1key[b,n,yblockShapeY+j,d]k\_compressed[b, n, y, d] = \frac{1}{actualBlockLenK[b,y]} \sum_{j=0}^{actualBlockLenK[b,y]-1} key[b, n, y \cdot blockShapeY + j, d]

    Step2a:QK Matmul

    score[b,n,x,y]=scaled=0D1q_compressed[b,n,x,d]k_compressed[b,n,y,d]score[b, n, x, y] = scale \cdot \sum_{d=0}^{D-1} q\_compressed[b, n, x, d] \cdot k\_compressed[b, n, y, d]

    Step2b:Softmax

    attn_score[b,n,x,y]=softmax(score[b,n,x,:])=exp(score[b,n,x,y]mfinal)lfinalattn\_score[b, n, x, y] = softmax(score[b, n, x, :]) = \frac{\exp(score[b, n, x, y] - m_{final})}{l_{final}}

    Step3:TopK选择生成索引

    topk_value=round(sparsity×Xblocks×Yblocks)topk\_value = \text{round}(sparsity \times Xblocks \times Yblocks) indices=TopK(attn_score[b,n,x,y],  topK_value)\mathcal{indices}= \text{TopK}\left(attn\_score[b, n, x, y],\; topK\_value\right)

    其中indices为attn_score[b, n, x, y] 中topk_value个最大值对应的索引集合。

    Step4:生成BlockSparseMask

    blockSparseMaskOut[b,n,x,y]={1(b,n,x,y)indices0(b,n,x,y)indicesblockSparseMaskOut[b, n, x, y] = \begin{cases} 1 & (b, n, x, y) \in \mathcal{indices} \\ 0 & (b, n, x, y) \notin \mathcal{indices} \end{cases}
  • 数据排布格式:

    BSASelectBlockMask输入query、key的数据排布格式支持从多种维度排布解读,可通过qInputLayout和kvInputLayout传入。为了方便理解后续支持的具体排布格式(如BNSD、TND等),此处先对排布格式中各缩写字母所代表的维度含义进行统一说明:

    • B:表示输入样本批量大小(Batch)
    • T:B和S合轴紧密排列的长度(Total tokens)
    • S:表示输入样本序列长度(Seq-Length)
    • H:表示隐藏层的大小(Head-Size)
    • N:表示多头数(Head-Num)
    • D:表示隐藏层最小的单元尺寸,需满足D = H / N(Head-Dim)
  • 当前支持的布局:

    • qInputLayout: "TND" "BNSD"
    • kvInputLayout: "TND" "BNSD"
[object Object]

每个算子分为,必须先调用"aclnnBSASelectBlockMaskGetWorkspaceSize"接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用"aclnnBSASelectBlockMask"接口执行计算。

[object Object]
[object Object]
[object Object]
  • 参数说明:

    [object Object]
  • 返回值

    aclnnStatus:返回状态码,具体参见

    第一段接口完成入参校验,出现以下场景时报错:

    [object Object]
[object Object]
  • 参数说明:

    [object Object]
  • 返回值:

    aclnnStatus:返回状态码,具体参见

[object Object]
  • 该接口若与PyTorch配合使用时,需要保证CANN相关包与PyTorch相关包的版本匹配。
  • actualSeqLengths在qInputLayout为 "TND" 时必选;actualSeqLengthsKV在kvInputLayout为 "TND" 时必选。
  • 根据算子支持的输入Layout,query张量Shape中对应的head维度大小记为N1,key张量Shape中对应的head维度大小记为N2。必须满足N1 = N2(仅支持MHA)。
  • headDim = 128。
  • blockShapeX和blockShapeY必须为64的倍数。
  • query和key压缩后,query和key对应的Xblocks和Yblocks需满足Xblocks - Yblocks > 1。
  • query和key的数据类型必须一致,仅支持FLOAT16和BFLOAT16。
  • blockSparseMaskOut数据类型为INT8(二值:0或1)。
  • postBlockShape当前不支持,必须传入nullptr。
  • actualBlockLenQuery / actualBlockLenKey若非null,每个元素取值范围 [0, blockShapeX] / [0, blockShapeY];为null时完整压缩。
  • 不涉及确定性计算。
[object Object]

示例代码如下,仅供参考,具体编译和执行过程请参考

[object Object]