Diff Coverage

Diff: origin/master...HEAD, staged and unstaged changes

Source File Diff Coverage (%) Missing Lines
hyper_parallel/components/functional/dsa_sparse_attention_rescale.py 0.0% 26,47-50,66-67,70,99-102,122-125,198,251,275-277,303
hyper_parallel/components/functional/dsa_sparse_attention_rescale.py
22
23
24
25
26
27
28
29
30
from einops import rearrange
import omni_training_custom_ops  # noqa: F401  # pylint: disable=unused-import


def _sink_attention_forward(
    query: torch.Tensor,
    sink_key: torch.Tensor,
    sink_value: torch.Tensor,
    num_heads: int,
43
44
45
46
47
48
49
50
51
52
53
54

    Returns:
        Sink-attention output and softmax statistics.
    """
    sink_query = rearrange(query, "b s n d -> s b (n d)")
    sink_key_sbh = rearrange(sink_key, "b s n d -> s b (n d)")
    sink_value_sbh = rearrange(sink_value, "b s n d -> s b (n d)")
    sink_output, sink_softmax_max, sink_softmax_sum = torch_npu.npu_fusion_attention(
        sink_query,
        sink_key_sbh,
        sink_value_sbh,
        num_heads,
62
63
64
65
66
67
68
69
70
71
72
73
74
        sparse_mode=0,
        actual_seq_qlen=None,
        actual_seq_kvlen=None,
    )[:3]
    sink_output = rearrange(sink_output, "s b (n d) -> b s n d", n=num_heads)
    return sink_output, sink_softmax_max, sink_softmax_sum


def _sink_attention_backward(
    query: torch.Tensor,
    sink_key: torch.Tensor,
    sink_value: torch.Tensor,
    sink_grad_output: torch.Tensor,
 95
 96
 97
 98
 99
100
101
102
103
104
105
106

    Returns:
        Gradients of the sink query, key, and value.
    """
    sink_query = rearrange(query, "b s n d -> s b (n d)")
    sink_key_sbh = rearrange(sink_key, "b s n d -> s b (n d)")
    sink_value_sbh = rearrange(sink_value, "b s n d -> s b (n d)")
    sink_grad_query, sink_grad_key, sink_grad_value, *_ = torch_npu.npu_fusion_attention_grad(
        sink_query,
        sink_key_sbh,
        sink_value_sbh,
        sink_grad_output.to(sink_key.dtype),
118
119
120
121
122
123
124
125
126
127
128
129
        actual_seq_qlen=None,
        actual_seq_kvlen=None,
        sparse_mode=0,
    )
    sink_grad_query = rearrange(sink_grad_query, "s b (n d) -> b s n d", n=num_heads)
    sink_grad_key = rearrange(sink_grad_key, "s b (n d) -> b s n d", n=sink_key.size(2))
    sink_grad_value = rearrange(sink_grad_value, "s b (n d) -> b s n d", n=sink_value.size(2))
    return sink_grad_query, sink_grad_key, sink_grad_value


class _SparseAttentionRescale(torch.autograd.Function):
    """Autograd bridge for sparse attention with separate sink parameters."""
194
195
196
197
198
199
200
201
202
            output = F.pad(output, [0, query_rope.size(-1)])
        output = rearrange(output, "(b s) n d -> b s n d", b=batch_size, s=sequence_length)

        query = torch.cat([query_nope, query_rope], dim=-1)
        sink_output, sink_softmax_max, sink_softmax_sum = _sink_attention_forward(
            query, sink_key, sink_value, num_heads, scale, keep_prob
        )
        softmax_max_rescale = softmax_max.squeeze(0).view(batch_size, sequence_length, num_heads)
        softmax_sum_rescale = softmax_sum.squeeze(0).view(batch_size, sequence_length, num_heads)
247
248
249
250
251
252
253
254
255

        Returns:
            Gradients corresponding to the forward inputs.
        """
        del grad_softmax_max, grad_softmax_sum
        (
            query_nope,
            compressed_kv,
            query_rope,
271
272
273
274
275
276
277
278
279
280
281
            for tensor in (query_nope, compressed_kv, query_rope, key_rope)
        ]
        grad_output = rearrange(output_scale * grad_rescaled_output, "b s n d -> (b s) n d")
        rescaled_output_tnd = rearrange(rescaled_output, "b s n d -> (b s) n d")
        if query_rope.size(-1) > 0:
            grad_output = grad_output[:, :, :-query_rope.size(-1)]
            rescaled_output_tnd = rescaled_output_tnd[:, :, :-query_rope.size(-1)]

        grad_query_nope, grad_key, grad_value, grad_query_rope, grad_key_rope = (
            torch.ops.custom.npu_sparse_flash_attention_grad_enhance(
                query_nope_tnd,
299
300
301
302
303
304
305
306
307
            )
        )
        sink_grad_output = rearrange(sink_scale * grad_rescaled_output, "b s n d -> s b (n d)")
        query = torch.cat([query_nope, query_rope], dim=-1)
        sink_grad_query, sink_grad_key, sink_grad_value = _sink_attention_backward(
            query,
            sink_key,
            sink_value,
            sink_grad_output,