Apply rotary embeddings to input tensors using the given frequency tensor. This function applies rotary embeddings to the given query or key 'x' tensors using the provided frequency tensor 'freqs_cis'. The input tensors are reshaped as complex numbers, and the frequency tensor is reshap
(
x: torch.Tensor,
freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]],
use_real: bool = True,
use_real_unbind_dim: int = -1,
)
| 1217 | |
| 1218 | |
| 1219 | def apply_rotary_emb( |
| 1220 | x: torch.Tensor, |
| 1221 | freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]], |
| 1222 | use_real: bool = True, |
| 1223 | use_real_unbind_dim: int = -1, |
| 1224 | ) -> Tuple[torch.Tensor, torch.Tensor]: |
| 1225 | """ |
| 1226 | Apply rotary embeddings to input tensors using the given frequency tensor. This function applies rotary embeddings |
| 1227 | to the given query or key 'x' tensors using the provided frequency tensor 'freqs_cis'. The input tensors are |
| 1228 | reshaped as complex numbers, and the frequency tensor is reshaped for broadcasting compatibility. The resulting |
| 1229 | tensors contain rotary embeddings and are returned as real tensors. |
| 1230 | |
| 1231 | Args: |
| 1232 | x (`torch.Tensor`): |
| 1233 | Query or key tensor to apply rotary embeddings. [B, H, S, D] xk (torch.Tensor): Key tensor to apply |
| 1234 | freqs_cis (`Tuple[torch.Tensor]`): Precomputed frequency tensor for complex exponentials. ([S, D], [S, D],) |
| 1235 | |
| 1236 | Returns: |
| 1237 | Tuple[torch.Tensor, torch.Tensor]: Tuple of modified query tensor and key tensor with rotary embeddings. |
| 1238 | """ |
| 1239 | if use_real: # HACK: This is True usually |
| 1240 | cos, sin = freqs_cis # [S, D] |
| 1241 | cos = cos[None, None] |
| 1242 | sin = sin[None, None] |
| 1243 | cos, sin = cos.to(x.device), sin.to(x.device) |
| 1244 | |
| 1245 | if use_real_unbind_dim == -1: # HACK: Pass this branch |
| 1246 | # Used for flux, cogvideox, hunyuan-dit |
| 1247 | x_real, x_imag = x.reshape(*x.shape[:-1], -1, 2).unbind(-1) # [B, S, H, D//2] |
| 1248 | x_rotated = torch.stack([-x_imag, x_real], dim=-1).flatten(3) |
| 1249 | elif use_real_unbind_dim == -2: |
| 1250 | # Used for Stable Audio |
| 1251 | x_real, x_imag = x.reshape(*x.shape[:-1], 2, -1).unbind(-2) # [B, S, H, D//2] |
| 1252 | x_rotated = torch.cat([-x_imag, x_real], dim=-1) |
| 1253 | else: |
| 1254 | raise ValueError(f"`use_real_unbind_dim={use_real_unbind_dim}` but should be -1 or -2.") |
| 1255 | |
| 1256 | out = (x.float() * cos + x_rotated.float() * sin).to(x.dtype) |
| 1257 | |
| 1258 | return out |
| 1259 | else: |
| 1260 | # used for lumina |
| 1261 | x_rotated = torch.view_as_complex(x.float().reshape(*x.shape[:-1], -1, 2)) |
| 1262 | freqs_cis = freqs_cis.unsqueeze(2) |
| 1263 | x_out = torch.view_as_real(x_rotated * freqs_cis).flatten(3) |
| 1264 | |
| 1265 | return x_out.type_as(x) |
| 1266 | |
| 1267 | |
| 1268 | def apply_rotary_emb_allegro(x: torch.Tensor, freqs_cis, positions): |
no test coverage detected