Files
2026-07-13 12:40:42 +08:00

127 lines
4.9 KiB
Python

# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from typing import TYPE_CHECKING
import paddle.nn.functional as F
if TYPE_CHECKING:
from paddle import Tensor
def scaled_dot_product_attention(
query: Tensor,
key: Tensor,
value: Tensor,
attn_mask: Tensor | None = None,
dropout_p: float = 0.0,
is_causal: bool = False,
scale: float | None = None,
enable_gqa: bool = False,
) -> Tensor:
r"""
The equation is:
.. math::
result=softmax(\frac{ Q * K^T }{\sqrt{d}}) * V
where : ``Q``, ``K``, and ``V`` represent the three input parameters of the attention module.
The dimensions of the three parameters are the same.
``d`` represents the size of the last dimension of the three parameters.
Warning:
This API only verifies inputs with dtype float16 and bfloat16, other dtypes may fall back to math
implementation, which is less optimized.
Note:
This API differs from :ref:`api_paddle_nn_functional_scaled_dot_product_attention` in that:
The QKV layout of this API is [batch_size, num_heads, seq_len, head_dim] or [num_heads, seq_len, head_dim].
Args:
query(Tensor): The query tensor in the Attention module.
4-D tensor with shape:
[batch_size, num_heads, seq_len, head_dim].
3-D tensor with shape:
[num_heads, seq_len, head_dim].
The dtype can be float16 or bfloat16.
key(Tensor): The key tensor in the Attention module.
4-D tensor with shape:
[batch_size, num_heads, seq_len, head_dim].
3-D tensor with shape:
[num_heads, seq_len, head_dim].
The dtype can be float16 or bfloat16.
value(Tensor): The value tensor in the Attention module.
4-D tensor with shape:
[batch_size, num_heads, seq_len, head_dim].
3-D tensor with shape:
[num_heads, seq_len, head_dim].
The dtype can be float16 or bfloat16.
attn_mask(Tensor, optional): The attention mask tensor. The shape should be broadcastable to
[batch_size, num_heads, seq_len_key, seq_len_query]. The dtype can be bool
or same type of query. The bool mask indicates the positions should take part
in attention. The non-bool mask will be added to attention score.
is_causal(bool, optional): Whether enable causal mode. If True, the attention masking is a lower
triangular matrix when the mask is a square matrix. The attention masking has the
form of the upper left causal bias when the mask is a non-square matrix.
An error is thrown if both attn_mask and is_causal are set.
scale(float, optional): The scaling factor used in the calculation of attention weights.
If None, scale = 1 / sqrt(head_dim).
enable_gqa(bool, optional): Whether enable GQA mode. Default False.
Returns:
out(Tensor): The attention tensor.
4-D tensor with shape: [batch_size, num_heads, seq_len, head_dim].
3-D tensor with shape: [num_heads, seq_len, head_dim].
The dtype can be float16 or bfloat16.
Examples:
.. code-block:: pycon
>>> # doctest: +SKIP('bfloat need V100 compile')
>>> import paddle
>>> q = paddle.rand((1, 2, 128, 16), dtype=paddle.bfloat16)
>>> output = paddle.compat.nn.functional.scaled_dot_product_attention(q, q, q, None, 0.9, False)
>>> print(output)
>>> # doctest: -SKIP
"""
if is_causal and attn_mask is not None:
raise RuntimeError(
"Explicit attn_mask should not be set when is_causal=True"
)
query, key, value = (
query.swapaxes(-3, -2),
key.swapaxes(-3, -2),
value.swapaxes(-3, -2),
)
out = F.scaled_dot_product_attention(
query,
key,
value,
attn_mask,
dropout_p,
is_causal,
True, # training
None, # backend
scale,
enable_gqa,
None, # name
)
return out.swapaxes(-3, -2)