MolecularDiffusion.modules.models.transformer_dynamics¶
Dense self-attention adapter for EnVariationalDiffusion.
Binds a plain (non-equivariant) Transformer to the
dynamics._forward(t, xh, node_mask, edge_mask, context) contract that
EnVariationalDiffusion.phi (modules/models/en_diffusion.py:234)
calls.
Novel-model ablation (docs/model_novel/diffusion_transformer/
INTEGRATION_PLAN.md): swaps EGCL’s equivariant pairwise-difference
message passing (modules/models/egcl.py::EGNN_dynamics) for plain
multi-head self-attention over absolute coordinates, with no distance/edge
features and no built-in rotation-equivariance – the hypothesis is that
the platform’s existing rotation-augmentation flag
(GeomMolecularGenerative.data_augmentation) substitutes for the
architectural guarantee.
Revision 2026-09-09: a real cluster run (300k steps, hyperparameters matched
to the EGCL baseline) still landed far below EGCL’s valid_posebuster. Two
concrete asymmetries against both EGCL and this platform’s other
non-equivariant 3D transformer (ADiT’s DiT,
modules/models/ldm/denoisers/dit.py) were identified and fixed here:
No near-zero output-head init – EGCL’s coordinate-update head is Xavier-init’d with
gain=0.001(modules/layers/conv.py); DiT zero-inits its final projection and AdaLN gates. This file’s output head previously had neither.Time was injected once, additively, at the input – every one of the 9 attention blocks was otherwise unconditioned, unlike DiT’s per-block AdaLN-zero conditioning.
Both are fixed by reusing DiT’s own blocks (DiTBlock, FinalLayer)
by import rather than re-deriving the same recipe – this platform’s other
non-equivariant 3D transformer already solved this exact problem, on the
same platform, so there’s no reason to reinvent it. Transformer/
AttentionBlock (modules/layers/tabasco/) are no longer used here as
a result; TimeFourierEncoding still is, feeding the same time embedding
into every block’s AdaLN conditioning instead of only the input sum.
Classes¶
Denoising network: plain multi-head self-attention, EDM interface. |
Module Contents¶
- class MolecularDiffusion.modules.models.transformer_dynamics.TransformerDynamics(in_node_nf: int, context_node_nf: int = 0, n_dims: int = 3, hidden_dim: int = 192, num_layers: int = 9, num_heads: int = 8, mlp_dim: int | None = None, dropout: float = 0.0, activation_type: str = 'gelu', add_sinusoid_posenc: bool = False)¶
Bases:
torch.nn.ModuleDenoising network: plain multi-head self-attention, EDM interface.
- Parameters:
in_node_nf – Node feature channels the diffusion model expects back (atom-type one-hot + atomic number [+ extra values]), excluding time and context, which are added internally.
context_node_nf – Conditioning channels, concatenated to the node features before embedding.
n_dims – Spatial dimensions (3).
hidden_dim – Transformer token width.
num_layers – Number of ``DiTBlock``s.
num_heads – Multi-head self-attention heads.
mlp_dim – Feed-forward hidden width;
Nonedefaults to4 * hidden_dim(DiTBlock’s own defaultmlp_ratio).dropout – Currently a no-op –
DiTBlock’s attention/MLP hardcode zero dropout internally and silently ignore extra kwargs. Kept as a constructor arg (this platform’s other dynamics wrappers all expose one) rather than removed, since the config default is already 0.0; flagged here so a nonzero value doesn’t look like it did something.activation_type – Currently a no-op for the same reason –
DiTBlock’s MLP hardcodesGELU(approximate="tanh"). Kept for config-shape compatibility with the pre-revision file; the bundled config’s default was already"gelu".add_sinusoid_posenc – Ablation-only knob, off by default. Atoms are an unordered set here, so this has no principled reason to help; it exists only for later ablation curiosity and is never load-bearing.
- add_sinusoid_posenc = False¶
- blocks¶
- context_node_nf = 0¶
- feat_embed¶
- final_layer¶
- in_node_nf¶
- n_dims = 3¶
- pos_embed¶
- time_encoding¶