MolecularDiffusion.modules.models.ditmc.flow_matching¶
Flow matching with a constant-noise interpolant. Port of
dit_mc/generative_process/flow_matching.py (+ the Kabsch / augmentation /
loss-reduction helpers from dit_mc/training/utils.py).
The interpolant is
with \(x_0\) from the harmonic prior, Kabsch-aligned to \(x_1\)
before interpolating, and every quantity centre-of-mass centred. With the
default regress_x1_bool=True the network regresses the clean \(x_1\) and
the drift is recovered as \(v_t = (\hat x_1 - x_\tau)/(1-\tau)\).
Three reductions that are easy to get wrong and are pinned here:
The loss is a mean over x/y/z and a mean over atoms, then a per-graph weight, then a sum divided by the number of graphs. A sum over xyz would scale it by 3N (
training/utils.py:91-125).The per-graph weight is \(1/(1-\min(\tau, 0.9))^2\), using the per-graph tau, not the per-node one.
Classifier-free guidance draws one Bernoulli per batch, not per molecule (
flow_matching.py:271).
Rotation augmentation is on by default upstream
(globals.augmentation_bool: True). Without it dit_ape/dit_rpe, which
are not equivariant by construction, train on a different distribution.
Classes¶
The generative process. Holds no parameters -- the network is passed in. |
Functions¶
|
Mean over trailing dims, segment-mean per graph, weight, sum / #graphs. |
|
Subtract the per-molecule centre of mass. |
|
Rigidly align |
|
One Haar-uniform rotation per molecule, applied to every |
Module Contents¶
- class MolecularDiffusion.modules.models.ditmc.flow_matching.FlowMatching(prior, sigma: float = 0.5, align_bool: bool = True, conditioning_bool: bool = True, regress_x1_bool: bool = True, weighted_loss_bool: bool = True, mixture_tau_bool: bool = False, free_guidance_bool: bool = False, free_guidance_prob: float = 0.1, self_conditioning_bool: bool = False, self_conditioning_prob: float = 0.5)¶
The generative process. Holds no parameters – the network is passed in.
- clean_prediction(nn_out, graph_latent: MolecularDiffusion.modules.models.ditmc.graphs.LatentGraph, time_latent)¶
(x1_pred, vt)from the raw network output.
- loss(net, graph_latent: MolecularDiffusion.modules.models.ditmc.graphs.LatentGraph, graph_prior, graph_cond, *, generator: torch.Generator | None = None) tuple[torch.Tensor, dict]¶
One training step.
graph_latent.x1must be set.
- sample(net, graph_latent: MolecularDiffusion.modules.models.ditmc.graphs.LatentGraph, graph_prior, graph_cond, *, num_steps: int = 50, free_guidance_scale: float = 1.0, logarithmic_time_bool: bool = False, return_trajectory: bool = False, generator: torch.Generator | None = None)¶
Explicit Euler integration of
v_tfromtau=0totau=1.
- align_bool = True¶
- conditioning_bool = True¶
- free_guidance_bool = False¶
- free_guidance_prob = 0.1¶
- mixture_tau_bool = False¶
- prior¶
- regress_x1_bool = True¶
- self_conditioning_bool = False¶
- self_conditioning_prob = 0.5¶
- sigma = 0.5¶
- weighted_loss_bool = True¶
- MolecularDiffusion.modules.models.ditmc.flow_matching.aggregate_node_error(node_error: torch.Tensor, batch_segments: torch.Tensor, num_graphs: int, graph_weight=1.0, scale: float = 1.0) torch.Tensor¶
Mean over trailing dims, segment-mean per graph, weight, sum / #graphs.
- MolecularDiffusion.modules.models.ditmc.flow_matching.center_data(x: torch.Tensor, batch_segments: torch.Tensor, num_graphs: int) torch.Tensor¶
Subtract the per-molecule centre of mass.
- MolecularDiffusion.modules.models.ditmc.flow_matching.kabsch_align(p: torch.Tensor, q: torch.Tensor, batch_segments: torch.Tensor, num_graphs: int) torch.Tensor¶
Rigidly align
pontoqper molecule (proper rotations only).
- MolecularDiffusion.modules.models.ditmc.flow_matching.rotation_augmentation(tensors: dict[str, torch.Tensor], batch_segments: torch.Tensor, num_graphs: int, *, generator: torch.Generator | None = None) tuple[dict[str, torch.Tensor], torch.Tensor]¶
One Haar-uniform rotation per molecule, applied to every
(N, 3)field.