Args: query (torch.Tensor): query of shape (``N``, ``L_q``, ``E_qk``) key (torch.Tensor): key of shape (``N``, ``L_kv``, ``E_qk``) value (torch.Tensor): value of shape (``N``, ``L_kv``, ``E_v``) attn_mask (torch.Tensor, optional): attention ma
(
self,
query: torch.Tensor,
key: torch.Tensor,
value: torch.Tensor,
attn_mask=None,
is_causal=False,
need_weights=False, # for compatibility with nn.MultiheadAttention
)
| 196 | self.batch_first = batch_first |
| 197 | |
| 198 | def forward( |
| 199 | self, |
| 200 | query: torch.Tensor, |
| 201 | key: torch.Tensor, |
| 202 | value: torch.Tensor, |
| 203 | attn_mask=None, |
| 204 | is_causal=False, |
| 205 | need_weights=False, # for compatibility with nn.MultiheadAttention |
| 206 | ) -> torch.Tensor: |
| 207 | """ |
| 208 | Args: |
| 209 | query (torch.Tensor): query of shape (``N``, ``L_q``, ``E_qk``) |
| 210 | key (torch.Tensor): key of shape (``N``, ``L_kv``, ``E_qk``) |
| 211 | value (torch.Tensor): value of shape (``N``, ``L_kv``, ``E_v``) |
| 212 | attn_mask (torch.Tensor, optional): attention mask of shape (``N``, ``L_q``, ``L_kv``) to pass to SDPA. Default: None |
| 213 | is_causal (bool, optional): Whether to apply causal mask. Default: False |
| 214 | |
| 215 | Returns: |
| 216 | attn_output (torch.Tensor): output of shape (N, L_t, E_q) |
| 217 | """ |
| 218 | if self._qkv_same_embed_dim: |
| 219 | if query is key and key is value: |
| 220 | result = self.packed_proj(query) |
| 221 | query, key, value = torch.chunk(result, 3, dim=-1) |
| 222 | else: |
| 223 | q_weight, k_weight, v_weight = torch.chunk( |
| 224 | self.packed_proj.weight, 3, dim=0 |
| 225 | ) |
| 226 | if self.bias: |
| 227 | q_bias, k_bias, v_bias = torch.chunk( |
| 228 | self.packed_proj.bias, 3, dim=0 |
| 229 | ) |
| 230 | else: |
| 231 | q_bias, k_bias, v_bias = None, None, None |
| 232 | query, key, value = ( |
| 233 | F.linear(query, q_weight, q_bias), |
| 234 | F.linear(key, k_weight, k_bias), |
| 235 | F.linear(value, v_weight, v_bias), |
| 236 | ) |
| 237 | |
| 238 | else: |
| 239 | query = self.q_proj(query) |
| 240 | key = self.k_proj(key) |
| 241 | value = self.v_proj(value) |
| 242 | |
| 243 | query = query.unflatten(-1, [self.nheads, self.E_head]).transpose(1, 2) |
| 244 | key = key.unflatten(-1, [self.nheads, self.E_head]).transpose(1, 2) |
| 245 | value = value.unflatten(-1, [self.nheads, self.E_head]).transpose(1, 2) |
| 246 | |
| 247 | attn_output = F.scaled_dot_product_attention( |
| 248 | query, key, value, dropout_p=self.dropout, is_causal=is_causal |
| 249 | ) |
| 250 | attn_output = attn_output.transpose(1, 2).flatten(-2) |
| 251 | |
| 252 | attn_output = self.out_proj(attn_output) |
| 253 | |
| 254 | return attn_output, None |
| 255 |
nothing calls this directly
no outgoing calls
no test coverage detected