multimodalart HF Staff commited on
Commit
3d2e374
·
verified ·
1 Parent(s): 79fce44

SDPA fallback for flash_attn_func in the action module

Browse files
__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 = True
13
- except:
14
- from flash_attn import flash_attn_func
 
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)