-
Notifications
You must be signed in to change notification settings - Fork 47
feat(npu): add MindIE-SD compile fusion and MINDIE attention backend #259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v1
Are you sure you want to change the base?
Changes from all commits
d2ad4d8
e94848c
0b6dff2
49ade03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,62 @@ | ||||||||||||||||||||||||||||||||||
| import torch | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| from diffsynth_engine.layers.attention.backends.abstract import ( | ||||||||||||||||||||||||||||||||||
| AttentionBackend, | ||||||||||||||||||||||||||||||||||
| AttentionImpl, | ||||||||||||||||||||||||||||||||||
| AttentionMetadata, | ||||||||||||||||||||||||||||||||||
| AttentionType, | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| from diffsynth_engine.utils.platform import is_npu_available | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| class MindieAttentionBackend(AttentionBackend): | ||||||||||||||||||||||||||||||||||
| @staticmethod | ||||||||||||||||||||||||||||||||||
| def check_availability() -> None: | ||||||||||||||||||||||||||||||||||
| if not is_npu_available(): | ||||||||||||||||||||||||||||||||||
| raise RuntimeError("NPU is not available, cannot use MINDIE attention backend") | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+9
to
+16
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 确实应该判断mindie才对 |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @staticmethod | ||||||||||||||||||||||||||||||||||
| def get_type() -> str: | ||||||||||||||||||||||||||||||||||
| return str(AttentionType.MINDIE) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @staticmethod | ||||||||||||||||||||||||||||||||||
| def get_impl_cls() -> type["AttentionImpl"]: | ||||||||||||||||||||||||||||||||||
| return MindieAttentionImpl | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @staticmethod | ||||||||||||||||||||||||||||||||||
| def get_supported_head_sizes() -> list[int]: | ||||||||||||||||||||||||||||||||||
| return [] | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| class MindieAttentionImpl(AttentionImpl): | ||||||||||||||||||||||||||||||||||
| def __init__( | ||||||||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||||||||
| num_heads: int, | ||||||||||||||||||||||||||||||||||
| head_size: int, | ||||||||||||||||||||||||||||||||||
| softmax_scale: float | None = None, | ||||||||||||||||||||||||||||||||||
| causal: bool = False, | ||||||||||||||||||||||||||||||||||
| num_kv_heads: int | None = None, | ||||||||||||||||||||||||||||||||||
| **extra_impl_args, | ||||||||||||||||||||||||||||||||||
| ) -> None: | ||||||||||||||||||||||||||||||||||
| self.scale = softmax_scale or (head_size**-0.5) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| def forward( | ||||||||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||||||||
| query: torch.Tensor, | ||||||||||||||||||||||||||||||||||
| key: torch.Tensor, | ||||||||||||||||||||||||||||||||||
| value: torch.Tensor, | ||||||||||||||||||||||||||||||||||
| attn_mask: torch.Tensor | None = None, | ||||||||||||||||||||||||||||||||||
| attn_metadata: AttentionMetadata | None = None, | ||||||||||||||||||||||||||||||||||
| **kwargs, | ||||||||||||||||||||||||||||||||||
| ) -> torch.Tensor: | ||||||||||||||||||||||||||||||||||
| from mindiesd.layers.flash_attn.attention_forward import attention_forward | ||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. import统一放开头清晰一点 |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return attention_forward( | ||||||||||||||||||||||||||||||||||
| query=query, | ||||||||||||||||||||||||||||||||||
| key=key, | ||||||||||||||||||||||||||||||||||
| value=value, | ||||||||||||||||||||||||||||||||||
| attn_mask=attn_mask, | ||||||||||||||||||||||||||||||||||
| scale=self.scale, | ||||||||||||||||||||||||||||||||||
| fused=True, | ||||||||||||||||||||||||||||||||||
| head_first=False, | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| from diffsynth_engine.utils.platform import is_mindie_sd_available | ||
|
|
||
| from .compilation import apply_mindie_sd_compile | ||
|
|
||
| __all__ = [ | ||
| "apply_mindie_sd_compile", | ||
| "is_mindie_sd_available", | ||
| ] |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,19 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import torch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from diffsynth_engine.utils.platform import is_mindie_sd_available | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def apply_mindie_sd_compile(model: torch.nn.Module) -> torch.nn.Module: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Apply MindIE-SD torch.compile backend fusion patterns. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Enables RMSNorm, RoPE, AdaLayerNorm, and MulAdd op fusion for NPU execution. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FastGELU fusion is disabled (npu_fast_gelu was slower than native GELU in practice). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| On non-NPU devices or when mindiesd is unavailable, returns the model unchanged. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not is_mindie_sd_available(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return model | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from mindiesd.compilation import CompilationConfig, MindieSDBackend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CompilationConfig.fusion_patterns.enable_fast_gelu = False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return torch.compile(model, backend=MindieSDBackend()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+19
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forcing
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里整体torch.compile不会有graph break问题吗?一般实践中我们只compile repeated blocks |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |||||
| from diffsynth_engine.utils import logging | ||||||
| from diffsynth_engine.utils.constants import MODEL_INDEX_NAME | ||||||
| from diffsynth_engine.utils.import_utils import LazyImport | ||||||
| from diffsynth_engine.utils.platform import is_npu_available | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
|
|
||||||
| if TYPE_CHECKING: | ||||||
| from diffsynth_engine.layers.attention.backends.abstract import AttentionBackend | ||||||
|
|
@@ -37,6 +38,7 @@ | |||||
| "sage3": "diffsynth_engine.layers.attention.backends.sage_attn_3:SageAttention3Backend", | ||||||
| "sdpa": "diffsynth_engine.layers.attention.backends.sdpa:SDPABackend", | ||||||
| "sparge": "diffsynth_engine.layers.attention.backends.sparge_attn:SpargeAttentionBackend", | ||||||
| "mindie": "diffsynth_engine.layers.attention.backends.mindie_attn:MindieAttentionBackend", | ||||||
| } | ||||||
|
|
||||||
| PIPELINE_REGISTRY: dict[str, LazyImport] = {} | ||||||
|
|
@@ -118,7 +120,7 @@ def get_attn_backend(attn_type: str | None = None) -> type["AttentionBackend"]: | |||||
| _attention_backend_registry_initialized = True | ||||||
|
|
||||||
| if attn_type is None: | ||||||
| attn_type = "sdpa" | ||||||
| attn_type = "mindie" if is_npu_available() else "sdpa" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When
Suggested change
|
||||||
| if attn_type not in ATTENTION_BACKEND_REGISTRY: | ||||||
| available_backends = sorted(ATTENTION_BACKEND_REGISTRY) | ||||||
| raise ValueError(f"Attention backend {attn_type!r} not found. Available backends: {available_backends}") | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,27 @@ def _is_mps() -> bool: | |
| return torch.backends.mps.is_available() | ||
|
|
||
|
|
||
| def is_npu_available() -> bool: | ||
| try: | ||
| import torch_npu | ||
|
|
||
| return torch_npu.npu.is_available() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 建议改成类似FLASH_ATTN_3_AVAILABLE的环境变量而不是每次try import |
||
| except ImportError: | ||
| return False | ||
|
|
||
|
|
||
| def is_mindie_sd_available() -> bool: | ||
| try: | ||
| import mindiesd # noqa: F401 | ||
|
|
||
| return is_npu_available() | ||
| except ImportError: | ||
| return False | ||
|
|
||
|
|
||
| def get_device(local_rank: int) -> torch.device: | ||
| if is_npu_available(): | ||
| return torch.device("npu", local_rank) | ||
| if _is_cuda() or _is_rocm(): | ||
| return torch.device("cuda", local_rank) | ||
| if _is_mps(): | ||
|
|
@@ -23,6 +43,8 @@ def get_device(local_rank: int) -> torch.device: | |
|
|
||
|
|
||
| def get_device_type() -> str: | ||
| if is_npu_available(): | ||
| return "npu" | ||
| if _is_cuda() or _is_rocm(): | ||
| return "cuda" | ||
| if _is_mps(): | ||
|
|
@@ -32,6 +54,8 @@ def get_device_type() -> str: | |
|
|
||
|
|
||
| def get_torch_distributed_backend() -> str: | ||
| if is_npu_available(): | ||
| return "hccl" | ||
| if _is_cuda() or _is_rocm(): | ||
| return "nccl" | ||
| if _is_mps(): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
直接默认是"auto"是不是更合适点🤔