| 193 | |
| 194 | |
| 195 | class MemoryEfficientCrossAttention(nn.Module): |
| 196 | # https://github.com/MatthieuTPHR/diffusers/blob/d80b531ff8060ec1ea982b65a1b8df70f73aa67c/src/diffusers/models/attention.py#L223 |
| 197 | def __init__(self, query_dim, context_dim=None, heads=8, dim_head=64, dropout=0.0): |
| 198 | super().__init__() |
| 199 | # print(f"Setting up {self.__class__.__name__}. Query dim is {query_dim}, context_dim is {context_dim} and using " |
| 200 | # f"{heads} heads.") |
| 201 | inner_dim = dim_head * heads |
| 202 | context_dim = default(context_dim, query_dim) |
| 203 | |
| 204 | self.heads = heads |
| 205 | self.dim_head = dim_head |
| 206 | |
| 207 | self.to_q = nn.Linear(query_dim, inner_dim, bias=False) |
| 208 | self.to_k = nn.Linear(context_dim, inner_dim, bias=False) |
| 209 | self.to_v = nn.Linear(context_dim, inner_dim, bias=False) |
| 210 | |
| 211 | self.to_out = nn.Sequential(nn.Linear(inner_dim, query_dim), nn.Dropout(dropout)) |
| 212 | self.attention_op: Optional[Any] = None |
| 213 | |
| 214 | def forward(self, x, context=None, mask=None): |
| 215 | q = self.to_q(x) |
| 216 | context = default(context, x) |
| 217 | k = self.to_k(context) |
| 218 | v = self.to_v(context) |
| 219 | |
| 220 | b, _, _ = q.shape |
| 221 | q, k, v = map( |
| 222 | lambda t: t.unsqueeze(3) |
| 223 | .reshape(b, t.shape[1], self.heads, self.dim_head) |
| 224 | .permute(0, 2, 1, 3) |
| 225 | .reshape(b * self.heads, t.shape[1], self.dim_head) |
| 226 | .contiguous(), |
| 227 | (q, k, v), |
| 228 | ) |
| 229 | |
| 230 | # actually compute the attention, what we cannot get enough of |
| 231 | out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None, op=self.attention_op) |
| 232 | |
| 233 | if exists(mask): |
| 234 | raise NotImplementedError |
| 235 | out = ( |
| 236 | out.unsqueeze(0) |
| 237 | .reshape(b, self.heads, out.shape[1], self.dim_head) |
| 238 | .permute(0, 2, 1, 3) |
| 239 | .reshape(b, out.shape[1], self.heads * self.dim_head) |
| 240 | ) |
| 241 | return self.to_out(out) |
| 242 | |
| 243 | |
| 244 | class BasicTransformerBlock(nn.Module): |
nothing calls this directly
no outgoing calls
no test coverage detected