comdoleger commited on
Commit
2b1f42f
·
verified ·
1 Parent(s): 3256179

Upload extensions_built_in/diffusion_models/omnigen2/src/models/embeddings.py with huggingface_hub

Browse files
extensions_built_in/diffusion_models/omnigen2/src/models/embeddings.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import List, Optional, Tuple, Union
15
+
16
+ import torch
17
+ from torch import nn
18
+
19
+
20
+ from diffusers.models.activations import get_activation
21
+
22
+
23
+ class TimestepEmbedding(nn.Module):
24
+ def __init__(
25
+ self,
26
+ in_channels: int,
27
+ time_embed_dim: int,
28
+ act_fn: str = "silu",
29
+ out_dim: int = None,
30
+ post_act_fn: Optional[str] = None,
31
+ cond_proj_dim=None,
32
+ sample_proj_bias=True,
33
+ ):
34
+ super().__init__()
35
+
36
+ self.linear_1 = nn.Linear(in_channels, time_embed_dim, sample_proj_bias)
37
+
38
+ if cond_proj_dim is not None:
39
+ self.cond_proj = nn.Linear(cond_proj_dim, in_channels, bias=False)
40
+ else:
41
+ self.cond_proj = None
42
+
43
+ self.act = get_activation(act_fn)
44
+
45
+ if out_dim is not None:
46
+ time_embed_dim_out = out_dim
47
+ else:
48
+ time_embed_dim_out = time_embed_dim
49
+ self.linear_2 = nn.Linear(time_embed_dim, time_embed_dim_out, sample_proj_bias)
50
+
51
+ if post_act_fn is None:
52
+ self.post_act = None
53
+ else:
54
+ self.post_act = get_activation(post_act_fn)
55
+
56
+ self.initialize_weights()
57
+
58
+ def initialize_weights(self):
59
+ nn.init.normal_(self.linear_1.weight, std=0.02)
60
+ nn.init.zeros_(self.linear_1.bias)
61
+ nn.init.normal_(self.linear_2.weight, std=0.02)
62
+ nn.init.zeros_(self.linear_2.bias)
63
+
64
+ def forward(self, sample, condition=None):
65
+ if condition is not None:
66
+ sample = sample + self.cond_proj(condition)
67
+ sample = self.linear_1(sample)
68
+
69
+ if self.act is not None:
70
+ sample = self.act(sample)
71
+
72
+ sample = self.linear_2(sample)
73
+
74
+ if self.post_act is not None:
75
+ sample = self.post_act(sample)
76
+ return sample
77
+
78
+
79
+ def apply_rotary_emb(
80
+ x: torch.Tensor,
81
+ freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]],
82
+ use_real: bool = True,
83
+ use_real_unbind_dim: int = -1,
84
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
85
+ """
86
+ Apply rotary embeddings to input tensors using the given frequency tensor. This function applies rotary embeddings
87
+ to the given query or key 'x' tensors using the provided frequency tensor 'freqs_cis'. The input tensors are
88
+ reshaped as complex numbers, and the frequency tensor is reshaped for broadcasting compatibility. The resulting
89
+ tensors contain rotary embeddings and are returned as real tensors.
90
+
91
+ Args:
92
+ x (`torch.Tensor`):
93
+ Query or key tensor to apply rotary embeddings. [B, H, S, D] xk (torch.Tensor): Key tensor to apply
94
+ freqs_cis (`Tuple[torch.Tensor]`): Precomputed frequency tensor for complex exponentials. ([S, D], [S, D],)
95
+
96
+ Returns:
97
+ Tuple[torch.Tensor, torch.Tensor]: Tuple of modified query tensor and key tensor with rotary embeddings.
98
+ """
99
+ if use_real:
100
+ cos, sin = freqs_cis # [S, D]
101
+ cos = cos[None, None]
102
+ sin = sin[None, None]
103
+ cos, sin = cos.to(x.device), sin.to(x.device)
104
+
105
+ if use_real_unbind_dim == -1:
106
+ # Used for flux, cogvideox, hunyuan-dit
107
+ x_real, x_imag = x.reshape(*x.shape[:-1], -1, 2).unbind(-1) # [B, S, H, D//2]
108
+ x_rotated = torch.stack([-x_imag, x_real], dim=-1).flatten(3)
109
+ elif use_real_unbind_dim == -2:
110
+ # Used for Stable Audio, OmniGen and CogView4
111
+ x_real, x_imag = x.reshape(*x.shape[:-1], 2, -1).unbind(-2) # [B, S, H, D//2]
112
+ x_rotated = torch.cat([-x_imag, x_real], dim=-1)
113
+ else:
114
+ raise ValueError(f"`use_real_unbind_dim={use_real_unbind_dim}` but should be -1 or -2.")
115
+
116
+ out = (x.float() * cos + x_rotated.float() * sin).to(x.dtype)
117
+
118
+ return out
119
+ else:
120
+ # used for lumina
121
+ # x_rotated = torch.view_as_complex(x.float().reshape(*x.shape[:-1], -1, 2))
122
+ x_rotated = torch.view_as_complex(x.float().reshape(*x.shape[:-1], x.shape[-1] // 2, 2))
123
+ freqs_cis = freqs_cis.unsqueeze(2)
124
+ x_out = torch.view_as_real(x_rotated * freqs_cis).flatten(3)
125
+
126
+ return x_out.type_as(x)