mindspore.ops.incre_flash_attention

查看源文件
mindspore.ops.incre_flash_attention(query, key, value, attn_mask=None, actual_seq_lengths=None, pse_shift=None, dequant_scale1=None, quant_scale1=None, dequant_scale2=None, quant_scale2=None, quant_offset2=None, antiquant_scale=None, antiquant_offset=None, block_table=None, num_heads=1, input_layout='BSH', scale_value=1.0, num_key_value_heads=0, block_size=0, inner_precise=1, kv_padding_size=None)[源代码]

增量推理场景接口。

  • b:batch维

  • N:注意力头数

  • kvN: key / value 头数

  • S:序列长度

  • D:头维度

  • H:隐藏层大小

  • kvH: key / value 的隐藏层大小

其中 \(H=N\times D\), \(kvH=kvN\times D\)

self-attention(自注意力)利用输入样本自身的关系构建了一种注意力模型。其原理是假设有一个长度为 \(n\) 的输入样本序列 \(x\)\(x\) 的每个元素都是一个 \(d\) 维向量, 可以将每个 \(d\) 维向量看作一个token embedding,将这样一条序列经过3个权重矩阵变换得到3个维度为 \(n\times d\) 的矩阵。

self-attention的计算公式一般定义如下,

\[Attention(Q,K,V)=Softmax(\frac{QK^{T} }{\sqrt{d} } )V\]

其中 \(Q\)\(K^{T}\) 的乘积代表输入 \(x\) 的注意力,为避免该值变得过大,通常除以 \(d\) 的平方根进行缩放,并对每行进行softmax归一化,与 \(V\) 相乘后得到一个 \(n\times d\) 的矩阵。

说明

  • 如果没有输入参数且没有默认值,需要传入 None

  • 参数 keyvalue 对应的Tensor的shape需要完全一致。

  • 参数 query\(N\) 等于 num_heads ,而参数 keyvalue\(N\) 等于 num_key_value_headsnum_heads 必须是 num_key_value_heads 的倍数。

  • 量化

    • querykeyvalue 的数据类型为float16,且输出为int8时,需要传入 quant_scale2quant_offset2 可选。

    • antiquant_scale 存在时, keyvalue 需要以int8传入, antiquant_offset 可选。

    • antiquant_scaleantiquant_offset 的数据类型需要与 query 一致。

  • pse_shift

    • pse_shift 的数据类型需与 query 一致,并且仅支持D轴对齐,即D轴可以被16整除。

  • Page attention:

    • 开启page attention的必要条件是 block_table 存在,并且 keyvalue 根据 block_table 中的索引在内存中连续排列。 支持的 keyvalue 数据类型为float16/bfloat16/int8。

    • 在page attention开启场景下,当 keyvalue 的输入类型为float16/bfloat16时,需要16对齐; 当输入类型为int8时,需要32对齐,推荐使用128对齐。

    • block_table 当前支持的max_block_num_per_seq最大为16k,超过16k会导致拦截和报错; 如果 \(S\) 过大导致 max_block_num_per_seq 超过16k,可通过增大 block_size 来解决。

    • 在page attention场景中, keyvalue 的Tensor的shape各维乘积不能超过int32的表示范围。

    • 在进行per-channel后量化时,不能同时启用page attention。

  • kv_padding_size

    • KV缓存传输起点的计算公式为 \(S-kv\_padding\_size-actual\_seq\_lengths\), KV缓存传输终点的计算公式为 \(S-kv\_padding\_size\) 。当起点或终点小于0时,返回的数据结果为全0。

    • kv_padding_size 小于0时,会设置为0。

    • kv_padding_size 需要与 actual_seq_lengths 参数一同启用,否则被认为是KV右填充场景。

    • 需要与 attn_mask 参数一同启用,并确保 attn_mask 的意义正确,即能正确隐藏无效数据,否则会引入精度问题。

    • kv_padding_size 不支持page attention场景。

