Spaces:
Sleeping
Sleeping
SDPA fallback for flash_attn_func in the action module
Browse files- __pycache__/app.cpython-311.pyc +0 -0
- wan/modules/action_module.py +13 -4
- wan/modules/attention.py +43 -0
__pycache__/app.cpython-311.pyc
ADDED
|
Binary file (30.2 kB). View file
|
|
|
wan/modules/action_module.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
| 1 |
from typing import Any, List, Tuple, Optional, Union, Dict
|
| 2 |
from einops import rearrange
|
| 3 |
-
from flash_attn import flash_attn_func
|
| 4 |
import torch
|
| 5 |
import torch.nn as nn
|
| 6 |
from .posemb_layers import apply_rotary_emb, get_nd_rotary_pos_embed
|
|
@@ -9,11 +8,21 @@ from torch.nn.attention.flex_attention import flex_attention
|
|
| 9 |
|
| 10 |
try:
|
| 11 |
import flash_attn_interface
|
| 12 |
-
FLASH_ATTN_3_AVAILABLE =
|
| 13 |
-
|
| 14 |
-
|
|
|
|
| 15 |
FLASH_ATTN_3_AVAILABLE = False
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
DISABLE_COMPILE = False # get os env
|
| 19 |
flex_attention = torch.compile(
|
|
|
|
| 1 |
from typing import Any, List, Tuple, Optional, Union, Dict
|
| 2 |
from einops import rearrange
|
|
|
|
| 3 |
import torch
|
| 4 |
import torch.nn as nn
|
| 5 |
from .posemb_layers import apply_rotary_emb, get_nd_rotary_pos_embed
|
|
|
|
| 8 |
|
| 9 |
try:
|
| 10 |
import flash_attn_interface
|
| 11 |
+
FLASH_ATTN_3_AVAILABLE = torch.cuda.is_available() and (
|
| 12 |
+
"h100" in torch.cuda.get_device_name(0).lower()
|
| 13 |
+
or "hopper" in torch.cuda.get_device_name(0).lower())
|
| 14 |
+
except ModuleNotFoundError:
|
| 15 |
FLASH_ATTN_3_AVAILABLE = False
|
| 16 |
|
| 17 |
+
try:
|
| 18 |
+
from flash_attn import flash_attn_func
|
| 19 |
+
except ModuleNotFoundError:
|
| 20 |
+
# No FlashAttention wheel on this platform. Every call site below runs
|
| 21 |
+
# without a causal flag or a sliding window (causality is enforced by the
|
| 22 |
+
# KV-cache layout, not the kernel), so PyTorch SDPA is a numerically
|
| 23 |
+
# equivalent substitute.
|
| 24 |
+
from .attention import sdpa_flash_attn_func as flash_attn_func
|
| 25 |
+
|
| 26 |
|
| 27 |
DISABLE_COMPILE = False # get os env
|
| 28 |
flex_attention = torch.compile(
|
wan/modules/attention.py
CHANGED
|
@@ -183,3 +183,46 @@ def attention(
|
|
| 183 |
|
| 184 |
out = out.transpose(1, 2).contiguous()
|
| 185 |
return out
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
|
| 184 |
out = out.transpose(1, 2).contiguous()
|
| 185 |
return out
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
def sdpa_flash_attn_func(
|
| 189 |
+
q,
|
| 190 |
+
k,
|
| 191 |
+
v,
|
| 192 |
+
dropout_p=0.,
|
| 193 |
+
softmax_scale=None,
|
| 194 |
+
causal=False,
|
| 195 |
+
window_size=(-1, -1),
|
| 196 |
+
**kwargs,
|
| 197 |
+
):
|
| 198 |
+
"""Drop-in replacement for ``flash_attn.flash_attn_func`` built on SDPA.
|
| 199 |
+
|
| 200 |
+
Same ``[B, L, H, D]`` in/out layout. Only the argument combinations the
|
| 201 |
+
action module actually uses are supported (no varlen, no sliding window).
|
| 202 |
+
Causal masking follows FlashAttention's bottom-right alignment, which
|
| 203 |
+
differs from ``F.scaled_dot_product_attention(is_causal=True)`` whenever the
|
| 204 |
+
query and key lengths differ.
|
| 205 |
+
"""
|
| 206 |
+
if window_size != (-1, -1):
|
| 207 |
+
raise NotImplementedError(
|
| 208 |
+
"sliding-window attention requires the real flash_attn kernel")
|
| 209 |
+
|
| 210 |
+
q_t, k_t, v_t = q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2)
|
| 211 |
+
attn_mask, is_causal = None, False
|
| 212 |
+
if causal:
|
| 213 |
+
lq, lk = q_t.shape[-2], k_t.shape[-2]
|
| 214 |
+
if lq == lk:
|
| 215 |
+
is_causal = True
|
| 216 |
+
else:
|
| 217 |
+
rows = torch.arange(lq, device=q.device).unsqueeze(1) + (lk - lq)
|
| 218 |
+
cols = torch.arange(lk, device=q.device).unsqueeze(0)
|
| 219 |
+
attn_mask = cols <= rows
|
| 220 |
+
|
| 221 |
+
out = torch.nn.functional.scaled_dot_product_attention(
|
| 222 |
+
q_t, k_t, v_t,
|
| 223 |
+
attn_mask=attn_mask,
|
| 224 |
+
dropout_p=dropout_p,
|
| 225 |
+
is_causal=is_causal,
|
| 226 |
+
scale=softmax_scale,
|
| 227 |
+
)
|
| 228 |
+
return out.transpose(1, 2)
|