MolecularDiffusion.modules.tasks.diffusion_equifm¶
EquiFM task – equivariant flow matching with hybrid probability transport.
Paper: arXiv:2312.07168 (NeurIPS 2023). Target repo: github.com/AlgoMole/MolFM.
The training objective here is a reconstruction of the paper’s Algorithm 1,
not the authors’ released objective. MolFM’s release is sampling-only: it
ships no loss, no EOT solver, and no data pipeline. args.pickle shows the
released QM9 weights were additionally trained with angle_penalty=True,
cat_loss='l2_masked_mean' and ode_regularization=0.001 – none of which
appear anywhere in the paper. A model trained with this task will therefore not
reproduce the paper’s Table 1 numbers, and the gap must not be reported as a
reproduction failure of the paper. The sampler and the converted released
checkpoint are faithful ports and are the real test of this integration.
Scope (per the approved INTEGRATION_PLAN.md): unconditional QM9 generation only.
No property conditioning / CFG (the release has context_node_nf=0 and no
conditional weights), no gradient guidance, no inpainting, no trajectory frames,
no sample_chain.
Attributes¶
Classes¶
Duck-typed |
|
Factory matching |
Module Contents¶
- class MolecularDiffusion.modules.tasks.diffusion_equifm.EquiFMTask(cnflows: MolecularDiffusion.modules.models.equifm.cnflows.Cnflows, default_n_timesteps: int, dataset_stats: dict, atom_vocab: List)¶
Bases:
torch.nn.ModuleDuck-typed
Task(docs/adding_new_models.md §2.1) aroundCnflows.- evaluate(pred: torch.Tensor, target: torch.Tensor)¶
- forward(batch: Dict[str, torch.Tensor])¶
- predict_and_target(batch: Dict[str, torch.Tensor])¶
- sample(batch_size: int | None = None, nodesxsample: torch.Tensor | None = None, num_steps: int | None = None, batch: Dict[str, torch.Tensor] | None = None, mode=None, n_frames: int = 0, **kwargs)¶
Unconditional sampling. Returns
(one_hot, charges, coords, node_mask)following the EDM/GeoLDM convention (chargesare true nuclear charges), which keepsrunmodes/generate/tasks_generate.pyon thesave_xyz_filebranch.modeandn_framesare accepted and ignored (trajectories are out of scope).
- T¶
- atom_vocab¶
- cnflows¶
- property device¶
- property model¶
- property n_node_dist¶
- property node_dist_model¶
- property norm_values¶
- prop_dist_model = None¶
- task_type = 'diffusion_equifm'¶
- class MolecularDiffusion.modules.tasks.diffusion_equifm.EquiFMTaskFactory(task_type: str = 'diffusion_equifm', n_dims: int = 3, include_charges: bool = True, normalize_factors=(1.0, 4.0, 10.0), sigma_min: float = 0.0001, beta_min: float = 0.1, beta_max: float = 20.0, discrete_path: str = 'HB_path', default_n_timesteps: int = 250, use_eot: bool = True, eot_max_iters: int = 20, dynamics: dict | None = None, dataset_stats: dict | None = None, atom_vocab: List | None = None, train_set: torch.utils.data.Dataset | None = None, **kwargs)¶
Factory matching
cli/train.py’stask_factory.build()pattern.train_setis declared as a named parameter so the declarative seam incli/train.pyinjects the training dataset (docs/adding_new_models.md §2.5); it is used only to build the atom-count histogram that backsnode_dist_model.- build() EquiFMTask¶
- compute_dataset_stats(dataset) None¶
Atom-count histogram from the training set (same shape as FlowMol’s).
- atom_vocab¶
- beta_max = 20.0¶
- beta_min = 0.1¶
- dataset_stats¶
- default_n_timesteps = 250¶
- discrete_path = 'HB_path'¶
- dynamics¶
- eot_max_iters = 20¶
- include_charges = True¶
- kwargs¶
- n_dims = 3¶
- normalize_factors = (1.0, 4.0, 10.0)¶
- sigma_min = 0.0001¶
- task_type = 'diffusion_equifm'¶
- train_set = None¶
- use_eot = True¶
- MolecularDiffusion.modules.tasks.diffusion_equifm.ModelTaskFactory¶