(self, x: Tensor, vec: Tensor, pe: Tensor, mask: Tensor = None, txt_length = None)
| 257 | |
| 258 | |
| 259 | def forward(self, x: Tensor, vec: Tensor, pe: Tensor, mask: Tensor = None, txt_length = None): |
| 260 | img_mod1, img_mod2 = self.img_mod(vec) |
| 261 | txt_mod1, txt_mod2 = self.txt_mod(vec) |
| 262 | |
| 263 | txt, img = x[:, :txt_length], x[:, txt_length:] |
| 264 | |
| 265 | # prepare image for attention |
| 266 | img_modulated = self.img_norm1(img) |
| 267 | img_modulated = (1 + img_mod1.scale) * img_modulated + img_mod1.shift |
| 268 | img_qkv = self.img_attn.qkv(img_modulated) |
| 269 | img_q, img_k, img_v = rearrange(img_qkv, "B L (K H D) -> K B H L D", K=3, H=self.num_heads) |
| 270 | img_q, img_k = self.img_attn.norm(img_q, img_k, img_v) |
| 271 | # prepare txt for attention |
| 272 | txt_modulated = self.txt_norm1(txt) |
| 273 | txt_modulated = (1 + txt_mod1.scale) * txt_modulated + txt_mod1.shift |
| 274 | txt_qkv = self.txt_attn.qkv(txt_modulated) |
| 275 | txt_q, txt_k, txt_v = rearrange(txt_qkv, "B L (K H D) -> K B H L D", K=3, H=self.num_heads) |
| 276 | txt_q, txt_k = self.txt_attn.norm(txt_q, txt_k, txt_v) |
| 277 | |
| 278 | # run actual attention |
| 279 | q = torch.cat((txt_q, img_q), dim=2) |
| 280 | k = torch.cat((txt_k, img_k), dim=2) |
| 281 | v = torch.cat((txt_v, img_v), dim=2) |
| 282 | if mask is not None: |
| 283 | mask = repeat(mask, 'B L S-> B H L S', H=self.num_heads) |
| 284 | attn = attention(q, k, v, pe=pe, mask = mask, backend = self.backend) |
| 285 | txt_attn, img_attn = attn[:, : txt.shape[1]], attn[:, txt.shape[1] :] |
| 286 | |
| 287 | # calculate the img bloks |
| 288 | img = img + img_mod1.gate * self.img_attn.proj(img_attn) |
| 289 | img = img + img_mod2.gate * self.img_mlp((1 + img_mod2.scale) * self.img_norm2(img) + img_mod2.shift) |
| 290 | |
| 291 | # calculate the txt bloks |
| 292 | txt = txt + txt_mod1.gate * self.txt_attn.proj(txt_attn) |
| 293 | txt = txt + txt_mod2.gate * self.txt_mlp((1 + txt_mod2.scale) * self.txt_norm2(txt) + txt_mod2.shift) |
| 294 | x = torch.cat((txt, img), 1) |
| 295 | return x |
| 296 | |
| 297 | |
| 298 | class SingleStreamBlock(nn.Module): |
nothing calls this directly
no test coverage detected