MSA and pair representations
Diagonal recurrent-state discretization and update
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Your task
For each active position, retain a decayed portion of every state channel and add a dense projection of the normalized injection vector. Convert the supplied continuous parameters into channel step sizes, decay coefficients and an input matrix, then return those discrete parameters and the updated state.
Function signature
diagonal_state_space_update(
state: torch.Tensor,
injection: torch.Tensor,
log_delta: torch.Tensor,
log_decay: torch.Tensor,
input_matrix: torch.Tensor,
norm_weight: torch.Tensor | None = None,
norm_bias: torch.Tensor | None = None,
update_mask: torch.Tensor | None = None,
eps: float = 1e-05,
) -> dict[str, torch.Tensor]Worked example
Decay and inject in different channels
Take state=[2,4], injection=[1,3], log_delta=[log(e-1),log(e-1)], log_decay=[0,0], and input_matrix=[[1,2],[3,4]]; omit optional affine normalization and update mask. Set eps=3. Each step size is 1, so decay=[e⁻¹,e⁻¹] and the discrete input matrix equals the supplied matrix. Injection has mean 2 and population variance 1, giving normalized values [-0.5,0.5]. The dense projection is [1·(-0.5)+2·0.5,3·(-0.5)+4·0.5]=[0.5,0.5]. Return state=[2/e+0.5,4/e+0.5]≈[1.235759,1.971518].
Parameters
| Parameter | Shape and meaning |
|---|---|
statetorch.Tensor | [\ldots, C]Previous recurrent state at each leading-axis position. |
injectiontorch.Tensor | [\ldots, C]Pair features to normalize and inject. |
log_deltatorch.Tensor | [C]Pre-softplus step-size parameters. |
log_decaytorch.Tensor | [C]Logarithmic positive decay rates. |
input_matrixtorch.Tensor | [C, C]Output-channel rows and input-channel columns. |
norm_weighttorch.Tensor | NoneDefault None | [C]Optional floating [C] LayerNorm scale. |
norm_biastorch.Tensor | NoneDefault None | [C]Optional floating [C] LayerNorm shift. |
update_masktorch.Tensor | NoneDefault None | Any shape broadcastable to state.shape[:-1].Optional bool broadcastable to the leading state axes. True advances the state; False preserves its previous value exactly. |
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
- Implement one channel-diagonal
state-space update.stateandinjectionhave the same floating shape[\ldots,C], with\mathrm{rank}\ge 1,C\ge 1and all leading dimensions positive. log_delta[C],log_decay[C]andinput_matrix[C,C]are floating, with the matrix indexed[\mathrm{output\_channel},\mathrm{input\_channel}]. Optionalnorm_weight[C]andnorm_bias[C]default to ones and zeros. All floating values share\mathrm{float32}/64dtype/device.epsis finite positive, default10^{-5}, and is added INSIDE the square root of population variance for LayerNorm. Optional boolupdate_maskbroadcasts tostate.shape[:-1];Trueupdates a position,Falsereturns its priorstateunchanged.- Compute
\delta_{c}=\operatorname{softplus}(\mathrm{log\_delta\_c})stably,\mathrm{decay\_c}=\operatorname{exp}(-\delta_{c}\cdot \operatorname{exp}(\mathrm{log\_decay\_c})), and\mathrm{discrete\_input\_matrix}[c,j]=\delta_{c}\cdot \mathrm{input\_matrix}[c,j]. - Normalize
injectionover its LASTCaxis:\mathrm{centered}=\mathrm{injection}-\operatorname{mean}(\mathrm{injection}),\mathrm{normalized}=\mathrm{centered}/\sqrt{\operatorname{mean}(\mathrm{centered}^{2})+\varepsilon}, then multiply bynorm_weightand addnorm_biaswhen supplied. \mathrm{updated}[\ldots,c]=\mathrm{decay\_c}\cdot \mathrm{state}[\ldots,c]+\sum_{j} \mathrm{discrete\_input\_matrix}[c,j]\cdot \mathrm{normalized}[\ldots,j].Applyupdate_maskonly to the returnedstate.- Return the updated-or-prior state, decay coefficients of shape
(C,), and discrete input matrix of shape(C,C); discretized parameters are returned even if every position is masked. The diagonal refers to channelwisedecay, not a diagonal of the residue-pair grid; the input matrix remains dense. log_deltais in[-40,40]andlog_decayin[-20,20], and all required intermediate products/results are finite and representable. Very smalldecaymay underflow to zero in the supplied dtype. Accept noncontiguous inputs, singleton channels and broadcast update masks; do not mutate inputs.- This is one raw recurrence step, not a nonlinear folding layer or proof that the full recycled model converges.
- Compute softplus stably as
\max(x,0)+\log(1+e^{-|x|}).
Why this matters
A diagonal transition supplies independent decay factors, while a dense input map injects shared features into the state.
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 diagonal_state_space_update(
state: torch.Tensor, # (..., C)
injection: torch.Tensor, # (..., C)
log_delta: torch.Tensor, # (C,)
log_decay: torch.Tensor, # (C,)
input_matrix: torch.Tensor, # (C, C)
norm_weight: torch.Tensor | None = None, # (C,)
norm_bias: torch.Tensor | None = None, # (C,)
update_mask: torch.Tensor | None = None, # Any shape broadcastable to state.shape(:-1).
eps: float = 1e-05,
) -> dict[str, torch.Tensor]:
"""Return dict[str, torch.Tensor]:
state: (..., C).
decay: (C,).
discrete_input_matrix: (C, C)."""
# Implement the operation. Inputs and test setup are supplied by BioTorch.
raise NotImplementedError("Implement diagonal_state_space_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.
Sources and further reading
A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.