r""" Determine mask type and combine masks if necessary. Note: This function will continue to improve with the iteration of MHA. Args: attn_mask: MHA's attention mask tensor, the shape is :math:`(L, S)` or :math:`(N\cdot\text{num\_heads}, L, S)` key_padding_mask: MHA's
(
attn_mask: Tensor,
key_padding_mask: Tensor,
query: Tensor,
key: Tensor,
add_bias_kv: bool = False,
add_zero_attn: bool = False,
is_causal: bool = False,
maybe_cudnn_style_mask: bool = False,
num_heads: int = 0,
)
| 2199 | |
| 2200 | |
| 2201 | def _merge_masks( |
| 2202 | attn_mask: Tensor, |
| 2203 | key_padding_mask: Tensor, |
| 2204 | query: Tensor, |
| 2205 | key: Tensor, |
| 2206 | add_bias_kv: bool = False, |
| 2207 | add_zero_attn: bool = False, |
| 2208 | is_causal: bool = False, |
| 2209 | maybe_cudnn_style_mask: bool = False, |
| 2210 | num_heads: int = 0, |
| 2211 | ): |
| 2212 | r""" |
| 2213 | Determine mask type and combine masks if necessary. |
| 2214 | |
| 2215 | Note: This function will continue to improve with the iteration of MHA. |
| 2216 | |
| 2217 | Args: |
| 2218 | attn_mask: MHA's attention mask tensor, the shape is :math:`(L, S)` or :math:`(N\cdot\text{num\_heads}, L, S)` |
| 2219 | key_padding_mask: MHA's padding mask tensor, the shape is :math:`(N, S)` |
| 2220 | query: MHA's query, the shape is :math:`(N, L, E_q)` |
| 2221 | key: MHA's key, the shape is :math:`(N, S, E_k)` |
| 2222 | add_bias_kv: used to determine whether pad is needed on the sequence dimension of attn_mask and key_padding_mask, from MHA's ``add_bias_kv``. |
| 2223 | add_zero_attn: used to determine whether pad is needed on the sequence dimension of attn_mask and key_padding_mask, from MHA's ``add_zero_attn``. |
| 2224 | is_causal: MHA's is_causal, is_causal provides a hint that attn_mask is the causal mask. |
| 2225 | maybe_cudnn_style_mask: MHA's maybe_cudnn_style_mask, like is_causal, maybe_cudnn_style_mask provides a hint that attn_mask and key_padding_mask is the cudnn style mask. |
| 2226 | num_heads: MHA's head number. |
| 2227 | Returns: |
| 2228 | merged_mask: merged mask, may be None, the shape is :math:`(L, S)`, :math:`(2\cdotL + 2\cdotN)` or :math:`(N\cdot\text{num\_heads}, L, S)` |
| 2229 | mask_type: merged mask type ``("no_mask", "default_mask", "cudnn_style_mask" or "user_defined_mask")`` |
| 2230 | """ |
| 2231 | mask_type = "no_mask" |
| 2232 | merged_mask = None |
| 2233 | batch_size = query.shape[0] |
| 2234 | seq_qlen = query.shape[1] |
| 2235 | seq_klen = key.shape[1] |
| 2236 | attn_mask_dim = attn_mask.ndim if attn_mask is not None else 0 |
| 2237 | attn_mask_shape = attn_mask.shape if attn_mask is not None else 0 |
| 2238 | key_padding_mask_shape = ( |
| 2239 | key_padding_mask.shape if key_padding_mask is not None else 0 |
| 2240 | ) |
| 2241 | |
| 2242 | # is_causal is used to hint whether to use a causal mask, where the upper right triangle is all -inf, |
| 2243 | # and the diagonal and lower left triangle are all 0. But if attn_mask is given, attn_mask is used first. |
| 2244 | if ( |
| 2245 | not maybe_cudnn_style_mask |
| 2246 | and is_causal |
| 2247 | and attn_mask is None |
| 2248 | and key_padding_mask is None |
| 2249 | ): |
| 2250 | # At this point, merged_mask = None |
| 2251 | mask_type = "default_mask" |
| 2252 | elif ( |
| 2253 | not maybe_cudnn_style_mask |
| 2254 | and is_causal |
| 2255 | and attn_mask is not None |
| 2256 | and key_padding_mask is None |
| 2257 | ): |
| 2258 | # At this point, merged_mask = attn_mask |
no test coverage detected