Structure module, templates and recycling
ESMFold Recycling Update
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Your task
Prepare the next ESMFold pass by adding feedback from the previous prediction to fresh base features. Reuse single features, pair features and virtual-Cβ distance feedback only when a cache exists and passes remain. Return the prepared features and explicit next-iteration/continuation state.
Function signature
esmfold_recycling_update(
activations: dict,
parameters: dict,
masks: dict,
structure: dict,
max_passes: int = 3,
eps: float = 1e-05,
) -> dict[str, torch.Tensor]Worked example
Use feedback only when available
Item 0 has a previous pass. Its normalized single feedback is [-1, 1] and pair feedback is [-2, 2]. The diagonal virtual-C-beta distance is zero, so bin 0 adds [1.5, 2.5]. The outputs are single [9, 21] and pair [1.5, 8.5]. Item 1 has no previous pass and keeps its base states. next_iteration is [2, 1].
import torch
activations = {
'single_base': torch.tensor([[[10.0, 20.0]], [[30.0, 40.0]]], dtype=torch.float64, requires_grad=True),
'pair_base': torch.tensor([[[[2.0, 4.0]]], [[[6.0, 8.0]]]], dtype=torch.float64, requires_grad=True),
'previous_single': torch.tensor([[[-1.0, 1.0]], [[-1.0, 1.0]]], dtype=torch.float64, requires_grad=True),
'previous_pair': torch.tensor([[[[-1.0, 1.0]]], [[[-1.0, 1.0]]]], dtype=torch.float64, requires_grad=True),
'distance_edges': torch.tensor([2.0], dtype=torch.float64),
}
parameters = {
'single_scale': torch.tensor([2.0, 2.0], dtype=torch.float64, requires_grad=True),
'single_bias': torch.tensor([0.0, 0.0], dtype=torch.float64, requires_grad=True),
'pair_scale': torch.tensor([4.0, 4.0], dtype=torch.float64, requires_grad=True),
'pair_bias': torch.tensor([0.0, 0.0], dtype=torch.float64, requires_grad=True),
'w_single': torch.tensor([[1.0, 0.0], [0.0, 1.0]], dtype=torch.float64, requires_grad=True),
'w_pair': torch.tensor([[1.0, 0.0], [0.0, 1.0]], dtype=torch.float64, requires_grad=True),
'w_distance': torch.tensor([[1.0, 2.0], [3.0, 4.0]], dtype=torch.float64, requires_grad=True),
'b_distance': torch.tensor([0.5, 0.5], dtype=torch.float64, requires_grad=True),
}
masks = {
'has_previous': torch.tensor([True, False], dtype=torch.bool),
'residue_mask': torch.tensor([[True], [True]], dtype=torch.bool),
'atom_mask': torch.full((2, 1, 4), True, dtype=torch.bool),
}
structure = {
'iteration': torch.tensor([1, 0], dtype=torch.int64),
'atom_positions': torch.tensor([[[[0.0, 1.0, 0.0], [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 0.0]]], [[[0.0, 1.0, 0.0], [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 0.0]]]], dtype=torch.float64, requires_grad=True),
}
max_passes = 3
eps = 3.0
result = esmfold_recycling_update(activations=activations, parameters=parameters, masks=masks, structure=structure, max_passes=max_passes, eps=eps)Expected return
{
'pseudo_beta': torch.tensor([[[-0.54067466, -0.56802827, -0.58273431]], [[0.0, 0.0, 0.0]]], dtype=torch.float64),
'distance_bins': torch.tensor([[[0]], [[-1]]], dtype=torch.int64),
'single': torch.tensor([[[9.0, 21.0]], [[30.0, 40.0]]], dtype=torch.float64),
'pair': torch.tensor([[[[1.5, 8.5]]], [[[6.0, 8.0]]]], dtype=torch.float64),
'next_iteration': torch.tensor([2, 1], dtype=torch.int64),
'continue': torch.tensor([True, True], dtype=torch.bool),
}Parameters
| Parameter | Shape and meaning |
|---|---|
activationsdict | Supplied intermediate tensors. |
parametersdict | Supplied model parameters, keyed as shown below. |
masksdict | Supplied masks. Each field below defines what True includes or permits. |
structuredict | Fields supplied together in this dictionary. |
max_passesintDefault 3 | Maximum recycling passes. |
epsfloatDefault 1e-05 | Positive value added to final-axis population variance inside each LayerNorm square root. It is not a mask/count denominator or an output offset. |
Return
dict[str, torch.Tensor]
Return exactly the named fields applicable to this operation.
Required behavior
- Feedback is active where has_previous is True and iteration < max_passes (default 3). Increment iteration wherever iteration < max_passes, even when no previous prediction is present; continue is next_iteration < max_passes.
- Sanitize previous single/pair states with residue_mask, apply supplied affine population LayerNorm (eps default 1e-5 inside square root), and project using w_single/w_pair. Add feedback only for active batch entries to the freshly supplied base states, then mask absent residues/pairs.
- Build virtual Cβ from backbone atoms: with
b=CA-N,d=C-CA, useCA-0.58273431(b\times d)+0.56802827b-0.54067466d. Require all N/CA/C atoms; residue identity is irrelevant. - Distance bin index is the number of squared distance_edges strictly below the squared pseudo-beta separation. Embed the resulting one-hot bins with w_distance plus b_distance, mask invalid residue pairs, and add this geometry contribution only as active feedback.
- Return zero pseudo_beta unless its selected atoms, residue, and feedback are valid. Return distance_bins = −1 unless both endpoints have valid pseudo-beta coordinates; otherwise return the strict-threshold bin index.
Why this matters
Recycling feeds information from an earlier prediction into fresh base representations; it does not itself rerun the network.
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 esmfold_recycling_update(
activations: dict,
parameters: dict,
masks: dict,
structure: dict,
max_passes: int = 3,
eps: float = 1e-05,
) -> dict[str, torch.Tensor]:
"""Return dict[str, torch.Tensor]:
single: (B, N, Cs).
pair: (B, N, N, Cz).
pseudo_beta: (B, N, 3).
distance_bins: (B, N, N).
next_iteration: (B,).
continue: (B,)."""
# Implement the operation. Inputs and test setup are supplied by BioTorch.
raise NotImplementedError("Implement esmfold_recycling_update")
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.
Related exercises
Sources and further reading
A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.