MSA and pair representations
Reference-coordinate and space-ID rotary features
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Your task
Turn reference atom coordinates and space identifiers into rotary phases. Return rotated queries and keys along with the exact cosine and sine features used.
Function signature
spatial_rotary_embedding(
q: torch.Tensor,
k: torch.Tensor,
reference_position: torch.Tensor,
space_uid: torch.Tensor,
spatial_inverse_frequency: torch.Tensor,
uid_inverse_frequency: torch.Tensor,
) -> dict[str, torch.Tensor]Worked example
Worked example
The half-width phase vector is [\pi/2,0,0,\pi/2]: the x coordinate and space ID give quarter-turns. Channel pairs (0, 4) and (3, 7) rotate to (-5, 1) and (-8, 4); the other pairs stay unchanged. q_rotated is [-5, 2, 3, -8, 1, 6, 7, 4].
import torch
q = torch.tensor([[[[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]]]], dtype=torch.float64, requires_grad=True)
k = torch.tensor([[[[8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0]]]], dtype=torch.float64, requires_grad=True)
reference_position = torch.tensor([[[1.5707963267948966, 0.0, 0.0]]], dtype=torch.float64, requires_grad=True)
space_uid = torch.tensor([[2]], dtype=torch.int64)
spatial_inverse_frequency = torch.tensor([1.0], dtype=torch.float64, requires_grad=True)
uid_inverse_frequency = torch.tensor([0.7853981633974483], dtype=torch.float64, requires_grad=True)
result = spatial_rotary_embedding(q=q, k=k, reference_position=reference_position, space_uid=space_uid, spatial_inverse_frequency=spatial_inverse_frequency, uid_inverse_frequency=uid_inverse_frequency)Expected return
{
'q_rotated': torch.tensor([[[[-5.0, 2.0, 3.0, -8.0, 1.0000000000000002, 6.0, 7.0, 4.000000000000001]]]], dtype=torch.float64),
'k_rotated': torch.tensor([[[[-3.9999999999999996, 7.0, 6.0, -0.9999999999999997, 8.0, 3.0, 2.0, 5.0]]]], dtype=torch.float64),
'cosine': torch.tensor([[[6.123233995736766e-17, 1.0, 1.0, 6.123233995736766e-17, 6.123233995736766e-17, 1.0, 1.0, 6.123233995736766e-17]]], dtype=torch.float64),
'sine': torch.tensor([[[1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0]]], dtype=torch.float64),
}Parameters
| Parameter | Shape and meaning |
|---|---|
qtorch.Tensor | [B, H, A, D]Query features, already projected into heads. |
ktorch.Tensor | [B, H, A, D]Key features, already projected into heads. |
reference_positiontorch.Tensor | [B, A, 3]Floating [B,A,3] reference xyz. |
space_uidtorch.Tensor | [B, A]Nonnegative int64 [B,A] reference-conformer space IDs. |
spatial_inverse_frequencytorch.Tensor | [S]S\ge 0, same frequencies reused for each physical axis. |
uid_inverse_frequencytorch.Tensor | [U]U\ge 0, separate UID frequencies. |
Return
dict[str, torch.Tensor]
Return exactly the named fields applicable to this operation.
Required behavior
- Implement reference-position/space-UID rotary features and apply them to atom self-attention queries and keys.
qandkhave identical[B,H,A,D]shape withB,H,A\ge 1and positive evenD.reference_position[B,A,3]is floating xyz;space_uid[B,A]is nonnegativeint64. spatial_inverse_frequency[S]anduid_inverse_frequency[U]are floating supplied nonnegative frequencies, withS,U\ge 0and3\cdot S+U\le D/2. All floating inputs share dtype (float32orfloat64) and device, and all phase products are finite and representable. There is no generation of random or checkpoint frequencies.- Construct one half-width angle vector in this exact order:
x\cdot f_{s}fors=0,\ldots,S-1, theny\cdot f_{s}, thenz\cdot f_{s}, then\mathrm{space\_uid}\cdot g_{u}foru=0,\ldots,U-1, thenD/2-3\cdot S-Uzeros. Concatenate that angle vector with itself to get[B,A,D]. - Return
\mathrm{cosine}=\cos(\mathrm{angle})and\mathrm{sine}=\sin(\mathrm{angle}), each[B,A,D]. - For each head split
qinto first and second halves[a,b],\mathrm{rotate\_half}(q)=[-b,a], and\mathrm{q\_rotated}=q\cdot \mathrm{cosine}[:,\mathrm{None}]+\mathrm{rotate\_half}(q)\cdot \mathrm{sine}[:,\mathrm{None}]; apply the same operation tok. Returnq_rotated,k_rotated,cosine,sine. - The inactive PAIRS span corresponding entries in both halves, not necessarily a contiguous trailing
D-channel suffix. No configuration keys or masks are required. Zero-length frequency groups are allowed, includingS=U=0which leavesq/kunchanged. Noncontiguous inputs are supported; do not mutate them. - Normalizing
Q/K, choosing an atom-index attention window, and the attention operation itself are separate problems. These phases use fixed reference coordinates, not noisy sample coordinates. - Coordinate translation with a common UID offset preserves
q-kdot products because only relative phases matter; arbitrary 3D rotations need not preserve scores, so this is not a general\mathrm{SE}(3)-equivariant encoding.
Why this matters
Each coordinate axis and the space identifier supplies a bank of phases. Shared phases make dot products respond to relative coordinates, while unused channel pairs receive zero angle and stay unchanged.
Starter code
You write the body of this function in the BioTorch workspace. Your code runs in an isolated PyTorch sandbox; Run checks the public examples and Submit grades the full test suite, including gradients.
import torch
def spatial_rotary_embedding(
q: torch.Tensor, # (B, H, A, D)
k: torch.Tensor, # (B, H, A, D)
reference_position: torch.Tensor, # (B, A, 3)
space_uid: torch.Tensor, # (B, A)
spatial_inverse_frequency: torch.Tensor, # (S,)
uid_inverse_frequency: torch.Tensor, # (U,)
) -> dict[str, torch.Tensor]:
"""Return dict[str, torch.Tensor]:
q_rotated: (B, H, A, D).
k_rotated: (B, H, A, D).
cosine: (B, A, D).
sine: (B, A, D)."""
# Implement the operation. Inputs and test setup are supplied by BioTorch.
raise NotImplementedError("Implement spatial_rotary_embedding")
Ready to implement it?
3 progressive hints, a solution walkthrough, and grading that checks values, shapes and gradients are waiting in the workspace.
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Sources and further reading
A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.