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

76 lines
3.1 KiB
Python

# Copyright (c) 2023 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
from paddle import _C_ops
from paddle.framework import in_dynamic_or_pir_mode
if TYPE_CHECKING:
from paddle import Tensor
def fused_partial_rope(
x: Tensor,
cos: Tensor,
sin: Tensor,
) -> Tensor:
r"""
Applies partial rotary position embedding on the pe_head_dim portion of input.
Args:
x (Tensor): The input tensor. The data type is bfloat16. The shape of x must be [batch_size, seq_len, num_heads, head_dim].
cos (Tensor): The input tensor. The data type is bfloat16. The shape of cos must be [1, seq_len, 1, pe_head_dim] and pe_head_dim must be a multiple of 2 and mustn't exceed head_dim.
sin (Tensor): The input tensor. The data type is bfloat16. The shape of sin must be [1, seq_len, 1, pe_head_dim] and pe_head_dim must be a multiple of 2 and mustn't exceed head_dim.
Returns:
out: Tensor representing the fused rotary position embedding, has same shape and data type as `x` .
Examples:
.. code-block:: pycon
>>> # doctest: +REQUIRES(env:GPU)
>>> import paddle
>>> from paddle.incubate.nn.functional import fused_partial_rope
>>> paddle.set_device('gpu')
>>> paddle.seed(2025)
>>> # x: [batch_size, seq_len, num_heads, head_dim]
>>> x = paddle.randn([2, 2, 2, 4], dtype='bfloat16')
>>> # sin, cos: [1, seq_len, 1, pe_head_dim]
>>> cos = paddle.randn([1, 2, 1, 2], dtype='bfloat16')
>>> sin = paddle.randn([1, 2, 1, 2], dtype='bfloat16')
>>> # out: [batch_size, seq_len, num_heads, head_dim]
>>> out = fused_partial_rope(x, cos, sin)
>>> print(out)
Tensor(shape=[2, 2, 2, 4], dtype=bfloat16, place=Place(gpu:0), stop_gradient=True,
[[[[-0.17968750, 0.28125000, -0.34765625, -0.92187500],
[-0.83593750, 2. , -0.13476562, -0.67187500]],
[[ 0.38281250, -0.63281250, 0.25000000, -1.03125000],
[-1.92187500, 2.12500000, 1.92968750, -4.21875000]]],
[[[-0.90625000, -1.62500000, -0.22167969, -0.68359375],
[-0.76562500, 0.23828125, 0.36523438, 0.53515625]],
[[ 0.92578125, -0.85156250, -0.75000000, 1.50000000],
[ 0.41992188, -1.13281250, 0.73437500, -2.18750000]]]])
"""
if in_dynamic_or_pir_mode():
return _C_ops.fused_partial_rope(x, cos, sin)