Files
vllm-omni/vllm_omni/diffusion/attention/layer.py
T
2025-12-22 17:48:39 +08:00

71 lines
2.5 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
# Copyright (c) Microsoft Corporation and Jiarui Fang
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team & Jiarui Fang
# Adapted from
# https://github.com/feifeibear/long-context-attention/blob/main/yunchang/attention/layer.py
import torch
import torch.nn as nn
from vllm_omni.diffusion.attention.backends.abstract import AttentionMetadata
from vllm_omni.diffusion.attention.parallel import build_parallel_attention_strategy
from vllm_omni.diffusion.attention.selector import get_attn_backend
class Attention(nn.Module):
def __init__(
self,
num_heads: int,
head_size: int,
causal: bool,
softmax_scale: float,
num_kv_heads: int | None = None,
prefix: str = "",
# ulysses attention
scatter_idx: int = 2,
gather_idx: int = 1,
use_sync: bool = False,
):
super().__init__()
self.attn_backend = get_attn_backend(-1)
self.attn_impl_cls = self.attn_backend.get_impl_cls()
self.attention = self.attn_impl_cls(
num_heads=num_heads,
head_size=head_size,
softmax_scale=softmax_scale,
causal=causal,
num_kv_heads=num_kv_heads,
)
self.softmax_scale = softmax_scale
self.scatter_idx = scatter_idx
self.gather_idx = gather_idx
self.use_sync = use_sync
# Parallel attention (communication / resharding) is a pluggable strategy.
# This keeps the attention kernel backend selection orthogonal.
self.parallel = build_parallel_attention_strategy(
scatter_idx=scatter_idx,
gather_idx=gather_idx,
use_sync=use_sync,
)
def forward(
self,
query: torch.Tensor,
key: torch.Tensor,
value: torch.Tensor,
attn_metadata: AttentionMetadata = None,
) -> torch.Tensor:
# Parallel strategy may reshard/communicate QKV before the attention kernel.
query, key, value, attn_metadata, ctx = self.parallel.pre_attention(query, key, value, attn_metadata)
# shape: (batch_size, seq_len, num_heads, head_size)
attn_output = self.attention.forward(query, key, value, attn_metadata)
if isinstance(attn_output, tuple):
attn_output = attn_output[0]
# Parallel strategy may need to reverse resharding after the kernel.
return self.parallel.post_attention(attn_output, ctx)