参数:
  • query (Tensor) - 公式中的输入Q,数据类型float16或bfloat16。shape为 \((B, 1, H)\) / \((B, N, 1, D)\)

  • key (Union[tuple, list]) - 公式中的输入K,数据类型为float16、bfloat16或int8。shape为 \((B, S, kvH)\) / \((B, kvN, S, D)\)

  • value (Union[tuple, list]) - 公式中的输入V,数据类型为float16、bfloat16或int8。shape为 \((B, S, kvH)\) / \((B, kvN, S, D)\)

  • attn_mask (Tensor,可选) - 注意力掩码Tensor,数据类型为bool、int8或uint8。shape为 \((B, S)\) / \((B, 1, S)\) / \((B, 1, 1, S)\) 。默认值: None

  • actual_seq_lengths (Union[Tensor, tuple[int], list[int]],可选) - 描述每个输入的实际序列长度,数据类型为int32或int64。shape为 \((B, )\) 。默认值: None

  • pse_shift (Tensor,可选) - 位置编码Tensor,数据类型为float16或bfloat16。输入Tensorshape为 \((1, N, 1, S)\) / \((B, N, 1, S)\) 。默认值: None

  • dequant_scale1 (Tensor,可选) - 量化参数,数据类型为uint64或float32。当前未使能。默认值: None

  • quant_scale1 (Tensor,可选) - 量化参数,数据类型为float32。当前未使能。默认值: None

  • dequant_scale2 (Tensor,可选) - 量化参数,数据类型为uint64或float32。当前未使能。默认值: None

  • quant_scale2 (Tensor,可选) - 后量化参数,数据类型为float32。shape为 \((1,)\) 。默认值: None

  • quant_offset2 (Tensor,可选) - 后量化参数,数据类型为float32。shape为 \((1,)\) 。默认值: None

  • antiquant_scale (Tensor,可选) - 伪量化参数,数据类型为float16或bfloat16。当 input_layout'BNSD' 时,shape为 \((2, kvN, 1, D)\);当 input_layout'BSH' 时,shape为 \((2, kvH)\) 。默认值: None

  • antiquant_offset (Tensor,可选) - 伪量化参数,数据类型为float16或bfloat16。当 input_layout'BNSD' 时,shape为 \((2, kvN, 1, D)\);当 input_layout'BSH' 时,shape为 \((2, kvH)\) 。默认值: None

  • block_table (Tensor,可选) - Tensor,数据类型为int32。shape为 \((B, max\_block\_num\_per\_seq)\),其中 \(max\_block\_num\_per\_seq = ceil(\frac{max(actual\_seq\_length)}{block\_size} )\) 。默认值: None

  • num_heads (int,可选) - 头的数量。默认值: 1

  • input_layout (str,可选) - 输入qkv的数据布局,支持 'BSH''BNSD' 。默认值: 'BSH'

  • scale_value (double,可选) - 表示缩放系数的值,用作计算中的标量。默认值: 1.0

  • num_key_value_heads (int,可选) - 用于GQA算法的 key / value 头数。如果 keyvalue`具有相同的头数,则值为0,使用 `num_heads 。默认值: 0

  • block_size (int,可选) - 页注意力中存储在每个KV块中的最大标记数。默认值: 0

  • inner_precise (int,可选) - 一个 {0, 1} 中的整数,指定计算模式。 0 为高精度模式(适用于float16 数据类型), 1 为高性能模式。默认值为 1

  • kv_padding_size (Tensor,可选) - Tensor,数据类型为int64。值的范围为 \(0\le kv\_padding\_size \le S-max(actual\_seq\_length)\) 。shape为 \(()\)\((1,)\) 。默认值: None

返回:

attention_out (Tensor),注意力输出Tensor,shape为 \((B, 1, H)\) / \((B, N, 1, D)\)

异常:
  • TypeError - query 的数据类型不是float16或bfloat16。

  • TypeError - keyvalue 的数据类型不同。

  • TypeError - attn_mask 的数据类型不是bool、int8或uint8。

  • TypeError - pse_shift 的数据类型不是bfloat16或float16。

  • TypeError - scale_value 不是double类型。

  • TypeError - input_layout 不是字符串。

  • TypeError - num_key_value_headsnum_heads 不是整数。

  • TypeError - inner_precise 不是整数。

  • TypeError - quant_scale1 不是float32类型的Tensor。

  • TypeError - quant_scale2 不是float32类型的Tensor。

  • TypeError - quant_offset2 不是float32类型的Tensor。

  • ValueError - actual_seq_lengths 的长度不是1或者B。

  • ValueError - input_layout 是字符串但不是BSH或BNSD。

  • ValueError - num_heads 不能被Q_H整除。

  • ValueError - num_heads 不能被 num_key_value_heads 整除。

  • RuntimeError - num_heads 小于等于 0。

  • RuntimeError - attn_mask 的shape不合法。

支持平台:

Ascend

样例:

>>> from mindspore import ops
>>> from mindspore.common import Tensor
>>> from mindspore.common import dtype as mstype
>>> import numpy as np
>>> B, N, S, D, kvN = 1, 4, 10, 128, 1
>>> query = Tensor(np.random.randn(B, 1, N * D), mstype.float16)
>>> key = [Tensor(np.random.randn(B, S, kvN * D), mstype.float16)]
>>> value = [Tensor(np.random.randn(B, S, kvN * D), mstype.float16)]
>>> ifa_ms = ops.functional.incre_flash_attention
>>> attn_out = ifa_ms(query, key, value, num_heads=N, num_key_value_heads=kvN)
>>> attn_out
Tensor(shape=[1, 1, 512], dtype=Float16, value=
[[[ 1.6104e+00,  7.3438e-01,  1.0684e+00 ... -8.7891e-01,  1.7695e+00,  1.0264e+00]]])