multimodalart HF Staff commited on
Commit
5044ae6
·
verified ·
1 Parent(s): ee15105

Upload diffsynth/models/wan_video_dit.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. diffsynth/models/wan_video_dit.py +24 -4
diffsynth/models/wan_video_dit.py CHANGED
@@ -91,17 +91,22 @@ def precompute_freqs_cis_3d(dim: int, end: int = 1024, theta: float = 10000.0):
91
 
92
 
93
  def precompute_freqs_cis(dim: int, end: int = 1024, theta: float = 10000.0):
94
- # 1d rope precompute
 
95
  freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)
96
- [: (dim // 2)].double() / dim))
97
  freqs = torch.outer(torch.arange(end, device=freqs.device), freqs)
98
  freqs_cis = torch.polar(torch.ones_like(freqs), freqs) # complex64
99
  return freqs_cis
100
 
101
 
102
  def rope_apply(x, freqs, num_heads):
 
 
 
 
103
  x = rearrange(x, "b s (n d) -> b s n d", n=num_heads)
104
- x_out = torch.view_as_complex(x.to(torch.float64).reshape(
105
  x.shape[0], x.shape[1], x.shape[2], -1, 2))
106
  x_out = torch.view_as_real(x_out * freqs).flatten(2)
107
  return x_out.to(x.dtype)
@@ -247,6 +252,7 @@ class SelfAttention(nn.Module):
247
  v_remote = rearrange(v, 'b (w_t n_t) (w_h n_h) (w_w n_w) d -> (b n_t n_h n_w) (w_t w_h w_w) d', w_t=w_t,
248
  w_h=w_h, w_w=w_w).contiguous()
249
  x_remote = self.attn(q_remote, k_remote, v_remote)
 
250
  x_remote = rearrange(x_remote, '(b n_t n_h n_w) (w_t w_h w_w) d -> b (w_t n_t) (w_h n_h) (w_w n_w) d',
251
  n_t=n_t,
252
  n_h=n_h, n_w=n_w, w_t=w_t, w_h=w_h, w_w=w_w).contiguous()
@@ -261,12 +267,14 @@ class SelfAttention(nn.Module):
261
  v_close = rearrange(v, 'b (n_t w_t) (n_h w_h) (n_w w_w) d -> (b n_t n_h n_w) (w_t w_h w_w) d',
262
  w_t=w_t, w_h=w_h, w_w=w_w).contiguous()
263
  x_close = self.attn(q_close, k_close, v_close)
 
264
  x_close = rearrange(x_close, '(b n_t n_h n_w) (w_t w_h w_w) d -> b (n_t w_t) (n_h w_h) (n_w w_w) d',
265
  n_t=n_t,
266
  n_h=n_h, n_w=n_w, w_t=w_t, w_h=w_h, w_w=w_w).contiguous()
267
  else:
268
  x_close = None
269
  # print(x_close.shape, q_close.shape, k_close.shape, v_close.shape)
 
270
 
271
  if self.use_remote and self.use_close:
272
  x = (x_remote + x_close) / 2
@@ -360,9 +368,21 @@ class DiTBlock(nn.Module):
360
  x = self.gate(x, gate_msa, self.self_attn(input_x, freqs))
361
  x = x + self.cross_attn(self.norm3(x), context)
362
  input_x = modulate(self.norm2(x), shift_mlp, scale_mlp)
363
- x = self.gate(x, gate_mlp, self.ffn(input_x))
364
  return x
365
 
 
 
 
 
 
 
 
 
 
 
 
 
366
 
367
  class MLP(torch.nn.Module):
368
  def __init__(self, in_dim, out_dim, has_pos_emb=False):
 
91
 
92
 
93
  def precompute_freqs_cis(dim: int, end: int = 1024, theta: float = 10000.0):
94
+ # 1d rope precompute (fp32: fp64 freqs would force fp64 activations on 4K
95
+ # sequences and blow past a 48 GB GPU; fp32 RoPE is numerically standard)
96
  freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)
97
+ [: (dim // 2)].float() / dim))
98
  freqs = torch.outer(torch.arange(end, device=freqs.device), freqs)
99
  freqs_cis = torch.polar(torch.ones_like(freqs), freqs) # complex64
100
  return freqs_cis
101
 
102
 
103
  def rope_apply(x, freqs, num_heads):
104
+ # Compute RoPE in fp32 (not the upstream fp64): at 685k tokens the fp64
105
+ # cast alone allocates >16 GB transients per q/k and OOMs a 48 GB GPU.
106
+ if freqs.dtype != torch.complex64:
107
+ freqs = freqs.to(torch.complex64)
108
  x = rearrange(x, "b s (n d) -> b s n d", n=num_heads)
109
+ x_out = torch.view_as_complex(x.to(torch.float32).reshape(
110
  x.shape[0], x.shape[1], x.shape[2], -1, 2))
111
  x_out = torch.view_as_real(x_out * freqs).flatten(2)
112
  return x_out.to(x.dtype)
 
252
  v_remote = rearrange(v, 'b (w_t n_t) (w_h n_h) (w_w n_w) d -> (b n_t n_h n_w) (w_t w_h w_w) d', w_t=w_t,
253
  w_h=w_h, w_w=w_w).contiguous()
254
  x_remote = self.attn(q_remote, k_remote, v_remote)
255
+ del q_remote, k_remote, v_remote # free before the close branch runs
256
  x_remote = rearrange(x_remote, '(b n_t n_h n_w) (w_t w_h w_w) d -> b (w_t n_t) (w_h n_h) (w_w n_w) d',
257
  n_t=n_t,
258
  n_h=n_h, n_w=n_w, w_t=w_t, w_h=w_h, w_w=w_w).contiguous()
 
267
  v_close = rearrange(v, 'b (n_t w_t) (n_h w_h) (n_w w_w) d -> (b n_t n_h n_w) (w_t w_h w_w) d',
268
  w_t=w_t, w_h=w_h, w_w=w_w).contiguous()
269
  x_close = self.attn(q_close, k_close, v_close)
270
+ del q_close, k_close, v_close
271
  x_close = rearrange(x_close, '(b n_t n_h n_w) (w_t w_h w_w) d -> b (n_t w_t) (n_h w_h) (n_w w_w) d',
272
  n_t=n_t,
273
  n_h=n_h, n_w=n_w, w_t=w_t, w_h=w_h, w_w=w_w).contiguous()
274
  else:
275
  x_close = None
276
  # print(x_close.shape, q_close.shape, k_close.shape, v_close.shape)
277
+ del q, k, v # base tensors are dead once both branches are computed
278
 
279
  if self.use_remote and self.use_close:
280
  x = (x_remote + x_close) / 2
 
368
  x = self.gate(x, gate_msa, self.self_attn(input_x, freqs))
369
  x = x + self.cross_attn(self.norm3(x), context)
370
  input_x = modulate(self.norm2(x), shift_mlp, scale_mlp)
371
+ x = self.gate(x, gate_mlp, self._ffn_chunked(input_x))
372
  return x
373
 
374
+ def _ffn_chunked(self, input_x: torch.Tensor, chunk_size: int = 65536) -> torch.Tensor:
375
+ # Feed-forward over token chunks: the full (1, 685k, 8960) hidden state
376
+ # is ~12 GB at bf16 batch 1; chunking keeps the peak far below that
377
+ # for a few extra kernel launches. Mathematically identical to self.ffn.
378
+ num_tokens = input_x.shape[1]
379
+ if num_tokens <= chunk_size:
380
+ return self.ffn(input_x)
381
+ outputs = []
382
+ for start in range(0, num_tokens, chunk_size):
383
+ outputs.append(self.ffn(input_x[:, start:start + chunk_size]))
384
+ return torch.cat(outputs, dim=1)
385
+
386
 
387
  class MLP(torch.nn.Module):
388
  def __init__(self, in_dim, out_dim, has_pos_emb=False):