| 141 | |
| 142 | |
| 143 | class CrossAttention(nn.Module): |
| 144 | def __init__(self, query_dim, context_dim=None, heads=8, dim_head=64, dropout=0.): |
| 145 | super().__init__() |
| 146 | inner_dim = dim_head * heads |
| 147 | context_dim = default(context_dim, query_dim) |
| 148 | |
| 149 | self.scale = dim_head ** -0.5 |
| 150 | self.heads = heads |
| 151 | |
| 152 | self.to_q = nn.Linear(query_dim, inner_dim, bias=False) |
| 153 | self.to_k = nn.Linear(context_dim, inner_dim, bias=False) |
| 154 | self.to_v = nn.Linear(context_dim, inner_dim, bias=False) |
| 155 | |
| 156 | self.to_out = nn.Sequential( |
| 157 | nn.Linear(inner_dim, query_dim), |
| 158 | nn.Dropout(dropout) |
| 159 | ) |
| 160 | |
| 161 | def forward(self, x, context=None, mask=None): |
| 162 | h = self.heads |
| 163 | |
| 164 | q = self.to_q(x) |
| 165 | context = default(context, x) |
| 166 | k = self.to_k(context) |
| 167 | v = self.to_v(context) |
| 168 | |
| 169 | q, k, v = map(lambda t: rearrange(t, 'b n (h d) -> (b h) n d', h=h), (q, k, v)) |
| 170 | |
| 171 | # force cast to fp32 to avoid overflowing |
| 172 | if _ATTN_PRECISION =="fp32": |
| 173 | with torch.autocast(enabled=False, device_type = 'cuda'): |
| 174 | q, k = q.float(), k.float() |
| 175 | sim = einsum('b i d, b j d -> b i j', q, k) * self.scale |
| 176 | else: |
| 177 | sim = einsum('b i d, b j d -> b i j', q, k) * self.scale |
| 178 | |
| 179 | del q, k |
| 180 | |
| 181 | if exists(mask): |
| 182 | mask = rearrange(mask, 'b ... -> b (...)') |
| 183 | max_neg_value = -torch.finfo(sim.dtype).max |
| 184 | mask = repeat(mask, 'b j -> (b h) () j', h=h) |
| 185 | sim.masked_fill_(~mask, max_neg_value) |
| 186 | |
| 187 | # attention, what we cannot get enough of |
| 188 | sim = sim.softmax(dim=-1) |
| 189 | |
| 190 | out = einsum('b i j, b j d -> b i d', sim, v) |
| 191 | out = rearrange(out, '(b h) n d -> b n (h d)', h=h) |
| 192 | return self.to_out(out) |
| 193 | |
| 194 | |
| 195 | class MemoryEfficientCrossAttention(nn.Module): |
nothing calls this directly
no outgoing calls
no test coverage detected