maltefranke commited on
Commit
cd01066
·
verified ·
1 Parent(s): 7611e15

Add GEOM-Drugs epoch 100 and QM9 epochs 1000 and 1500 with inference assets

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. geom/explicit_h/README.md +8 -4
  2. geom/explicit_h/epoch_100.ckpt +3 -0
  3. geom/explicit_h/manifest.json +10 -6
  4. geom/explicit_h/metadata.json +9 -0
  5. geom/explicit_h/validation.json +36 -14
  6. qm9/explicit_h/README.md +16 -0
  7. qm9/explicit_h/atom_tokens.txt +5 -0
  8. qm9/explicit_h/charge_tokens.txt +3 -0
  9. qm9/explicit_h/config.yaml +327 -0
  10. qm9/explicit_h/distributions.json +56 -0
  11. qm9/explicit_h/distributions.pt +3 -0
  12. qm9/explicit_h/edge_tokens.txt +5 -0
  13. qm9/explicit_h/epoch_1000.ckpt +3 -0
  14. qm9/explicit_h/epoch_1500.ckpt +3 -0
  15. qm9/explicit_h/manifest.json +610 -0
  16. qm9/explicit_h/metadata.json +55 -0
  17. qm9/explicit_h/runtime/README.md +5 -0
  18. qm9/explicit_h/runtime/configs/callbacks/callbacks.yaml +20 -0
  19. qm9/explicit_h/runtime/configs/data/chembl3d/chembl3d.yaml +8 -0
  20. qm9/explicit_h/runtime/configs/data/chembl3d/implicit_h.yaml +5 -0
  21. qm9/explicit_h/runtime/configs/data/chembl3d/max100.yaml +7 -0
  22. qm9/explicit_h/runtime/configs/data/chembl3d/max100_implicit_h.yaml +5 -0
  23. qm9/explicit_h/runtime/configs/data/geom/geom.yaml +11 -0
  24. qm9/explicit_h/runtime/configs/data/geom/implicit_h.yaml +5 -0
  25. qm9/explicit_h/runtime/configs/data/geom/scaffold_decoration.yaml +24 -0
  26. qm9/explicit_h/runtime/configs/data/molecular.yaml +136 -0
  27. qm9/explicit_h/runtime/configs/data/qm9/qm9.yaml +106 -0
  28. qm9/explicit_h/runtime/configs/data/qm9/scaffold_decoration.yaml +22 -0
  29. qm9/explicit_h/runtime/configs/default.yaml +25 -0
  30. qm9/explicit_h/runtime/configs/defaults/chembl3d/chembl3d.yaml +5 -0
  31. qm9/explicit_h/runtime/configs/defaults/chembl3d/implicit_h.yaml +5 -0
  32. qm9/explicit_h/runtime/configs/defaults/chembl3d/implicit_h_2x4090.yaml +10 -0
  33. qm9/explicit_h/runtime/configs/defaults/chembl3d/train_2x4090.yaml +40 -0
  34. qm9/explicit_h/runtime/configs/defaults/core.yaml +13 -0
  35. qm9/explicit_h/runtime/configs/defaults/geom/geom.yaml +20 -0
  36. qm9/explicit_h/runtime/configs/defaults/geom/implicit_h.yaml +5 -0
  37. qm9/explicit_h/runtime/configs/defaults/geom/scaffold_decoration.yaml +23 -0
  38. qm9/explicit_h/runtime/configs/defaults/qm9/qm9.yaml +20 -0
  39. qm9/explicit_h/runtime/configs/defaults/qm9/scaffold_decoration.yaml +11 -0
  40. qm9/explicit_h/runtime/configs/defaults/qm9/train_2x4090.yaml +29 -0
  41. qm9/explicit_h/runtime/configs/embeddings/geom.yaml +28 -0
  42. qm9/explicit_h/runtime/configs/embeddings/qm9.yaml +29 -0
  43. qm9/explicit_h/runtime/configs/heads/head.yaml +75 -0
  44. qm9/explicit_h/runtime/configs/insertion_head/gmm.yaml +16 -0
  45. qm9/explicit_h/runtime/configs/insertion_head/unimodal.yaml +13 -0
  46. qm9/explicit_h/runtime/configs/integrator/integrator.yaml +30 -0
  47. qm9/explicit_h/runtime/configs/logging/wandb_logger.yaml +6 -0
  48. qm9/explicit_h/runtime/configs/loss_weights/calibrated_geom.yaml +18 -0
  49. qm9/explicit_h/runtime/configs/loss_weights/calibrated_geom_frozen.yaml +25 -0
  50. qm9/explicit_h/runtime/configs/loss_weights/tuned_weights.yaml +15 -0
geom/explicit_h/README.md CHANGED
@@ -1,12 +1,16 @@
1
- # GEOM-Drugs with explicit hydrogens — epoch 50
2
 
3
- Continued from the best checkpoint after 48 completed epochs. The original Lightning checkpoint includes current weights, EMA weights and optimizer state. The inference loader constructs only the selected network (EMA by default).
 
 
 
 
4
 
5
  ```python
6
  from morph.inference import load_pretrained
7
 
8
- model = load_pretrained("geom-explicit-h", epoch=50, device="cuda")
9
  trajectories, validity, vocab, coordinate_std = model.generate(n_mols=16)
10
  ```
11
 
12
- The training subset contains at most 72 atoms including hydrogen. Coordinates returned by generation are in Angstrom. Config, vocabularies and training distributions are included; no dataset is needed for inference.
 
1
+ # GEOM-Drugs with explicit hydrogens
2
 
3
+ Published completed epochs: 50, 100.
4
+
5
+ Continued from the best checkpoint after 48 completed epochs. The training subset contains at most 72 atoms including hydrogen.
6
+
7
+ The original Lightning checkpoints include current weights, EMA weights and optimizer state. The inference loader constructs only the selected network (EMA by default).
8
 
9
  ```python
10
  from morph.inference import load_pretrained
11
 
12
+ model = load_pretrained("geom-explicit-h", epoch=100, device="cuda")
13
  trajectories, validity, vocab, coordinate_std = model.generate(n_mols=16)
14
  ```
15
 
16
+ Coordinates returned by generation are in Angstrom. Config, vocabularies and training distributions are included; no dataset is needed for inference. Training settings and source are in `training_bundle.tar.gz`.
geom/explicit_h/epoch_100.ckpt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0ab5ad7247b5518858c8cb6aa7c4102352e8fe09cbb6744c33a4c784c85b8587
3
+ size 509181449
geom/explicit_h/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "README.md": {
3
- "bytes": 701,
4
- "sha256": "9947149d5b311da2f381b57f135811eb1eade2dba84cdf452ae69f5e11ba1016"
5
  },
6
  "atom_tokens.txt": {
7
  "bytes": 22,
@@ -32,8 +32,8 @@
32
  "sha256": "016c4a5bbb4f5ef36d1d62dff772ecf8d384e8ab3e2c94ebeb4c4357183f690a"
33
  },
34
  "metadata.json": {
35
- "bytes": 1094,
36
- "sha256": "b23b8944369765d12b2cbae0f5d48614225e44cb59deff8bb0e49783318ddb31"
37
  },
38
  "runtime/configs/callbacks/callbacks.yaml": {
39
  "bytes": 699,
@@ -596,11 +596,15 @@
596
  "sha256": "4fd11b415e9b4a599344431218db7f9960ba443dc29787410a4566ce5dacb434"
597
  },
598
  "validation.json": {
599
- "bytes": 294,
600
- "sha256": "5acbbb78be426e03abd58c3dc062b30b000e91e815c329dfa7f1422c9866b740"
601
  },
602
  "runtime/README.md": {
603
  "bytes": 1041,
604
  "sha256": "7e32e04cce313c7faad9a3170ab009591aa327a900ee67f980889b7d7e4c82ba"
 
 
 
 
605
  }
606
  }
 
1
  {
2
  "README.md": {
3
+ "bytes": 790,
4
+ "sha256": "abba7fd92562707cf7a27e782e2abe357f012a261a57964a035351bf673c17eb"
5
  },
6
  "atom_tokens.txt": {
7
  "bytes": 22,
 
32
  "sha256": "016c4a5bbb4f5ef36d1d62dff772ecf8d384e8ab3e2c94ebeb4c4357183f690a"
33
  },
34
  "metadata.json": {
35
+ "bytes": 1404,
36
+ "sha256": "b4deb28242f9bcefe514ab60288652105e2975bca68c53ab1a740976a53fa099"
37
  },
38
  "runtime/configs/callbacks/callbacks.yaml": {
39
  "bytes": 699,
 
596
  "sha256": "4fd11b415e9b4a599344431218db7f9960ba443dc29787410a4566ce5dacb434"
597
  },
598
  "validation.json": {
599
+ "bytes": 780,
600
+ "sha256": "b296c55b86daeaf6e68f77b807fe3965ee6627ab0540da584fa9b0fc16f0f238"
601
  },
602
  "runtime/README.md": {
603
  "bytes": 1041,
604
  "sha256": "7e32e04cce313c7faad9a3170ab009591aa327a900ee67f980889b7d7e4c82ba"
605
+ },
606
+ "epoch_100.ckpt": {
607
+ "bytes": 509181449,
608
+ "sha256": "0ab5ad7247b5518858c8cb6aa7c4102352e8fe09cbb6744c33a4c784c85b8587"
609
  }
610
  }
geom/explicit_h/metadata.json CHANGED
@@ -17,6 +17,15 @@
17
  "global_step": 441050,
18
  "bytes": 509181385,
19
  "sha256": "016c4a5bbb4f5ef36d1d62dff772ecf8d384e8ab3e2c94ebeb4c4357183f690a"
 
 
 
 
 
 
 
 
 
20
  }
21
  ],
22
  "atom_tokens": [
 
17
  "global_step": 441050,
18
  "bytes": 509181385,
19
  "sha256": "016c4a5bbb4f5ef36d1d62dff772ecf8d384e8ab3e2c94ebeb4c4357183f690a"
20
+ },
21
+ {
22
+ "filename": "epoch_100.ckpt",
23
+ "original_filename": "epoch=99-step=882100.ckpt",
24
+ "completed_epochs": 100,
25
+ "checkpoint_epoch_index": 99,
26
+ "global_step": 882100,
27
+ "bytes": 509181449,
28
+ "sha256": "0ab5ad7247b5518858c8cb6aa7c4102352e8fe09cbb6744c33a4c784c85b8587"
29
  }
30
  ],
31
  "atom_tokens": [
geom/explicit_h/validation.json CHANGED
@@ -1,17 +1,39 @@
1
  {
2
  "dataset_access": false,
3
- "completed_epochs": 50,
4
- "global_step": 441050,
5
- "all_checkpoint_weights_finite": true,
6
- "strict_load": {
7
- "current": true,
8
- "ema": true
9
- },
10
- "sampling_smoke": {
11
- "attempts": 1,
12
- "integration_steps": 100,
13
- "validity": [
14
- true
15
- ]
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
 
1
  {
2
  "dataset_access": false,
3
+ "checkpoints": [
4
+ {
5
+ "dataset_access": false,
6
+ "completed_epochs": 50,
7
+ "global_step": 441050,
8
+ "all_checkpoint_weights_finite": true,
9
+ "strict_load": {
10
+ "current": true,
11
+ "ema": true
12
+ },
13
+ "sampling_smoke": {
14
+ "attempts": 1,
15
+ "integration_steps": 100,
16
+ "validity": [
17
+ true
18
+ ]
19
+ }
20
+ },
21
+ {
22
+ "dataset_access": false,
23
+ "completed_epochs": 100,
24
+ "global_step": 882100,
25
+ "all_checkpoint_weights_finite": true,
26
+ "strict_load": {
27
+ "current": true,
28
+ "ema": true
29
+ },
30
+ "sampling_smoke": {
31
+ "attempts": 1,
32
+ "integration_steps": 100,
33
+ "validity": [
34
+ true
35
+ ]
36
+ }
37
+ }
38
+ ]
39
  }
qm9/explicit_h/README.md ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # QM9 with explicit hydrogens
2
+
3
+ Published completed epochs: 1000, 1500.
4
+
5
+ Trained from scratch on the original QM9 split with explicit hydrogen atoms. Validation runs every epoch and checkpoints are retained every 25 epochs.
6
+
7
+ The original Lightning checkpoints include current weights, EMA weights and optimizer state. The inference loader constructs only the selected network (EMA by default).
8
+
9
+ ```python
10
+ from morph.inference import load_pretrained
11
+
12
+ model = load_pretrained("qm9-explicit-h", epoch=1500, device="cuda")
13
+ trajectories, validity, vocab, coordinate_std = model.generate(n_mols=16)
14
+ ```
15
+
16
+ Coordinates returned by generation are in Angstrom. Config, vocabularies and training distributions are included; no dataset is needed for inference. Training settings and source are in `training_bundle.tar.gz`.
qm9/explicit_h/atom_tokens.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ C
2
+ F
3
+ H
4
+ N
5
+ O
qm9/explicit_h/charge_tokens.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ -1
2
+ 0
3
+ 1
qm9/explicit_h/config.yaml ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ representation: molecule
2
+ seed: 42
3
+ heads:
4
+ heads:
5
+ _target_: morph.model.layers.heads.MultiHeadModule
6
+ output_init_std: ${model.head_initialization.output_std}
7
+ independent_adapters: ${oc.select:model.head_independent_adapters,false}
8
+ heads_configs:
9
+ graph_aggregation: mean
10
+ node_heads:
11
+ atom_type_head:
12
+ input_dim: ${model.head_node_dim}
13
+ output_dim: ${len:${data.vocab.atom_tokens}}
14
+ adapter_dim: ${model.head_node_adapter_dim}
15
+ group: state
16
+ charge_head:
17
+ input_dim: ${model.head_node_dim}
18
+ output_dim: ${len:${data.vocab.charge_tokens}}
19
+ adapter_dim: ${model.head_node_adapter_dim}
20
+ group: state
21
+ ins_rate_head:
22
+ input_dim: ${model.head_node_dim}
23
+ output_dim: 1
24
+ adapter_dim: ${model.head_node_adapter_dim}
25
+ group: edit
26
+ initial_rate: ${model.head_initialization.ins_rate}
27
+ do_del_head:
28
+ input_dim: ${model.head_node_dim}
29
+ output_dim: 1
30
+ adapter_dim: ${model.head_node_adapter_dim}
31
+ group: edit
32
+ initial_probability: ${model.head_initialization.do_del_probability}
33
+ do_sub_a_head:
34
+ input_dim: ${model.head_node_dim}
35
+ output_dim: 1
36
+ adapter_dim: ${model.head_node_adapter_dim}
37
+ group: edit
38
+ initial_probability: ${model.head_initialization.do_sub_a_probability}
39
+ edge_heads:
40
+ edge_type_head:
41
+ input_dim: ${model.head_edge_dim}
42
+ output_dim: ${len:${data.vocab.edge_tokens}}
43
+ adapter_dim: ${model.head_edge_adapter_dim}
44
+ group: state
45
+ do_sub_e_head:
46
+ input_dim: ${model.head_edge_dim}
47
+ output_dim: 1
48
+ adapter_dim: ${model.head_edge_adapter_dim}
49
+ group: state
50
+ initial_probability: ${model.head_initialization.do_sub_e_probability}
51
+ ins_edge_head:
52
+ _target_: morph.model.layers.heads.InsertionEdgeHead
53
+ _recursive_: false
54
+ hidden_dim: ${model.head_node_dim}
55
+ readout_dim: ${model.head_insertion_edge_dim}
56
+ output_init_std: ${model.head_initialization.output_std}
57
+ n_edge_types: ${len:${data.vocab.edge_tokens}}
58
+ n_atom_types: ${len:${data.vocab.atom_tokens}}
59
+ n_charge_types: ${len:${data.vocab.charge_tokens}}
60
+ rbf_embedding_args:
61
+ _target_: morph.model.layers.embedding.RBFEmbedding
62
+ num_rbf: 128
63
+ rbf_dmax: 3.5
64
+ out_dim: 64
65
+ dropout: 0.0
66
+ trainable: false
67
+ insertion_head:
68
+ mode: unimodal
69
+ dimension: 3
70
+ num_components: 1
71
+ model:
72
+ _target_: morph.model.layers.heads.UnimodalInsertionHead
73
+ hidden_dim: ${model.head_node_dim}
74
+ readout_dim: ${model.head_insertion_adapter_dim}
75
+ output_init_std: ${model.head_initialization.output_std}
76
+ independent_adapters: ${oc.select:model.head_independent_adapters,false}
77
+ N_a: ${len:${data.vocab.atom_tokens}}
78
+ N_c: ${len:${data.vocab.charge_tokens}}
79
+ model:
80
+ module:
81
+ optimizer_config:
82
+ implementation: torch
83
+ optimizer:
84
+ execution: ${oc.env:MORPH_MUON_EXECUTION,native}
85
+ lr: 0.01
86
+ momentum: 0.95
87
+ weight_decay: 0.0
88
+ nesterov: true
89
+ ns_steps: 5
90
+ eps: 1.0e-07
91
+ adjust_lr_fn: original
92
+ aux_optimizer:
93
+ lr: 0.0003
94
+ betas:
95
+ - 0.9
96
+ - 0.95
97
+ eps: 1.0e-10
98
+ weight_decay: 0.0
99
+ gradient_clip_val: 1.0
100
+ gradient_clip_algorithm: norm
101
+ scheduler:
102
+ _target_: morph.utils.lr_schedulers.MultiGroupCosineWarmupLR
103
+ warmup_steps: 2000
104
+ total_steps: 200000
105
+ min_lr_fraction: 0.05
106
+ last_epoch: -1
107
+ interval: step
108
+ monitor: null
109
+ loss_weights:
110
+ do_sub_a: 0.2
111
+ sub_a_class: 0.03
112
+ do_sub_e: 0.25
113
+ sub_e_class: 0.5
114
+ do_del: 0.4
115
+ ins_rate: 0.15
116
+ ins_state: 0.01
117
+ ins_e: 0.4
118
+ x: 2.0
119
+ c: 0.5
120
+ ins_e_ii: 0.03
121
+ _target_: morph.model.lightning.base.LightningModuleRates
122
+ insertion_head_mode: ${insertion_head.mode}
123
+ ins_noise_scale: ${data.ins_noise_scale}
124
+ ema_decay: 0.999
125
+ ema_warmup_steps: 5000
126
+ use_ema_for_eval: true
127
+ time_dist: ${if:${eq:${model.sample_time_strategy}, log}, ${model.beta_sched},
128
+ ${model.linear_sched}}
129
+ integrator: ${model.integrator}
130
+ vocab: ${data.vocab}
131
+ use_learnable_loss_weights: false
132
+ use_time_weights: false
133
+ model:
134
+ _target_: morph.model.backbones.dit.DiTBackboneWithHeads
135
+ _recursive_: false
136
+ atom_type_embedding_args: ${embeddings.atom_type_embedding}
137
+ edge_type_embedding_args: ${embeddings.edge_type_embedding}
138
+ time_embedding_args: ${embeddings.time_embedding}
139
+ node_count_embedding_args: ${embeddings.node_count_embedding}
140
+ incident_bond_embedding: false
141
+ backbone_model_args: ${model.backbone}
142
+ heads_args: ${heads.heads}
143
+ insertion_head_args: ${insertion_head.model}
144
+ ins_edge_head_args: ${heads.ins_edge_head}
145
+ rotate: true
146
+ n_augmentations: 1
147
+ integrator: ${integrator.integrator}
148
+ beta_sched:
149
+ _target_: torch.distributions.Beta
150
+ concentration1: 2.0
151
+ concentration0: 1.0
152
+ linear_sched:
153
+ _target_: torch.distributions.Uniform
154
+ low: 0.0
155
+ high: 1.0
156
+ sample_time_strategy: linear
157
+ head_node_dim: ${model.backbone.out_node_nf}
158
+ head_edge_dim: ${model.backbone.out_edge_nf}
159
+ head_node_adapter_dim: 256
160
+ head_edge_adapter_dim: 256
161
+ head_insertion_adapter_dim: 256
162
+ head_insertion_edge_dim: 256
163
+ head_independent_adapters: true
164
+ head_initialization:
165
+ output_std: 0.001
166
+ coordinate_output_std: 0.0
167
+ do_del_probability: 0.5
168
+ do_sub_a_probability: 0.5
169
+ do_sub_e_probability: 0.5
170
+ ins_rate: 0.6931471805599453
171
+ token_weighting:
172
+ type_loss_token_weights: uniform
173
+ weight_alpha: 0.4
174
+ lora:
175
+ enabled: false
176
+ rank: 8
177
+ alpha: 8.0
178
+ dropout: 0.0
179
+ targets:
180
+ - qkv
181
+ - proj
182
+ - mlp.gate_value
183
+ - mlp.out_proj
184
+ freeze_base: true
185
+ backbone:
186
+ _target_: morph.model.backbones.dit.DiTBackbone
187
+ _recursive_: false
188
+ d_input: ${embeddings.atom_type_embedding.out_dim}
189
+ d_cond: ${oc.eval:"${embeddings.time_embedding.out_dim} + ${embeddings.node_count_embedding.out_dim}"}
190
+ d_model: 512
191
+ out_node_nf: 256
192
+ out_edge_nf: 256
193
+ num_layers: 8
194
+ nhead: 16
195
+ mlp_ratio: 4.0
196
+ ffn_hidden_dim: null
197
+ ffn_multiple_of: 64
198
+ qk_norm: true
199
+ coordinate_output_init_std: ${model.head_initialization.coordinate_output_std}
200
+ center_coordinate_output: true
201
+ in_edge_nf: ${embeddings.edge_type_embedding.out_dim}
202
+ edge_pair_dim: 256
203
+ pair_bias_hidden_dim: 32
204
+ num_atom_types: ${len:${data.vocab.atom_tokens}}
205
+ lora: ${model.lora}
206
+ rbf_embedding_args:
207
+ _target_: morph.model.layers.embedding.RBFEmbedding
208
+ num_rbf: 128
209
+ rbf_dmax: 3.5
210
+ out_dim: 64
211
+ dropout: 0.0
212
+ trainable: false
213
+ schedule:
214
+ _target_: morph.flow_matching.schedules.SmoothstepSchedule
215
+ shift: 0.8
216
+ trainer:
217
+ trainer:
218
+ deterministic: warn
219
+ devices: 1
220
+ accelerator: auto
221
+ strategy: auto
222
+ precision: 32-true
223
+ max_epochs: 3000
224
+ accumulate_grad_batches: 2
225
+ num_sanity_val_steps: 0
226
+ gradient_clip_val: null
227
+ gradient_clip_algorithm: norm
228
+ check_val_every_n_epoch: 1
229
+ num_val_samples: 4096
230
+ limit_val_batches: null
231
+ limit_predict_batches: 4
232
+ max_time: null
233
+ enable_progress_bar: false
234
+ do_train: false
235
+ do_validate: false
236
+ do_predict: true
237
+ checkpoint_path: null
238
+ final_checkpoint_path: null
239
+ callbacks: {}
240
+ logging:
241
+ enabled: false
242
+ project: morph-${data.dataset_name}
243
+ name: qm9-explicit-h
244
+ save_dir: .
245
+ offline: false
246
+ integrator:
247
+ integrator:
248
+ _target_: morph.flow_matching.integration.RateIntegrator
249
+ vocab: ${data.vocab}
250
+ distributions: None
251
+ insertion_head_mode: ${insertion_head.mode}
252
+ insertion_dimension: ${insertion_head.dimension}
253
+ insertion_num_components: ${insertion_head.num_components}
254
+ time_strategy: log
255
+ time_beta_alpha: 2.0
256
+ time_beta_beta: 1.0
257
+ num_integration_steps: 100
258
+ ins_noise_scale: ${data.ins_noise_scale}
259
+ renoise_insertions: true
260
+ exact_schedule_integration: true
261
+ del_schedule: ${data.interpolator.del_schedule}
262
+ ins_schedule: ${data.interpolator.ins_schedule}
263
+ sub_schedule: ${data.interpolator.sub_schedule}
264
+ sub_e_schedule: ${data.interpolator.sub_e_schedule}
265
+ data:
266
+ dataset_name: qm9
267
+ root_path: .
268
+ preprocess_workers: 0
269
+ n_atoms_strategy: uniform
270
+ uniform_n_atoms_padding: 5
271
+ optimal_transport: equivariant
272
+ ins_noise_scale: 0.35
273
+ move_noise_scale: 0.3
274
+ allow_charged: false
275
+ preprocessing:
276
+ _target_: morph.dataset.core.preprocessing.Preprocessing
277
+ _recursive_: false
278
+ root: .
279
+ train_dataset: null
280
+ atom_tokens_path: ${data.preprocessing.root}/atom_tokens.txt
281
+ edge_tokens_path: ${data.preprocessing.root}/edge_tokens.txt
282
+ charge_tokens_path: ${data.preprocessing.root}/charge_tokens.txt
283
+ distributions_path: ${data.preprocessing.root}/distributions.pt
284
+ num_workers: 0
285
+ vocab: None
286
+ interpolator:
287
+ _target_: morph.flow_matching.interpolation.Interpolator
288
+ distributions: None
289
+ optimal_transport: ${data.optimal_transport}
290
+ ins_noise_scale: ${data.ins_noise_scale}
291
+ move_noise_scale: ${data.move_noise_scale}
292
+ pre_align_iters: 2
293
+ c_move: 1.0
294
+ c_sub: 0.0
295
+ c_ins: 6.125
296
+ c_del: 6.125
297
+ del_schedule: ${schedule}
298
+ ins_schedule: ${schedule}
299
+ sub_schedule:
300
+ _target_: morph.flow_matching.schedules.SmoothstepSchedule
301
+ shift: 1.5
302
+ sub_e_schedule:
303
+ _target_: morph.flow_matching.schedules.SmoothstepSchedule
304
+ shift: 1.5
305
+ datamodule: null
306
+ embeddings:
307
+ atom_type_embedding:
308
+ _target_: morph.model.layers.embedding.Embedding
309
+ num_embeddings: ${len:${data.vocab.atom_tokens}}
310
+ embedding_dim: 64
311
+ out_dim: 128
312
+ edge_type_embedding:
313
+ _target_: morph.model.layers.embedding.Embedding
314
+ num_embeddings: ${len:${data.vocab.edge_tokens}}
315
+ embedding_dim: 64
316
+ out_dim: 128
317
+ time_embedding:
318
+ _target_: morph.model.layers.embedding.TimeEmbedding
319
+ embedding_dim: 128
320
+ out_dim: 128
321
+ node_count_embedding:
322
+ _target_: morph.model.layers.embedding.ExtrapolatableCountEmbedding
323
+ embedding_dim: 64
324
+ out_dim: 128
325
+ min_period: 64.0
326
+ max_period: 512.0
327
+ max_count: 32.0
qm9/explicit_h/distributions.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "atom_type_distribution": [
3
+ 0.36011767387390137,
4
+ 0.00031341883004643023,
5
+ 0.5080203413963318,
6
+ 0.05379530042409897,
7
+ 0.07775323837995529
8
+ ],
9
+ "edge_type_distribution": [
10
+ 0.8788241147994995,
11
+ 0.10941674560308456,
12
+ 0.00502026965841651,
13
+ 0.0020077268127352,
14
+ 0.004731142893433571
15
+ ],
16
+ "charge_type_distribution": [
17
+ 0.00020011454762425274,
18
+ 0.9995997548103333,
19
+ 0.00020011454762425274
20
+ ],
21
+ "n_atoms_distribution": [
22
+ 0.0,
23
+ 0.0,
24
+ 0.0,
25
+ 1.9999999494757503e-05,
26
+ 3.9999998989515007e-05,
27
+ 4.999999873689376e-05,
28
+ 0.00011999999696854502,
29
+ 0.0002099999983329326,
30
+ 0.0006699999794363976,
31
+ 0.0016299999551847577,
32
+ 0.00395999988541007,
33
+ 0.007689999882131815,
34
+ 0.015320000238716602,
35
+ 0.029020000249147415,
36
+ 0.05211000144481659,
37
+ 0.08551999926567078,
38
+ 0.11935000121593475,
39
+ 0.14640000462532043,
40
+ 0.14754000306129456,
41
+ 0.1411599963903427,
42
+ 0.09175000339746475,
43
+ 0.08540000021457672,
44
+ 0.026650000363588333,
45
+ 0.03260999917984009,
46
+ 0.0037499999161809683,
47
+ 0.007519999984651804,
48
+ 0.00033999999868683517,
49
+ 0.001069999998435378,
50
+ 0.0,
51
+ 9.999999747378752e-05
52
+ ],
53
+ "coordinate_std": 1.373397946357727,
54
+ "pairwise_distance_histogram": null,
55
+ "radius_of_gyration_histogram": null
56
+ }
qm9/explicit_h/distributions.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:93d265dd9afcf536270680492e4bf6ba776969d0811a32e918b8a8994189ccc6
3
+ size 2585
qm9/explicit_h/edge_tokens.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <NO_BOND>
2
+ 1
3
+ 2
4
+ 3
5
+ 4
qm9/explicit_h/epoch_1000.ckpt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:144410a5d6efcb326c3dfa466bbd3ec1fb203d4278923f2ec7d8a486ef9f8f1e
3
+ size 508845203
qm9/explicit_h/epoch_1500.ckpt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:90b418b9aa5de7cdb2109df20bc4ded1c46159b3abd10595750a5b583d0f9f87
3
+ size 508845203
qm9/explicit_h/manifest.json ADDED
@@ -0,0 +1,610 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "README.md": {
3
+ "bytes": 809,
4
+ "sha256": "fc9f081b53993af560a3dbeebcab1d35e937100453175bbf6692a582734c6520"
5
+ },
6
+ "atom_tokens.txt": {
7
+ "bytes": 10,
8
+ "sha256": "f5d5fb17b30809b00de20eeb6fe7b0d93a2a60ffd36339e06e875f5ba882de0c"
9
+ },
10
+ "charge_tokens.txt": {
11
+ "bytes": 7,
12
+ "sha256": "e8f533e310170a31a7e5e5fe125447fbe0253de205966ae295713c98c6ac531c"
13
+ },
14
+ "config.yaml": {
15
+ "bytes": 10254,
16
+ "sha256": "b2f460c9863459983689c7db35a8bf912f604b381dc3aeb06f77993196a2b566"
17
+ },
18
+ "distributions.json": {
19
+ "bytes": 1303,
20
+ "sha256": "309fcb1c579957c26b0db523953449ec76e0c58f2a793c6d4e924ca1a49dbe68"
21
+ },
22
+ "distributions.pt": {
23
+ "bytes": 2585,
24
+ "sha256": "93d265dd9afcf536270680492e4bf6ba776969d0811a32e918b8a8994189ccc6"
25
+ },
26
+ "edge_tokens.txt": {
27
+ "bytes": 18,
28
+ "sha256": "45ff09c48d164f6add1fa4b61d61564798d49dfebc697bf99a866dca60506d4c"
29
+ },
30
+ "epoch_1000.ckpt": {
31
+ "bytes": 508845203,
32
+ "sha256": "144410a5d6efcb326c3dfa466bbd3ec1fb203d4278923f2ec7d8a486ef9f8f1e"
33
+ },
34
+ "epoch_1500.ckpt": {
35
+ "bytes": 508845203,
36
+ "sha256": "90b418b9aa5de7cdb2109df20bc4ded1c46159b3abd10595750a5b583d0f9f87"
37
+ },
38
+ "metadata.json": {
39
+ "bytes": 1395,
40
+ "sha256": "6e54fdcd0481b12211232de7d75c050995f64a2d89b6da572b624af0300a06dc"
41
+ },
42
+ "runtime/README.md": {
43
+ "bytes": 302,
44
+ "sha256": "31e2f5e3dc2b9ededfb6c6d8f0de40092288fb2affcf0ba13fa667f997c374c6"
45
+ },
46
+ "runtime/configs/callbacks/callbacks.yaml": {
47
+ "bytes": 699,
48
+ "sha256": "dce0adebf5956dce687d64a074238f9c12866373bfe21df6658d967d6bfd1f90"
49
+ },
50
+ "runtime/configs/data/chembl3d/chembl3d.yaml": {
51
+ "bytes": 278,
52
+ "sha256": "a96974d90353a850c4a1d0bac27de5f1fc8724b81cc5bbc122aab6f76f3051c5"
53
+ },
54
+ "runtime/configs/data/chembl3d/implicit_h.yaml": {
55
+ "bytes": 81,
56
+ "sha256": "08da196d0288cf1fe4dba8dd407c49d9bee003607504beb59f79e5d6b9eaef0c"
57
+ },
58
+ "runtime/configs/data/chembl3d/max100.yaml": {
59
+ "bytes": 246,
60
+ "sha256": "052dba7b3f3efce990019518823476bd6bf1381bb5f606822c9fc7a485e6d0bf"
61
+ },
62
+ "runtime/configs/data/chembl3d/max100_implicit_h.yaml": {
63
+ "bytes": 79,
64
+ "sha256": "152325f11c7d1500469d4ee381100ae12247e6a2e0b90e5ef7501b405144bb2d"
65
+ },
66
+ "runtime/configs/data/geom/geom.yaml": {
67
+ "bytes": 428,
68
+ "sha256": "736c04e86c029bed65ce3ed022f937dd418ddc70d4b9fc064b38d979bf29ee6d"
69
+ },
70
+ "runtime/configs/data/geom/implicit_h.yaml": {
71
+ "bytes": 73,
72
+ "sha256": "c6b3ff5496af997de0c28e5aa7265903d6d0c8b59aab001ab21d6a64baeb772a"
73
+ },
74
+ "runtime/configs/data/geom/scaffold_decoration.yaml": {
75
+ "bytes": 1107,
76
+ "sha256": "d317728a98961e98a1f03bcc3b0f8c513169ca23b68ea07ba807b99066e7ca80"
77
+ },
78
+ "runtime/configs/data/molecular.yaml": {
79
+ "bytes": 5005,
80
+ "sha256": "f79ade5ddbf7d08f2eecbb2aa9c3e6b182b8a8e7e48960aff5e5edda5601bdc9"
81
+ },
82
+ "runtime/configs/data/qm9/qm9.yaml": {
83
+ "bytes": 3648,
84
+ "sha256": "3beea93868a1e889b049dcc2ccbc3b7489fa4672e964138654bc512ea01ab9f2"
85
+ },
86
+ "runtime/configs/data/qm9/scaffold_decoration.yaml": {
87
+ "bytes": 890,
88
+ "sha256": "40b36f2bc25bf4052cdd676a26d9e528cb4f7b13deddbb1660f454f97b159c40"
89
+ },
90
+ "runtime/configs/default.yaml": {
91
+ "bytes": 1294,
92
+ "sha256": "bcf9744acbf53afa4305ffd6e9cf95e6f99571750488eaa8cad85896a51aca66"
93
+ },
94
+ "runtime/configs/defaults/chembl3d/chembl3d.yaml": {
95
+ "bytes": 90,
96
+ "sha256": "f09553bc670e6c87ac8c1f8bbd0a8df73f1e83b02a3dcf9d6d06b915ac3bce93"
97
+ },
98
+ "runtime/configs/defaults/chembl3d/implicit_h.yaml": {
99
+ "bytes": 102,
100
+ "sha256": "a0ee1440984eb4c9d3c96a5d1c18df9f59b8e42c499f8a340ccd8deb8c454cd8"
101
+ },
102
+ "runtime/configs/defaults/chembl3d/implicit_h_2x4090.yaml": {
103
+ "bytes": 331,
104
+ "sha256": "518571405333a40e1602ee4c77fd153b56fd53e77aaa2aaf530796142f58d4b8"
105
+ },
106
+ "runtime/configs/defaults/chembl3d/train_2x4090.yaml": {
107
+ "bytes": 826,
108
+ "sha256": "0e6b01b264ab1ae70ae7f144ecd0a03d242e24f02feb087e3d5e2b7bc24790da"
109
+ },
110
+ "runtime/configs/defaults/core.yaml": {
111
+ "bytes": 431,
112
+ "sha256": "0dcfb68e2fece1dc277f647d3b3769af882cf8175e0c3b479bc50029e2538b1c"
113
+ },
114
+ "runtime/configs/defaults/geom/geom.yaml": {
115
+ "bytes": 425,
116
+ "sha256": "f447a1bdd39e211b5cf43c4cce56e708da6472d58f79e87885621ec4899c1c8e"
117
+ },
118
+ "runtime/configs/defaults/geom/implicit_h.yaml": {
119
+ "bytes": 98,
120
+ "sha256": "9d3a188e6bd2a2b01609ba0d652184bb8a2f7e27fd89d4a3031568051cae605e"
121
+ },
122
+ "runtime/configs/defaults/geom/scaffold_decoration.yaml": {
123
+ "bytes": 828,
124
+ "sha256": "bcce546bce2b0b7bfaf7c0663e05423fd03c952bf6e52cbbf31976723661f0d1"
125
+ },
126
+ "runtime/configs/defaults/qm9/qm9.yaml": {
127
+ "bytes": 429,
128
+ "sha256": "46070ea792300c0817c0acdff256181b21ef17dfe9f72070bb12da27dc28d534"
129
+ },
130
+ "runtime/configs/defaults/qm9/scaffold_decoration.yaml": {
131
+ "bytes": 348,
132
+ "sha256": "3bb8b6a757ea4921c31df2c0869949baef703df980b964d9636f52b64ac39267"
133
+ },
134
+ "runtime/configs/defaults/qm9/train_2x4090.yaml": {
135
+ "bytes": 554,
136
+ "sha256": "43a835246afb7126786e8ffa71c8b80ed9db1ef3a16e5240f1eec7882a4ef5ba"
137
+ },
138
+ "runtime/configs/embeddings/geom.yaml": {
139
+ "bytes": 803,
140
+ "sha256": "06793f4d446d899197e3db28d064592af9049612ee78cb0718a63e3d6fdc3151"
141
+ },
142
+ "runtime/configs/embeddings/qm9.yaml": {
143
+ "bytes": 849,
144
+ "sha256": "de57af7f1ff9b44dbb952f852c0177789196105b77f396298ff8e0218c0626b7"
145
+ },
146
+ "runtime/configs/heads/head.yaml": {
147
+ "bytes": 2475,
148
+ "sha256": "238e2346041e0aedccd16a6ed4066e163004c0e45a2cbc6fd1f6d17e16eb44ed"
149
+ },
150
+ "runtime/configs/insertion_head/gmm.yaml": {
151
+ "bytes": 488,
152
+ "sha256": "1e26914eed9b4971e0f6ff0b61bbdb34103233d346719a55ba6273dd3d785c05"
153
+ },
154
+ "runtime/configs/insertion_head/unimodal.yaml": {
155
+ "bytes": 495,
156
+ "sha256": "547a6391c3b341e3e369f8f4c7aab9752c67dfbbb533388d25956e9011b305e8"
157
+ },
158
+ "runtime/configs/integrator/integrator.yaml": {
159
+ "bytes": 1580,
160
+ "sha256": "8f0d9aafb0b2727cd58154e1fd97df693c8b7d4f5a3fb5efcb9188553f54660f"
161
+ },
162
+ "runtime/configs/logging/wandb_logger.yaml": {
163
+ "bytes": 139,
164
+ "sha256": "a9a2787e048d4eb70f2ff3c49d4355f1a5a382047c8619203b1f9131d829928d"
165
+ },
166
+ "runtime/configs/loss_weights/calibrated_geom.yaml": {
167
+ "bytes": 644,
168
+ "sha256": "d4763c84aa9e1eb77fb2b456384332a4b3a84b072d560918b2357222a43f4ca1"
169
+ },
170
+ "runtime/configs/loss_weights/calibrated_geom_frozen.yaml": {
171
+ "bytes": 1141,
172
+ "sha256": "a08acb61d67a852051dbded08f8bb67f21101888fd0a22a96a522781d28c570d"
173
+ },
174
+ "runtime/configs/loss_weights/tuned_weights.yaml": {
175
+ "bytes": 420,
176
+ "sha256": "2bb5884465666d6fc638f787fd79257e4126c69a5cc55b55615fc45e02e65894"
177
+ },
178
+ "runtime/configs/loss_weights/uniform.yaml": {
179
+ "bytes": 336,
180
+ "sha256": "3c14d6443048f69d436fe03792703a33c67f368ecbb349de2fd145da4c96eabc"
181
+ },
182
+ "runtime/configs/model/backbones/dit.yaml": {
183
+ "bytes": 4039,
184
+ "sha256": "65b0f08be8fb307b8b01e7b460fd083fe60d48148fbece378d7e5a23dd4a9fb0"
185
+ },
186
+ "runtime/configs/model/finetune/lora_finetune.yaml": {
187
+ "bytes": 328,
188
+ "sha256": "6334a5112499c0f3bc1fe5de224e2b6b3265dc524c8d6b9048113868fb864558"
189
+ },
190
+ "runtime/configs/model/finetune/scaffold_finetune.yaml": {
191
+ "bytes": 5659,
192
+ "sha256": "1aad0d33e9b5ae95d9f50b5201a29bb8677fe42ea2bcf59e0e61d053ef1dfddb"
193
+ },
194
+ "runtime/configs/optimizer/muon_aux_adam.yaml": {
195
+ "bytes": 1212,
196
+ "sha256": "3b0a6189f3ba81f85f7d26c6f6ad7f64dcb25098a14e411211d7a62983a7180c"
197
+ },
198
+ "runtime/configs/schedule/beta.yaml": {
199
+ "bytes": 78,
200
+ "sha256": "75c485edfd70016b255282adcf5de25dfb95c9e32bb6587017fb8935ffe64eaa"
201
+ },
202
+ "runtime/configs/schedule/cubic.yaml": {
203
+ "bytes": 54,
204
+ "sha256": "a998a2d3390ab5daf4df079852ae8daa907687cf059f55c500409c9493949c0c"
205
+ },
206
+ "runtime/configs/schedule/fast_power.yaml": {
207
+ "bytes": 126,
208
+ "sha256": "22f36106bd43ca253ffea412e00539f2b07efbc49109b97c1232df6a827a2baf"
209
+ },
210
+ "runtime/configs/schedule/linear.yaml": {
211
+ "bytes": 55,
212
+ "sha256": "f7881af26080ab5569e67b39f6eae2733c033b9623020e6271959f09fac45fa0"
213
+ },
214
+ "runtime/configs/schedule/smoothstep.yaml": {
215
+ "bytes": 70,
216
+ "sha256": "f6e8651953d93f0d18c997d40c199b3d80ddd352a2041cc51e29adc9a7f22778"
217
+ },
218
+ "runtime/configs/trainer/trainer.yaml": {
219
+ "bytes": 1402,
220
+ "sha256": "6f78e83ad46529bee7a2878b20727ff403420a515c1629bd73a608a2fb654f5f"
221
+ },
222
+ "runtime/pyproject.toml": {
223
+ "bytes": 4464,
224
+ "sha256": "d4854128f81144905cef68d37222d0d06fb372e2bd148e49177e0ff082a7b01f"
225
+ },
226
+ "runtime/requirements-tested.txt": {
227
+ "bytes": 177,
228
+ "sha256": "fac030b53775fd8ed8f89b17050ea74180f99dfab270b1d75d4ca3c0573ede76"
229
+ },
230
+ "runtime/src/morph/__init__.py": {
231
+ "bytes": 79,
232
+ "sha256": "bb402ea5c6f79e569205cc2bf4168d06430753ce8499ca4ffb8614743626fd59"
233
+ },
234
+ "runtime/src/morph/__main__.py": {
235
+ "bytes": 149,
236
+ "sha256": "95a7983479559ca2b15c7afa3881b3142ef4636583501184469b972df7646d4f"
237
+ },
238
+ "runtime/src/morph/_vendor/__init__.py": {
239
+ "bytes": 72,
240
+ "sha256": "8480cd966a03870a7142e1763094bf00e221d2c3c2b1af1d4d458fb8b7f37a20"
241
+ },
242
+ "runtime/src/morph/_vendor/geom_drugs_preprocessing.py": {
243
+ "bytes": 11328,
244
+ "sha256": "33a9c21d29df269a5f342a0b0e8bced0fc620559f0cb3a7a4cfabd5c369ceccb"
245
+ },
246
+ "runtime/src/morph/_vendor/muon.py": {
247
+ "bytes": 16405,
248
+ "sha256": "c61af8c2c4a635cc682b84e279851cb54fedc6fb935d8eb11aafbeb1c5e81fc6"
249
+ },
250
+ "runtime/src/morph/cli.py": {
251
+ "bytes": 9723,
252
+ "sha256": "27eee3fd6d6410747f12b19b670a74f50a51b842a50b1eff4e75c46d0d08a986"
253
+ },
254
+ "runtime/src/morph/config.py": {
255
+ "bytes": 704,
256
+ "sha256": "bd3562c030611f87cc514308f155ad93740dd59927732f71b2e15009012d78ff"
257
+ },
258
+ "runtime/src/morph/dataset/__init__.py": {
259
+ "bytes": 620,
260
+ "sha256": "44ae493354fed0fec4b410f46e0c1fb0351b5fbe5f404ff50f77181e60a39cee"
261
+ },
262
+ "runtime/src/morph/dataset/conditional/__init__.py": {
263
+ "bytes": 238,
264
+ "sha256": "e46c747069acbf3d82407ccfcf96f2e33608c010a429f9abdb064bb71795d134"
265
+ },
266
+ "runtime/src/morph/dataset/conditional/scaffold/__init__.py": {
267
+ "bytes": 167,
268
+ "sha256": "6ef414b31cceb7303c174d720e0d0666efd6f6678c97b3cf86d33c799d2153dd"
269
+ },
270
+ "runtime/src/morph/dataset/conditional/scaffold/cutters.py": {
271
+ "bytes": 12282,
272
+ "sha256": "b29e0d7b1758461cda868bcba56d58b21ce76a45a9365bed73f7a2735103616f"
273
+ },
274
+ "runtime/src/morph/dataset/conditional/scaffold/datamodule.py": {
275
+ "bytes": 1402,
276
+ "sha256": "ecd4a5819d3654f8f76e3e0d059a60bfc9d0ac2ec343514d45517e7094c7c282"
277
+ },
278
+ "runtime/src/morph/dataset/conditional/scaffold/lmdb.py": {
279
+ "bytes": 4243,
280
+ "sha256": "54ea075ebb4a8ed481f93f57e9a5e25504918b6595bde106f2489e21e7e73b5b"
281
+ },
282
+ "runtime/src/morph/dataset/conditional/scaffold/wrappers.py": {
283
+ "bytes": 7720,
284
+ "sha256": "a44d61452b676dc1dfd8d6bd44c09b22d463c8129b23cf98ec3903d10a693f2c"
285
+ },
286
+ "runtime/src/morph/dataset/core/__init__.py": {
287
+ "bytes": 376,
288
+ "sha256": "7bab9c675f0850efc50e14a9898accfde5f8d1c1e2420414ac8c0986822d27e0"
289
+ },
290
+ "runtime/src/morph/dataset/core/atomic_data.py": {
291
+ "bytes": 708,
292
+ "sha256": "7d59ec16ed5b3cf82b57b49dd4d7799862709353a65f4d473d4571ba91b86fa6"
293
+ },
294
+ "runtime/src/morph/dataset/core/batch.py": {
295
+ "bytes": 23924,
296
+ "sha256": "7b2b2afd749b621b1ca890d192e4dc9378b61ead9ef34b90f04dc449e6bad369"
297
+ },
298
+ "runtime/src/morph/dataset/core/containers.py": {
299
+ "bytes": 19637,
300
+ "sha256": "adae656c3fbbe5cfe32f378a419c7e1076f653163ffe7d2c1d1d0abc71a99cd7"
301
+ },
302
+ "runtime/src/morph/dataset/core/conversion.py": {
303
+ "bytes": 2224,
304
+ "sha256": "0842565c503048a86a517c202dd0cc7c07e9296a841601b178ec38c43f903a6a"
305
+ },
306
+ "runtime/src/morph/dataset/core/flow_matching_wrapper.py": {
307
+ "bytes": 7568,
308
+ "sha256": "7672ce6dc416bbccae1471b8e4fb66f44adf7eaf8f0f2fa151f1268e9513a17d"
309
+ },
310
+ "runtime/src/morph/dataset/core/insertion_data.py": {
311
+ "bytes": 14393,
312
+ "sha256": "7e99e4d59b29ea537708b5f7887ed3e61b4b31ebf80d55fe5a0c6823ff8a439c"
313
+ },
314
+ "runtime/src/morph/dataset/core/insertion_targets.py": {
315
+ "bytes": 6614,
316
+ "sha256": "2e62e89125310572735d916e97c8a544cfb3eb76fb167ecd134b5f8b0424df8c"
317
+ },
318
+ "runtime/src/morph/dataset/core/lightning_datamodule.py": {
319
+ "bytes": 7057,
320
+ "sha256": "4d525cbcde4a64d7cac41837e0379c40097cc38fbbc2f54ff30ff7e3ab83de4c"
321
+ },
322
+ "runtime/src/morph/dataset/core/lmdb.py": {
323
+ "bytes": 10111,
324
+ "sha256": "748b7a10f8fb20f74c267de393cc3e1933ea86debde99d8fdaaef94e0a9afd29"
325
+ },
326
+ "runtime/src/morph/dataset/core/preprocessing.py": {
327
+ "bytes": 20145,
328
+ "sha256": "da9cffd6beb6da63ee749dd8b60d4d0509bcd937778014739b04ffc599dde066"
329
+ },
330
+ "runtime/src/morph/dataset/core/properties.py": {
331
+ "bytes": 1952,
332
+ "sha256": "4dc63574f5fde284245078adf50fb2d8a9ac16443b8276154c03b7703cc2e937"
333
+ },
334
+ "runtime/src/morph/dataset/core/representation.py": {
335
+ "bytes": 6591,
336
+ "sha256": "0ecac55e1faf9748826ec8f4c7f1a274263214ea3f68cc69de7047b55dd6a65f"
337
+ },
338
+ "runtime/src/morph/dataset/core/tokenized_decode.py": {
339
+ "bytes": 6559,
340
+ "sha256": "483afb3d468113da33cc8699998e6439fcde2264ee7ca479724206360584a2b8"
341
+ },
342
+ "runtime/src/morph/dataset/core/vocab.py": {
343
+ "bytes": 2236,
344
+ "sha256": "f8618488f7bcdc8a58d8b9f3443b764eac60985a33ead1bcc2d17d3bdc213329"
345
+ },
346
+ "runtime/src/morph/dataset/unconditional/__init__.py": {
347
+ "bytes": 403,
348
+ "sha256": "d7cd3b85745ad1a4d884c0a11a64b3ab9cedcc64e30f604dbe83f5beb14fa97b"
349
+ },
350
+ "runtime/src/morph/dataset/unconditional/chembl3d.py": {
351
+ "bytes": 9854,
352
+ "sha256": "d5cfd1ee4ddd3085b95b9a678d761d4f0beef99ac5ecfb21d3dfb3cae59653eb"
353
+ },
354
+ "runtime/src/morph/dataset/unconditional/geom.py": {
355
+ "bytes": 4071,
356
+ "sha256": "12bc792c2a61b3e6c29ae265b9997ba610765e268408e873918b5a65225945be"
357
+ },
358
+ "runtime/src/morph/dataset/unconditional/qm9.py": {
359
+ "bytes": 9520,
360
+ "sha256": "06b6086cb1234b283cd3a45daad2e06d3bdb5d45810b873f860c82969ccbfe53"
361
+ },
362
+ "runtime/src/morph/flow_matching/__init__.py": {
363
+ "bytes": 78,
364
+ "sha256": "674f4630aa8421d7e75c913741c6efb1a163fbc38ce909c6cdb011f9ba9ef48e"
365
+ },
366
+ "runtime/src/morph/flow_matching/assignment.py": {
367
+ "bytes": 16050,
368
+ "sha256": "b6ad66538f5bd7f14e0eee2a0ffd25a4110d1504e057a0a9eb63a354d9f6aadb"
369
+ },
370
+ "runtime/src/morph/flow_matching/integration.py": {
371
+ "bytes": 33356,
372
+ "sha256": "f64b7b9ed2a79c11932b72e498e57eef924b5c85a05aa6893ddfe11e2d4595e9"
373
+ },
374
+ "runtime/src/morph/flow_matching/interpolation.py": {
375
+ "bytes": 22169,
376
+ "sha256": "6ef2e03626fd4b3194c68df6e2410ab6e630f4891f97a8328b4eb0b3e18c7dcd"
377
+ },
378
+ "runtime/src/morph/flow_matching/prior.py": {
379
+ "bytes": 2389,
380
+ "sha256": "0f9b77274238b23be7a2ad88ee8e6dcbb785817fcfa3a35aa863b489d2a6e05d"
381
+ },
382
+ "runtime/src/morph/flow_matching/sampling_step.py": {
383
+ "bytes": 2806,
384
+ "sha256": "c768682a47da1b7852838e20b39317528717fc0485cbc35030b3ca71d7d845bb"
385
+ },
386
+ "runtime/src/morph/flow_matching/schedules.py": {
387
+ "bytes": 6776,
388
+ "sha256": "6fd8396a05052ae7831babc75ca40a7e748fb9edffe82bb2559533afa949b2a9"
389
+ },
390
+ "runtime/src/morph/inference/__init__.py": {
391
+ "bytes": 732,
392
+ "sha256": "63047340b4c7ed784e969b7d54035ab737282ee2acc6eeb26ba6cb3d52b4f573"
393
+ },
394
+ "runtime/src/morph/inference/bundles.py": {
395
+ "bytes": 6395,
396
+ "sha256": "f6e2d46e6e428452a58208e78c83da01d6c786f10f7062643a093fb6750dafe6"
397
+ },
398
+ "runtime/src/morph/inference/catalog.py": {
399
+ "bytes": 6215,
400
+ "sha256": "53a27b86d39641fd4964da82f4b1875598a0cdb1533f981074c6b7a14b4174b7"
401
+ },
402
+ "runtime/src/morph/inference/generate.py": {
403
+ "bytes": 11889,
404
+ "sha256": "c3181fbf6187cf22b476431ed7c0fdea4c74ea8e97acf270f486318e43646d19"
405
+ },
406
+ "runtime/src/morph/inference/hub.py": {
407
+ "bytes": 9739,
408
+ "sha256": "fa1f43937d66f0ab4b7b9c11ed749aef8d23444b2df3257c36ff72ecd3b821ca"
409
+ },
410
+ "runtime/src/morph/inference/module.py": {
411
+ "bytes": 3820,
412
+ "sha256": "415e0f9c624c191855874b8dd88d5e7aa18941632bc403a9c0b685bbf74f1d60"
413
+ },
414
+ "runtime/src/morph/inference/registry.py": {
415
+ "bytes": 4314,
416
+ "sha256": "8ca3e4246e00707ed0d646e6e760acebd5e3d3443e5e8d5f71f3b54653993fa9"
417
+ },
418
+ "runtime/src/morph/model/README.md": {
419
+ "bytes": 10319,
420
+ "sha256": "9c06b5b90300f7449048640417116aa8869dc1a75f106cbdd9344a89f6e446d3"
421
+ },
422
+ "runtime/src/morph/model/__init__.py": {
423
+ "bytes": 80,
424
+ "sha256": "1c7c3875387d5ba7f9166a804ea5a7ef7bd469728c1ad5c5003150d44e33be51"
425
+ },
426
+ "runtime/src/morph/model/backbones/__init__.py": {
427
+ "bytes": 64,
428
+ "sha256": "a1a1419590c11aa6ed429f8b6b293470e30fe767f5571d2517b0883efb071e0c"
429
+ },
430
+ "runtime/src/morph/model/backbones/conditional_dit.py": {
431
+ "bytes": 25451,
432
+ "sha256": "411fe1d0fd17c24e03e153d57f299aa0436bc5749e2064d5574681878429795d"
433
+ },
434
+ "runtime/src/morph/model/backbones/dit.py": {
435
+ "bytes": 31262,
436
+ "sha256": "e2798baaf31bc8004a17c2432c56af9c4b12651d259cc0deaf5f18c83c6ddd33"
437
+ },
438
+ "runtime/src/morph/model/build.py": {
439
+ "bytes": 3442,
440
+ "sha256": "e69f4231815f09c094d787f11edc49e222cbdc970edc6e416b6b94a9b88d4b21"
441
+ },
442
+ "runtime/src/morph/model/finetune/__init__.py": {
443
+ "bytes": 282,
444
+ "sha256": "8746b1e29e5a3b3b1805389257270b90f5d30995783f2cf41b9fb533c485fc0c"
445
+ },
446
+ "runtime/src/morph/model/finetune/base/__init__.py": {
447
+ "bytes": 803,
448
+ "sha256": "6e0ded0b3a5c2a76ccb85b05cf63bcc54e145bd1be07d933a737d6151433d856"
449
+ },
450
+ "runtime/src/morph/model/finetune/base/conditional_backbone.py": {
451
+ "bytes": 2853,
452
+ "sha256": "1353e96443eacf3ce88473a30d02ab4f1c8b6a9c90763ea61c58d353b806b378"
453
+ },
454
+ "runtime/src/morph/model/finetune/base/context_encoder.py": {
455
+ "bytes": 15124,
456
+ "sha256": "8d5dfc91ec73120161ed0a51dcc7edac442004ad4d5213ba34d9d11cfd1eee15"
457
+ },
458
+ "runtime/src/morph/model/finetune/base/finetune_base.py": {
459
+ "bytes": 9526,
460
+ "sha256": "2efa00fd8eed1096a9cf8799dee4abfd8b27de1c0600e22a906dddaa089c4ca0"
461
+ },
462
+ "runtime/src/morph/model/finetune/scaffold/__init__.py": {
463
+ "bytes": 366,
464
+ "sha256": "6345e71c8b03ee5eb0dcd105c0532acf73a1795bf6360b2847be600bcecd40ba"
465
+ },
466
+ "runtime/src/morph/model/finetune/scaffold/scaffold.py": {
467
+ "bytes": 1984,
468
+ "sha256": "6de7a6083b4303ae422f03f15b5b40b1233d48bfc2dd1e0aa83a4eaa8adf40dd"
469
+ },
470
+ "runtime/src/morph/model/finetune/scaffold/scaffold_context.py": {
471
+ "bytes": 6086,
472
+ "sha256": "d9446254770e3c3ea2c634a0636ab82a718514a7cb69760d756e9235cfbe2814"
473
+ },
474
+ "runtime/src/morph/model/layers/__init__.py": {
475
+ "bytes": 189,
476
+ "sha256": "79671fbdea358c330a45b7fd3d842119b32b1d548804b3d441bbfb7dbd703b69"
477
+ },
478
+ "runtime/src/morph/model/layers/attention.py": {
479
+ "bytes": 21038,
480
+ "sha256": "7efc416ac8fec0236909661ad0693a0aef613ff97a964fb6d8252cb49c60b5c6"
481
+ },
482
+ "runtime/src/morph/model/layers/embedding.py": {
483
+ "bytes": 14356,
484
+ "sha256": "efe924190da5904e05495f421dcc313134cebe0dee9bf665060e1e5781cd95ef"
485
+ },
486
+ "runtime/src/morph/model/layers/gmm.py": {
487
+ "bytes": 6753,
488
+ "sha256": "628e90c73bdbb3e70104214f80bbf8a94896ddbe22a9a3fc40cce34b20d2565f"
489
+ },
490
+ "runtime/src/morph/model/layers/heads.py": {
491
+ "bytes": 30913,
492
+ "sha256": "7113c29a6be81c93ca980dc19d0847d2015ac36702683e4f1adedd549aed46ae"
493
+ },
494
+ "runtime/src/morph/model/layers/kernels.py": {
495
+ "bytes": 12483,
496
+ "sha256": "be0c52b69c7612946244755e2865de0491440a41163cf828168eb750a8f929cf"
497
+ },
498
+ "runtime/src/morph/model/layers/lora.py": {
499
+ "bytes": 5947,
500
+ "sha256": "7194750605e7b5df9a02e4c4a39cf29c982f117c40198c99c73211c85ecdfe4b"
501
+ },
502
+ "runtime/src/morph/model/lightning/__init__.py": {
503
+ "bytes": 339,
504
+ "sha256": "c53943a4eb1e45568cebfb538655cc5eb7ead46284bbcd515800102c89177e52"
505
+ },
506
+ "runtime/src/morph/model/lightning/_optimizer.py": {
507
+ "bytes": 19578,
508
+ "sha256": "f77519db8d3458c05aec1543cb4cd487995cf398abcc71b62ea1835cb132165e"
509
+ },
510
+ "runtime/src/morph/model/lightning/_sampling.py": {
511
+ "bytes": 15344,
512
+ "sha256": "2694ba5cd0b315147285ba268ed5ad246d6091d2426fcd7b21f78d0eb0a8fca1"
513
+ },
514
+ "runtime/src/morph/model/lightning/_setup.py": {
515
+ "bytes": 6537,
516
+ "sha256": "835f510094110c4dbc590a88d9b94d41474ae87b442785a949328feda5b9afce"
517
+ },
518
+ "runtime/src/morph/model/lightning/_training.py": {
519
+ "bytes": 22479,
520
+ "sha256": "0451c3c4f1ad46cc5380615a3fbf8452d1fb4a0d27d69c885a411a3612c0997c"
521
+ },
522
+ "runtime/src/morph/model/lightning/_validation.py": {
523
+ "bytes": 11509,
524
+ "sha256": "03890457e504eed96f23dd8633a6af4317a9ed61e80b3e4ec935aaf9e63038d7"
525
+ },
526
+ "runtime/src/morph/model/lightning/base.py": {
527
+ "bytes": 9294,
528
+ "sha256": "ce9159e7b387ece0a3ce010b164f675b81980d2f617b5b05d00f96695ee33e28"
529
+ },
530
+ "runtime/src/morph/model/losses/__init__.py": {
531
+ "bytes": 190,
532
+ "sha256": "bb9de5950496ed184a32e11834d8e6f3b7d406773509ffa6c406a86bb5249fae"
533
+ },
534
+ "runtime/src/morph/model/losses/functional.py": {
535
+ "bytes": 11765,
536
+ "sha256": "42ae52f604a0cb8b7fe08955cfd273945ca068727994f20b02c80cdee3a00e1b"
537
+ },
538
+ "runtime/src/morph/utils/__init__.py": {
539
+ "bytes": 78,
540
+ "sha256": "eb76ca86f046931eaea693a696317e8b3ce0b8ad8695a92e3744fd1892f2b9b8"
541
+ },
542
+ "runtime/src/morph/utils/checkpoints.py": {
543
+ "bytes": 2301,
544
+ "sha256": "750302eb039e3947a5d4c84e4e7d04eb46e974cc0031ef1d197a3573e20eae4b"
545
+ },
546
+ "runtime/src/morph/utils/edge_alignment.py": {
547
+ "bytes": 4896,
548
+ "sha256": "0edcde93cfa3a2d825e783ea5cf64715aa248e59ffb8c6a23d4490d74976a71e"
549
+ },
550
+ "runtime/src/morph/utils/graph_math.py": {
551
+ "bytes": 6755,
552
+ "sha256": "2bae326c3538d757aac66dcfc4a0b5d023b17bd987d814d3dab9a57f9ce60552"
553
+ },
554
+ "runtime/src/morph/utils/loss_accumulation.py": {
555
+ "bytes": 15115,
556
+ "sha256": "0f3eca42145e715290576dd86f4bcfb1553714ec4cabeda9246cfaf1e4f4323c"
557
+ },
558
+ "runtime/src/morph/utils/lr_schedulers.py": {
559
+ "bytes": 5554,
560
+ "sha256": "b954c12df413ca6676263ef1af960e2a4ff52692acfd4223e72a6e02122a3638"
561
+ },
562
+ "runtime/src/morph/utils/metrics/__init__.py": {
563
+ "bytes": 6730,
564
+ "sha256": "abec143d21e36343fff54db0ca8042111b9e70da426567b13ec36d6cb05696b6"
565
+ },
566
+ "runtime/src/morph/utils/metrics/chemistry.py": {
567
+ "bytes": 34152,
568
+ "sha256": "61b598b99fad41571f9334b28f94fbeeeb0282d1b80423b1f2bc8f14180884e8"
569
+ },
570
+ "runtime/src/morph/utils/metrics/distribution.py": {
571
+ "bytes": 3348,
572
+ "sha256": "0a6c25c4e65843308059a3effc44e1072837e747926074c1d7c47ba7ee72cb46"
573
+ },
574
+ "runtime/src/morph/utils/metrics/plotting.py": {
575
+ "bytes": 4270,
576
+ "sha256": "686d491d7fbc83cf35f772649a869dc1a271966d2a4fa6162d6e2334db735723"
577
+ },
578
+ "runtime/src/morph/utils/metrics/posecheck_strain.py": {
579
+ "bytes": 6695,
580
+ "sha256": "60a4751cce0e23d87d8602135de0c9850182fe97f20632cb9095445bdc6b0365"
581
+ },
582
+ "runtime/src/morph/utils/metrics/tensor.py": {
583
+ "bytes": 13503,
584
+ "sha256": "3fcb867cde5d47f81725acc3b862fc56af5ecce23dee3a11ebe6d05c1772c6fe"
585
+ },
586
+ "runtime/src/morph/utils/rdkit_utils.py": {
587
+ "bytes": 9018,
588
+ "sha256": "0fddc055c6de60893272fe8c50c92de29c9e72b7819827caac753e4cd0c6f1e5"
589
+ },
590
+ "runtime/src/morph/utils/run_config.py": {
591
+ "bytes": 8025,
592
+ "sha256": "0c289120887a051379523af528ebc9310f356f3b92efb898ddaf773dbf698aa2"
593
+ },
594
+ "runtime/src/morph/utils/vocab_utils.py": {
595
+ "bytes": 6343,
596
+ "sha256": "7b5506971b5092865b86311173b24d7fb70a881f123c57fd8696c412a25d618b"
597
+ },
598
+ "runtime/uv.lock": {
599
+ "bytes": 611263,
600
+ "sha256": "6fd6609500ea661b3b5c9f17d0997c5709295ca2cbbe16c97fc8259178fa931e"
601
+ },
602
+ "training_config.yaml": {
603
+ "bytes": 12028,
604
+ "sha256": "b95ee96def79a9602c4b635e7432d97a75a1427dc141d98c950ff38d6012ef6a"
605
+ },
606
+ "validation.json": {
607
+ "bytes": 781,
608
+ "sha256": "5b128cbe9fce32cfbdb1ebe63d62a35b50d1b391bac1c0ab4ae25e0d22fa3fdd"
609
+ }
610
+ }
qm9/explicit_h/metadata.json ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "dataset": "qm9",
3
+ "variant": "explicit_h",
4
+ "includes_explicit_hydrogens": true,
5
+ "training_run": "qm9-explicit-25ep-16529301",
6
+ "resumed_from_completed_epoch": null,
7
+ "source_snapshot": "qm9_launch_20261008",
8
+ "checkpoint_format": "Original Lightning checkpoint, current + EMA + optimizer state",
9
+ "epoch_numbering": "Completed epochs (one-based); original checkpoint epoch is zero-based",
10
+ "checkpoints": [
11
+ {
12
+ "filename": "epoch_1000.ckpt",
13
+ "original_filename": "epoch=999-step=24000.ckpt",
14
+ "completed_epochs": 1000,
15
+ "checkpoint_epoch_index": 999,
16
+ "global_step": 24000,
17
+ "bytes": 508845203,
18
+ "sha256": "144410a5d6efcb326c3dfa466bbd3ec1fb203d4278923f2ec7d8a486ef9f8f1e"
19
+ },
20
+ {
21
+ "filename": "epoch_1500.ckpt",
22
+ "original_filename": "epoch=1499-step=36000.ckpt",
23
+ "completed_epochs": 1500,
24
+ "checkpoint_epoch_index": 1499,
25
+ "global_step": 36000,
26
+ "bytes": 508845203,
27
+ "sha256": "90b418b9aa5de7cdb2109df20bc4ded1c46159b3abd10595750a5b583d0f9f87"
28
+ }
29
+ ],
30
+ "training_split_sizes": {
31
+ "train": 100000,
32
+ "validation": 20000,
33
+ "test": 12947
34
+ },
35
+ "atom_tokens": [
36
+ "C",
37
+ "F",
38
+ "H",
39
+ "N",
40
+ "O"
41
+ ],
42
+ "edge_tokens": [
43
+ "<NO_BOND>",
44
+ "1",
45
+ "2",
46
+ "3",
47
+ "4"
48
+ ],
49
+ "charge_tokens": [
50
+ "-1",
51
+ "0",
52
+ "1"
53
+ ],
54
+ "coordinate_std_angstrom": 1.373397946357727
55
+ }
qm9/explicit_h/runtime/README.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # Morph inference runtime
2
+
3
+ Archived source used for the QM9 training run.
4
+
5
+ Install with `python -m pip install .`, then use `morph models list` or `from morph.inference import load_pretrained`. See the model repository at https://huggingface.co/maltefranke/morph for checkpoint loading and generation.
qm9/explicit_h/runtime/configs/callbacks/callbacks.yaml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+
3
+ ## Put your callback args here
4
+ callbacks:
5
+ monitor_metric: ${if:${oc.eval:"'${representation}' in ('geometric_graph', 'molecule')"},val/validity,val/batch/pair_dist_l1}
6
+ monitor_metric_mode: ${if:${oc.eval:"'${representation}' in ('geometric_graph', 'molecule')"},max,min}
7
+
8
+ # model_checkpoints -> best-by-metric (top-1, monitored)
9
+ # every_n_epochs_checkpoint -> latest (no monitor; overwrites every epoch)
10
+ model_checkpoints:
11
+ save_top_k: 1
12
+ save_last: False
13
+ verbose: False
14
+
15
+ every_n_epochs_checkpoint:
16
+ every_n_epochs: 1
17
+ save_top_k: 1
18
+ save_last: False
19
+ verbose: False
20
+ save_on_train_epoch_end: True # Force per-train-epoch firing
qm9/explicit_h/runtime/configs/data/chembl3d/chembl3d.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # LoQI ChEMBL3D source format, without dataset-specific size/element filters.
2
+ defaults:
3
+ - /data/molecular@_here_
4
+ - _self_
5
+
6
+ dataset_name: chembl3d
7
+ dataset_target: morph.dataset.unconditional.chembl3d.FlowMatchingChEMBL3DDataset
8
+ source_dir: ${oc.env:CHEMBL3D_SOURCE_DIR,null}
qm9/explicit_h/runtime/configs/data/chembl3d/implicit_h.yaml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ defaults:
2
+ - /data/chembl3d/chembl3d@_here_
3
+ - _self_
4
+
5
+ hydrogen_mode: implicit
qm9/explicit_h/runtime/configs/data/chembl3d/max100.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Inclusive total-atom limit, applied before hydrogen removal.
2
+ defaults:
3
+ - /data/chembl3d/chembl3d@_here_
4
+ - _self_
5
+
6
+ max_atoms: 100
7
+ cache_name: ${data.dataset_name}_max${data.max_atoms}${if:${eq:${data.hydrogen_mode},implicit},_implicit_h,''}
qm9/explicit_h/runtime/configs/data/chembl3d/max100_implicit_h.yaml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ defaults:
2
+ - /data/chembl3d/max100@_here_
3
+ - _self_
4
+
5
+ hydrogen_mode: implicit
qm9/explicit_h/runtime/configs/data/geom/geom.yaml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GEOM-Drugs source format and default molecule subset.
2
+ defaults:
3
+ - /data/molecular@_here_
4
+ - _self_
5
+
6
+ dataset_name: geom
7
+ dataset_target: morph.dataset.unconditional.geom.FlowMatchingGEOMDataset
8
+ source_dir: ${oc.env:GEOM_SOURCE_DIR,null} # Optional prefiltered pickle directory.
9
+ # Preserve the established GEOM subset. Limits apply before hydrogen removal.
10
+ max_atoms: 72
11
+ allowed_atom_symbols: [H, C, N, O, S, F, Cl, Br, P, I]
qm9/explicit_h/runtime/configs/data/geom/implicit_h.yaml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ defaults:
2
+ - /data/geom/geom@_here_
3
+ - _self_
4
+
5
+ hydrogen_mode: implicit
qm9/explicit_h/runtime/configs/data/geom/scaffold_decoration.yaml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GEOM-Drugs data config for the **scaffold decoration** task.
2
+ #
3
+ # Mirrors configs/data/qm9/scaffold_decoration.yaml but on GEOM-Drugs: source
4
+ # is the selected scaffold of each target; target is the full molecule. The model
5
+ # learns to grow it by inserting decoration atoms around the fixed scaffold.
6
+ #
7
+ # Inherits from configs/data/geom/geom.yaml and overrides:
8
+ # - datamodule._target_ -> ScaffoldLightningDataModule
9
+ #
10
+ # The scaffold cache is built lazily into ``scaffold_groups_dir`` on first run
11
+ # (one file per split and scaffold kind) and reused afterwards.
12
+ defaults:
13
+ - /data/geom/geom@_here_
14
+ - _self_
15
+
16
+ scaffold_groups_dir: ${data.preprocessing.root}/processed/scaffold_groups
17
+ scaffold_kind: rgroup # murcko, rgroup (BRICS), heavy (generate H), linker
18
+ # Evaluate each distinct molecule/scaffold pair; training always draws randomly.
19
+ enumerate_slicings: false
20
+ datamodule:
21
+ _target_: morph.dataset.conditional.scaffold.datamodule.ScaffoldLightningDataModule
22
+ scaffold_groups_dir: ${data.scaffold_groups_dir}
23
+ scaffold_kind: ${data.scaffold_kind}
24
+ enumerate_slicings: ${data.enumerate_slicings}
qm9/explicit_h/runtime/configs/data/molecular.yaml ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Shared drug-like molecular training and preprocessing configuration.
2
+
3
+ root_path: ${oc.env:PROJECT_ROOT}/data
4
+ preprocess_workers: 10
5
+ preprocess_chunk_size: 128
6
+ statistics_workers: ${data.preprocess_workers}
7
+ hydrogen_mode: explicit
8
+ # The mode is part of the cache path; changing it discovers fresh vocab/statistics.
9
+ cache_name: ${data.dataset_name}${if:${eq:${data.hydrogen_mode},implicit},_implicit_h,''}
10
+ source_dir: null
11
+ max_atoms: null
12
+ allowed_atom_symbols: null
13
+
14
+ n_atoms_strategy: "uniform" # "approx", "empirical", "learned"
15
+ # Uniform source-count support padding; explicit so inference and training can
16
+ # be matched or ablated without code changes.
17
+ uniform_n_atoms_padding: 5
18
+ optimal_transport: "equivariant"
19
+ # Physical Angstroms (converted to normalized coordinates internally). These
20
+ # reproduce the former normalized 0.25 / 0.2 scales at GEOM's training-set std.
21
+ # Physical Angstroms. Insertion bridge noise vanishes as (1-t); move noise is
22
+ # the persistent training-time jitter floor for matched atoms and insertions
23
+ # that are already present.
24
+ ins_noise_scale: 0.65
25
+ move_noise_scale: 0.5
26
+
27
+ # Drug-like datasets contain charged species; allow them in validity metrics.
28
+ allow_charged: true
29
+
30
+
31
+ # Preprocessing configuration - computes tokens from data and distributions from training dataset only
32
+ preprocessing:
33
+ _target_: morph.dataset.core.preprocessing.Preprocessing
34
+ _recursive_: false
35
+ root: ${data.root_path}/${data.cache_name}
36
+ num_workers: ${data.statistics_workers}
37
+ train_dataset: ${data.datamodule.datasets.train}
38
+ atom_tokens_path: ${data.preprocessing.root}/processed/atom_tokens.txt
39
+ edge_tokens_path: ${data.preprocessing.root}/processed/edge_tokens.txt
40
+ charge_tokens_path: ${data.preprocessing.root}/processed/charge_tokens.txt
41
+ distributions_path: ${data.preprocessing.root}/processed/distributions.pt
42
+ # Tokens and distributions will be discovered from data and saved to files
43
+ # On subsequent runs, they will be loaded from the files
44
+
45
+ vocab: null
46
+
47
+ interpolator:
48
+ _target_: morph.flow_matching.interpolation.Interpolator
49
+ distributions: null
50
+ optimal_transport: ${data.optimal_transport}
51
+ ins_noise_scale: ${data.ins_noise_scale}
52
+ move_noise_scale: ${data.move_noise_scale}
53
+ # Training-only categorical corruption; pairs are scaled per molecule to
54
+ # match the expected number of changed atoms. Clean targets stay unchanged.
55
+ atom_type_noise_prob: 0.0
56
+ # OT matching (cost always squared-Euclidean; move cost in Angstrom). c_move
57
+ # scales the squared move distance (A^2); c_ins/c_del/c_sub are fixed A^2 costs,
58
+ # directly comparable. At 6.125 each, delete+insert costs 3.5^2, so atoms
59
+ # farther than 3.5 A apart are left unmatched by default.
60
+ pre_align_iters: 2 # equivariant-OT inner loop (Hungarian+Kabsch) iters
61
+ c_move: 1.0
62
+ c_sub: 0.0
63
+ c_ins: 6.125
64
+ c_del: 6.125
65
+ del_schedule: ${schedule}
66
+ ins_schedule: ${schedule}
67
+ sub_schedule:
68
+ _target_: morph.flow_matching.schedules.SmoothstepSchedule
69
+ shift: 1.5
70
+ sub_e_schedule:
71
+ _target_: morph.flow_matching.schedules.SmoothstepSchedule
72
+ shift: 1.5
73
+
74
+ datamodule:
75
+ _target_: morph.dataset.core.lightning_datamodule.LightningDataModule
76
+ # tokens and distributions will be passed from preprocessing in run.py
77
+
78
+ vocab: ${data.vocab}
79
+ distributions: null
80
+ representation: ${representation}
81
+
82
+ datasets:
83
+ train:
84
+ _target_: ${data.dataset_target}
85
+ root: ${data.preprocessing.root}
86
+ preprocess_workers: ${data.preprocess_workers}
87
+ preprocess_chunk_size: ${data.preprocess_chunk_size}
88
+ hydrogen_mode: ${data.hydrogen_mode}
89
+ source_dir: ${data.source_dir}
90
+ max_atoms: ${data.max_atoms}
91
+ allowed_atom_symbols: ${data.allowed_atom_symbols}
92
+ vocab: ${data.vocab}
93
+ distributions: null
94
+
95
+ val:
96
+ - _target_: ${data.dataset_target}
97
+ root: ${data.preprocessing.root}
98
+ preprocess_workers: ${data.preprocess_workers}
99
+ preprocess_chunk_size: ${data.preprocess_chunk_size}
100
+ hydrogen_mode: ${data.hydrogen_mode}
101
+ source_dir: ${data.source_dir}
102
+ max_atoms: ${data.max_atoms}
103
+ allowed_atom_symbols: ${data.allowed_atom_symbols}
104
+ vocab: ${data.vocab}
105
+ distributions: null
106
+
107
+ test:
108
+ - _target_: ${data.dataset_target}
109
+ root: ${data.preprocessing.root}
110
+ preprocess_workers: ${data.preprocess_workers}
111
+ preprocess_chunk_size: ${data.preprocess_chunk_size}
112
+ hydrogen_mode: ${data.hydrogen_mode}
113
+ source_dir: ${data.source_dir}
114
+ max_atoms: ${data.max_atoms}
115
+ allowed_atom_symbols: ${data.allowed_atom_symbols}
116
+ vocab: ${data.vocab}
117
+ distributions: null
118
+
119
+ interpolator: ${data.interpolator}
120
+
121
+ rotate: ${model.rotate}
122
+ n_augmentations: ${model.n_augmentations}
123
+
124
+ num_workers:
125
+ train: 10
126
+ val: 0
127
+ test: 0
128
+
129
+ batch_size:
130
+ train: 320
131
+ val: 128
132
+ test: 64
133
+
134
+ n_atoms_strategy: ${data.n_atoms_strategy}
135
+ uniform_n_atoms_padding: ${data.uniform_n_atoms_padding}
136
+ time_dist: ${model.module.time_dist}
qm9/explicit_h/runtime/configs/data/qm9/qm9.yaml ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## QM9 data and preprocessing configuration.
2
+
3
+ dataset_name: qm9
4
+ root_path: ${oc.env:PROJECT_ROOT}/data
5
+ preprocess_workers: 0
6
+
7
+ n_atoms_strategy: "uniform" # "approx", "empirical", "learned"
8
+ # Expand both ends of the empirical count support for the uniform flow source.
9
+ # QM9's minimum is already the hard lower bound of 3, so positive padding is
10
+ # necessarily asymmetric; set to 0 for an unpadded 3--29 diagnostic prior.
11
+ uniform_n_atoms_padding: 5
12
+ optimal_transport: "equivariant"
13
+ # Physical Angstroms (converted to normalized coordinates internally). Insertion
14
+ # bridge noise vanishes as (1-t); move noise is the persistent training-time
15
+ # jitter floor for matched atoms and insertions that are already present.
16
+ ins_noise_scale: 0.35
17
+ move_noise_scale: 0.3
18
+
19
+ # QM9 contains only neutral molecules; charged species are treated as invalid.
20
+ allow_charged: false
21
+
22
+
23
+ # Preprocessing configuration - computes tokens from data and distributions from training dataset only
24
+ preprocessing:
25
+ _target_: morph.dataset.core.preprocessing.Preprocessing
26
+ _recursive_: false
27
+ root: ${data.root_path}/qm9
28
+ train_dataset: ${data.datamodule.datasets.train}
29
+ # Canonical (representation-agnostic) cache. One preprocessing per dataset;
30
+ # representation-specific projection happens at runtime in the wrapper.
31
+ atom_tokens_path: ${data.preprocessing.root}/processed/atom_tokens.txt
32
+ edge_tokens_path: ${data.preprocessing.root}/processed/edge_tokens.txt
33
+ charge_tokens_path: ${data.preprocessing.root}/processed/charge_tokens.txt
34
+ distributions_path: ${data.preprocessing.root}/processed/distributions.pt
35
+
36
+ vocab: None
37
+
38
+ interpolator:
39
+ _target_: morph.flow_matching.interpolation.Interpolator
40
+ distributions: None
41
+ optimal_transport: ${data.optimal_transport}
42
+ ins_noise_scale: ${data.ins_noise_scale}
43
+ move_noise_scale: ${data.move_noise_scale}
44
+ # OT matching (cost always squared-Euclidean; move cost in Angstrom). c_move
45
+ # scales the squared move distance (A^2); c_ins/c_del/c_sub are fixed A^2 costs,
46
+ # directly comparable. At 6.125 each, delete+insert costs 3.5^2, so atoms
47
+ # farther than 3.5 A apart are left unmatched by default.
48
+ pre_align_iters: 2 # equivariant-OT inner loop (Hungarian+Kabsch) iters
49
+ c_move: 1.0
50
+ c_sub: 0.0
51
+ c_ins: 6.125
52
+ c_del: 6.125
53
+ del_schedule: ${schedule}
54
+ ins_schedule: ${schedule}
55
+ sub_schedule:
56
+ _target_: morph.flow_matching.schedules.SmoothstepSchedule
57
+ shift: 1.5
58
+ sub_e_schedule:
59
+ _target_: morph.flow_matching.schedules.SmoothstepSchedule
60
+ shift: 1.5
61
+
62
+ datamodule:
63
+ _target_: morph.dataset.core.lightning_datamodule.LightningDataModule
64
+ # tokens and distributions will be passed from preprocessing in run.py
65
+
66
+ vocab: ${data.vocab}
67
+ distributions: None
68
+ representation: ${representation}
69
+
70
+ datasets:
71
+ train:
72
+ _target_: morph.dataset.unconditional.qm9.FlowMatchingQM9Dataset
73
+ root: ${data.root_path}/qm9
74
+ vocab: ${data.vocab}
75
+ distributions: None
76
+
77
+ val:
78
+ - _target_: morph.dataset.unconditional.qm9.FlowMatchingQM9Dataset
79
+ root: ${data.root_path}/qm9
80
+ vocab: ${data.vocab}
81
+ distributions: None
82
+
83
+ test:
84
+ - _target_: morph.dataset.unconditional.qm9.FlowMatchingQM9Dataset
85
+ root: ${data.root_path}/qm9
86
+ vocab: ${data.vocab}
87
+ distributions: None
88
+
89
+ interpolator: ${data.interpolator}
90
+
91
+ rotate: ${model.rotate}
92
+ n_augmentations: ${model.n_augmentations}
93
+
94
+ num_workers:
95
+ train: 10
96
+ val: 0
97
+ test: 0
98
+
99
+ batch_size:
100
+ train: 1024
101
+ val: 128
102
+ test: 32
103
+
104
+ n_atoms_strategy: ${data.n_atoms_strategy}
105
+ uniform_n_atoms_padding: ${data.uniform_n_atoms_padding}
106
+ time_dist: ${model.module.time_dist}
qm9/explicit_h/runtime/configs/data/qm9/scaffold_decoration.yaml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # QM9 data config for the **scaffold decoration** task.
2
+ #
3
+ # Source is the selected scaffold of each target; target is the full molecule.
4
+ # The model learns to grow the molecule by inserting decoration atoms
5
+ # around the fixed scaffold.
6
+ #
7
+ # Inherits from configs/data/qm9/qm9.yaml and overrides:
8
+ # - datamodule._target_ → ScaffoldLightningDataModule
9
+ #
10
+ defaults:
11
+ - /data/qm9/qm9@_here_
12
+ - _self_
13
+
14
+ scaffold_groups_dir: ${data.root_path}/qm9/processed/scaffold_groups
15
+ scaffold_kind: rgroup # murcko, rgroup (BRICS), heavy (generate H), linker
16
+ # Evaluate each distinct molecule/scaffold pair; training always draws randomly.
17
+ enumerate_slicings: false
18
+ datamodule:
19
+ _target_: morph.dataset.conditional.scaffold.datamodule.ScaffoldLightningDataModule
20
+ scaffold_groups_dir: ${data.scaffold_groups_dir}
21
+ scaffold_kind: ${data.scaffold_kind}
22
+ enumerate_slicings: ${data.enumerate_slicings}
qm9/explicit_h/runtime/configs/default.yaml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defaults:
2
+ - _self_
3
+ # Single-knob presets bundle
4
+ # `data` + `embeddings` (with dataset-tuned ExtrapolatableCount params)
5
+ # plus the shared `core` group selections. Override individual groups as
6
+ # usual, e.g. `defaults=geom/geom model=backbones/dit embeddings=qm9`.
7
+ - defaults: qm9/qm9
8
+
9
+ # What the model trains on. Datasets declare their CAPABILITIES; run.py validates
10
+ # the requested mode against them before preprocessing.
11
+ # pointcloud — x, a only (charges and edges are dummy singletons)
12
+ # charged_pointcloud — x, a, c (edges are dummy singletons)
13
+ # geometric_graph — x, a, edge_index, e (charges are dummy neutral)
14
+ # molecule — full chemistry (current behavior)
15
+ representation: molecule
16
+ seed: 42
17
+
18
+ # Run directory: <root>/<dataset>/<cfg_method>/<date>/<wandb_id>. Root is
19
+ # MORPH_RUN_ROOT (scratch, set in .env) so every run's outputs/checkpoints/wandb
20
+ # land off-repo; falls back to <cwd>/outputs for ad-hoc runs with no env set.
21
+ # wandb id is MORPH_RUN_ID (same as WANDB_RUN_ID). Set in the shell before
22
+ # torchrun, or set automatically for single-process runs in run.py before Hydra composes.
23
+ hydra:
24
+ run:
25
+ dir: ${oc.env:MORPH_RUN_ROOT,${hydra:runtime.cwd}/outputs}/${hydra:runtime.choices.data}/${now:%Y-%m-%d}/${oc.env:MORPH_RUN_ID}
qm9/explicit_h/runtime/configs/defaults/chembl3d/chembl3d.yaml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - core
4
+ - /data: chembl3d/chembl3d
5
+ - /embeddings: geom
qm9/explicit_h/runtime/configs/defaults/chembl3d/implicit_h.yaml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - /defaults/core
4
+ - /data: chembl3d/implicit_h
5
+ - /embeddings: geom
qm9/explicit_h/runtime/configs/defaults/chembl3d/implicit_h_2x4090.yaml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - /defaults/chembl3d/train_2x4090
4
+ - override /data: chembl3d/max100_implicit_h
5
+ - _self_
6
+
7
+ # Train from scratch: the atom vocabulary/statistics differ from the H model.
8
+ # Preserve global batch 640, eval every epoch, both checkpoint callbacks every 5.
9
+ logging:
10
+ project: morph-chembl3d-implicit-h
qm9/explicit_h/runtime/configs/defaults/chembl3d/train_2x4090.yaml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - /defaults/core
4
+ - /data: chembl3d/max100
5
+ - /embeddings: geom
6
+ - _self_
7
+
8
+ # Profiled on max100 ChEMBL: 2 GPUs * 320 * 1 = 640 effective global batch.
9
+ data:
10
+ datamodule:
11
+ train_prefetch_factor: 1
12
+ batch_size:
13
+ train: 320
14
+ val: 32
15
+ test: 32
16
+ num_workers:
17
+ train: 20
18
+ val: 2
19
+ test: 2
20
+
21
+ trainer:
22
+ trainer:
23
+ accelerator: gpu
24
+ devices: 2
25
+ accumulate_grad_batches: 1
26
+ max_epochs: -1
27
+ check_val_every_n_epoch: 1
28
+ num_val_samples: 4096
29
+ # Validation runs during fit; leave wall-clock headroom for final checkpointing.
30
+ do_validate: false
31
+ do_predict: false
32
+ final_checkpoint_path: final.ckpt
33
+
34
+ callbacks:
35
+ model_checkpoints:
36
+ every_n_epochs: 5
37
+ every_n_epochs_checkpoint:
38
+ every_n_epochs: 5
39
+ save_top_k: -1
40
+ save_last: link
qm9/explicit_h/runtime/configs/defaults/core.yaml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ # Shared default groups that don't change between QM9 / GEOM runs.
3
+ # Dataset-specific presets (defaults/qm9/qm9.yaml, defaults/geom/geom.yaml) inherit
4
+ # from this and only add `data` + `embeddings`.
5
+ defaults:
6
+ - /heads: head
7
+ - /insertion_head: unimodal
8
+ - /model: backbones/dit
9
+ - /schedule: smoothstep
10
+ - /trainer: trainer
11
+ - /callbacks: callbacks
12
+ - /logging: wandb_logger
13
+ - /integrator: integrator
qm9/explicit_h/runtime/configs/defaults/geom/geom.yaml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ # GEOM preset: shared core + GEOM data and embeddings.
3
+ defaults:
4
+ - core
5
+ - /data: geom/geom
6
+ - /embeddings: geom
7
+ - _self_
8
+
9
+ # Evaluate every epoch; keep every fifth completed epoch for releases/resuming.
10
+ trainer:
11
+ trainer:
12
+ check_val_every_n_epoch: 1
13
+
14
+ callbacks:
15
+ model_checkpoints:
16
+ every_n_epochs: 5
17
+ every_n_epochs_checkpoint:
18
+ every_n_epochs: 5
19
+ save_top_k: -1
20
+ save_last: link
qm9/explicit_h/runtime/configs/defaults/geom/implicit_h.yaml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - /defaults/core
4
+ - /data: geom/implicit_h
5
+ - /embeddings: geom
qm9/explicit_h/runtime/configs/defaults/geom/scaffold_decoration.yaml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ # GEOM-Drugs **scaffold decoration** fine-tune preset.
3
+ #
4
+ # Mirrors defaults/qm9/scaffold_decoration.yaml on GEOM-Drugs. Bare-scaffold
5
+ # source -> full-molecule target: the model learns to grow a molecule by
6
+ # inserting decoration atoms around the fixed scaffold.
7
+ #
8
+ # Differences from the QM9 scaffold preset:
9
+ # - data -> geom/scaffold_decoration (GEOM base datasets)
10
+ # - embeddings -> geom
11
+ #
12
+ # Reuses the scaffold_finetune model config (loads the pretrained unconditional
13
+ # DiT into the clean lane + adds the node/edge conditioning and the gated
14
+ # cross-attn blocks).
15
+ #
16
+ # Pair with a GEOM unconditional DiT checkpoint via
17
+ # ``model.module.pretrained_ckpt=...``.
18
+ defaults:
19
+ - core
20
+ - /data: geom/scaffold_decoration
21
+ - /embeddings: geom
22
+ - override /model: finetune/scaffold_finetune
23
+ - _self_
qm9/explicit_h/runtime/configs/defaults/qm9/qm9.yaml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ # QM9 preset: shared core + QM9 data and embeddings.
3
+ defaults:
4
+ - /defaults/core
5
+ - /data: qm9/qm9
6
+ - /embeddings: qm9
7
+ - _self_
8
+
9
+ trainer:
10
+ trainer:
11
+ check_val_every_n_epoch: 1
12
+
13
+ # Keep the full 25-epoch checkpoint history for model releases and resuming.
14
+ callbacks:
15
+ model_checkpoints:
16
+ every_n_epochs: 25
17
+ every_n_epochs_checkpoint:
18
+ every_n_epochs: 25
19
+ save_top_k: -1
20
+ save_last: link
qm9/explicit_h/runtime/configs/defaults/qm9/scaffold_decoration.yaml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ # QM9 **scaffold decoration** fine-tune preset.
3
+ #
4
+ # Bare-scaffold source → full-molecule target. The model learns to grow
5
+ # a molecule by inserting decoration atoms around the fixed scaffold.
6
+ defaults:
7
+ - core
8
+ - /data: qm9/scaffold_decoration
9
+ - /embeddings: qm9
10
+ - override /model: finetune/scaffold_finetune
11
+ - _self_
qm9/explicit_h/runtime/configs/defaults/qm9/train_2x4090.yaml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - /defaults/qm9/qm9
4
+ - _self_
5
+
6
+ # Preserve the established QM9 effective batch: 2 GPUs * 1024 * 2 = 4096.
7
+ data:
8
+ datamodule:
9
+ train_prefetch_factor: 1
10
+ batch_size:
11
+ train: 1024
12
+ val: 128
13
+ test: 32
14
+ num_workers:
15
+ train: 20
16
+ val: 2
17
+ test: 2
18
+
19
+ trainer:
20
+ trainer:
21
+ accelerator: gpu
22
+ devices: 2
23
+ accumulate_grad_batches: 2
24
+ max_epochs: 3000
25
+ check_val_every_n_epoch: 1
26
+ num_val_samples: 4096
27
+ do_validate: false
28
+ do_predict: false
29
+ final_checkpoint_path: final.ckpt
qm9/explicit_h/runtime/configs/embeddings/geom.yaml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Shared embedding stack tuned for GEOM-Drugs.
2
+ # - node_count_embedding uses ExtrapolatableCountEmbedding with periods/max_count
3
+ # scaled up for the much larger atom counts in GEOM-Drugs.
4
+
5
+ atom_type_embedding:
6
+ _target_: morph.model.layers.embedding.Embedding
7
+ num_embeddings: ${len:${data.vocab.atom_tokens}}
8
+ embedding_dim: 64
9
+ out_dim: 128
10
+
11
+ edge_type_embedding:
12
+ _target_: morph.model.layers.embedding.Embedding
13
+ num_embeddings: ${len:${data.vocab.edge_tokens}}
14
+ embedding_dim: 64
15
+ out_dim: 128
16
+
17
+ time_embedding:
18
+ _target_: morph.model.layers.embedding.TimeEmbedding
19
+ embedding_dim: 128
20
+ out_dim: 128
21
+
22
+ node_count_embedding:
23
+ _target_: morph.model.layers.embedding.ExtrapolatableCountEmbedding
24
+ embedding_dim: 64
25
+ out_dim: 128
26
+ min_period: 128.0
27
+ max_period: 1024.0
28
+ max_count: 96.0
qm9/explicit_h/runtime/configs/embeddings/qm9.yaml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Shared embedding stack tuned for QM9.
2
+ # - node_count_embedding uses ExtrapolatableCountEmbedding so the model can
3
+ # generalise slightly outside the training atom-count support.
4
+ # - Defaults sized for QM9 (training counts in [3, 29]).
5
+
6
+ atom_type_embedding:
7
+ _target_: morph.model.layers.embedding.Embedding
8
+ num_embeddings: ${len:${data.vocab.atom_tokens}}
9
+ embedding_dim: 64
10
+ out_dim: 128
11
+
12
+ edge_type_embedding:
13
+ _target_: morph.model.layers.embedding.Embedding
14
+ num_embeddings: ${len:${data.vocab.edge_tokens}}
15
+ embedding_dim: 64
16
+ out_dim: 128
17
+
18
+ time_embedding:
19
+ _target_: morph.model.layers.embedding.TimeEmbedding
20
+ embedding_dim: 128
21
+ out_dim: 128
22
+
23
+ node_count_embedding:
24
+ _target_: morph.model.layers.embedding.ExtrapolatableCountEmbedding
25
+ embedding_dim: 64
26
+ out_dim: 128
27
+ min_period: 64.0
28
+ max_period: 512.0
29
+ max_count: 32.0
qm9/explicit_h/runtime/configs/heads/head.yaml ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Standard molecular DiT readouts. The insertion-content head is an independent
2
+ # Hydra choice (``insertion_head=unimodal`` by default, or ``=gmm``).
3
+
4
+ heads:
5
+ _target_: morph.model.layers.heads.MultiHeadModule
6
+ output_init_std: ${model.head_initialization.output_std}
7
+ independent_adapters: ${oc.select:model.head_independent_adapters,false}
8
+
9
+ heads_configs:
10
+ graph_aggregation: mean
11
+
12
+ node_heads:
13
+ atom_type_head:
14
+ input_dim: ${model.head_node_dim}
15
+ output_dim: ${len:${data.vocab.atom_tokens}}
16
+ adapter_dim: ${model.head_node_adapter_dim}
17
+ group: state
18
+
19
+ charge_head:
20
+ input_dim: ${model.head_node_dim}
21
+ output_dim: ${len:${data.vocab.charge_tokens}}
22
+ adapter_dim: ${model.head_node_adapter_dim}
23
+ group: state
24
+
25
+ ins_rate_head:
26
+ input_dim: ${model.head_node_dim}
27
+ output_dim: 1
28
+ adapter_dim: ${model.head_node_adapter_dim}
29
+ group: edit
30
+ initial_rate: ${model.head_initialization.ins_rate}
31
+
32
+ do_del_head:
33
+ input_dim: ${model.head_node_dim}
34
+ output_dim: 1
35
+ adapter_dim: ${model.head_node_adapter_dim}
36
+ group: edit
37
+ initial_probability: ${model.head_initialization.do_del_probability}
38
+
39
+ do_sub_a_head:
40
+ input_dim: ${model.head_node_dim}
41
+ output_dim: 1
42
+ adapter_dim: ${model.head_node_adapter_dim}
43
+ group: edit
44
+ initial_probability: ${model.head_initialization.do_sub_a_probability}
45
+
46
+ edge_heads:
47
+ edge_type_head:
48
+ input_dim: ${model.head_edge_dim}
49
+ output_dim: ${len:${data.vocab.edge_tokens}}
50
+ adapter_dim: ${model.head_edge_adapter_dim}
51
+ group: state
52
+
53
+ do_sub_e_head:
54
+ input_dim: ${model.head_edge_dim}
55
+ output_dim: 1
56
+ adapter_dim: ${model.head_edge_adapter_dim}
57
+ group: state
58
+ initial_probability: ${model.head_initialization.do_sub_e_probability}
59
+
60
+ ins_edge_head:
61
+ _target_: morph.model.layers.heads.InsertionEdgeHead
62
+ _recursive_: false
63
+ hidden_dim: ${model.head_node_dim}
64
+ readout_dim: ${model.head_insertion_edge_dim}
65
+ output_init_std: ${model.head_initialization.output_std}
66
+ n_edge_types: ${len:${data.vocab.edge_tokens}}
67
+ n_atom_types: ${len:${data.vocab.atom_tokens}}
68
+ n_charge_types: ${len:${data.vocab.charge_tokens}}
69
+ rbf_embedding_args:
70
+ _target_: morph.model.layers.embedding.RBFEmbedding
71
+ num_rbf: 128
72
+ rbf_dmax: 3.5
73
+ out_dim: 64
74
+ dropout: 0.0
75
+ trainable: false
qm9/explicit_h/runtime/configs/insertion_head/gmm.yaml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Optional mixture-density insertion-content head.
2
+ mode: gmm
3
+ dimension: 3
4
+ num_components: 10
5
+
6
+ model:
7
+ _target_: morph.model.layers.heads.GMMInsertionHead
8
+ hidden_dim: ${model.head_node_dim}
9
+ readout_dim: ${model.head_insertion_adapter_dim}
10
+ output_init_std: ${model.head_initialization.output_std}
11
+ num_components: ${insertion_head.num_components}
12
+ sigma_min: 0.05
13
+ sigma_max: 2.0
14
+ sigma_init: 0.5
15
+ N_a: ${len:${data.vocab.atom_tokens}}
16
+ N_c: ${len:${data.vocab.charge_tokens}}
qm9/explicit_h/runtime/configs/insertion_head/unimodal.yaml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Default insertion-content head: one nearest pending atom per spawning node.
2
+ mode: unimodal
3
+ dimension: 3
4
+ num_components: 1
5
+
6
+ model:
7
+ _target_: morph.model.layers.heads.UnimodalInsertionHead
8
+ hidden_dim: ${model.head_node_dim}
9
+ readout_dim: ${model.head_insertion_adapter_dim}
10
+ output_init_std: ${model.head_initialization.output_std}
11
+ independent_adapters: ${oc.select:model.head_independent_adapters,false}
12
+ N_a: ${len:${data.vocab.atom_tokens}}
13
+ N_c: ${len:${data.vocab.charge_tokens}}
qm9/explicit_h/runtime/configs/integrator/integrator.yaml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ integrator:
2
+ _target_: morph.flow_matching.integration.RateIntegrator
3
+ vocab: ${data.vocab}
4
+ distributions: None
5
+ insertion_head_mode: ${insertion_head.mode}
6
+ insertion_dimension: ${insertion_head.dimension}
7
+ insertion_num_components: ${insertion_head.num_components}
8
+ # strategy used for sampling time during **integration**
9
+ # NOTE can be different from the time strategy used for the model (see below)
10
+ time_strategy: log # "linear", "log", or "beta"
11
+ # shape params for time_strategy: beta (Beta inverse-CDF spacing).
12
+ # defaults match the model's beta_sched (concentration1=2.0, concentration0=1.0)
13
+ time_beta_alpha: 2.0
14
+ time_beta_beta: 1.0
15
+ num_integration_steps: 100
16
+ ins_noise_scale: ${data.ins_noise_scale}
17
+ # When true, freshly-inserted nodes are pushed to the t+dt marginal (kappa-mix
18
+ # on atom/bond types, (1-t)*ins_noise on x) to match training. Charge remains
19
+ # a clean prediction target rather than an interpolated state. When false,
20
+ # insertions enter at the model's clean prediction.
21
+ renoise_insertions: true
22
+ # Integrate the known categorical schedule hazard over every time interval
23
+ # instead of using its left-endpoint Euler approximation.
24
+ # With either method, the final interval always completes pending discrete
25
+ # transitions using the learned edit probabilities (no extra model call).
26
+ exact_schedule_integration: true
27
+ del_schedule: ${data.interpolator.del_schedule}
28
+ ins_schedule: ${data.interpolator.ins_schedule}
29
+ sub_schedule: ${data.interpolator.sub_schedule}
30
+ sub_e_schedule: ${data.interpolator.sub_e_schedule}
qm9/explicit_h/runtime/configs/logging/wandb_logger.yaml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ ## Put your model args here
2
+ enabled: true
3
+ project: morph-${data.dataset_name}
4
+ name: ${oc.env:MORPH_RUN_ID,base}
5
+ save_dir: .
6
+ offline: false
qm9/explicit_h/runtime/configs/loss_weights/calibrated_geom.yaml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package model.module.loss_weights
2
+ # Balance-only (geometric-mean=1) calibration weights, scaled down by a global
3
+ # factor of 0.2 (1/5). At the original geometric-mean=1 scale the realized
4
+ # full-model grad-norm was ~5, far above gradient_clip_val=1.0, so clipping
5
+ # fired on every step. The 0.2 factor brings the realized norm to ~1.0 so the
6
+ # clip becomes a spike safety-valve again. Re-running calibration now applies
7
+ # this scaling automatically (see trainer.target_total_grad_norm).
8
+ c: 0.164
9
+ do_del: 0.20
10
+ do_sub_a: 0.30
11
+ do_sub_e: 0.24
12
+ ins_e: 0.21
13
+ ins_e_ii: 0.22
14
+ ins_state: 0.14
15
+ ins_rate: 0.20
16
+ sub_a_class: 0.15
17
+ sub_e_class: 0.19
18
+ x: 0.22
qm9/explicit_h/runtime/configs/loss_weights/calibrated_geom_frozen.yaml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package model.module.loss_weights
2
+ # Balance-only (geometric-mean = 1) loss weights — ratios only. The learning
3
+ # rate owns step size and gradient_clip_val stays a pure spike catch, so these
4
+ # are NOT scaled to a target grad-norm (unlike the older calibrated_geom.yaml,
5
+ # which baked in a ~0.2 global scale to hit the clip target).
6
+ #
7
+ # Source: frozen init-state calibration (trainer.calibrate_mode=loss,
8
+ # calibrate_freeze_model=true), geom / DiT / uncond,
9
+ # run 2026-06-07 (outputs/geom/uncond/cal_then_lr/2026-06-07_12-29-25/calibrate).
10
+ # Because the model is held at init, every probe batch is an unbiased snapshot of
11
+ # the initial per-term losses — so the three binary do_* losses come out equal
12
+ # (all BCE at p=0.5 = ln2), unlike the previous 2500-step *training* probe
13
+ # (calibrated_geom.yaml) which gave them different weights purely from differing
14
+ # training rates. See notebooks/lr_calibration_analysis.ipynb for the comparison.
15
+ c: 0.745146
16
+ do_del: 1.730107
17
+ do_sub_a: 1.730107
18
+ do_sub_e: 1.730106
19
+ ins_e: 0.867232
20
+ ins_e_ii: 0.867232
21
+ ins_state: 0.519379
22
+ ins_rate: 1.128104
23
+ sub_a_class: 0.522109
24
+ sub_e_class: 0.867232
25
+ x: 1.298792
qm9/explicit_h/runtime/configs/loss_weights/tuned_weights.yaml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package model.module.loss_weights
2
+ # Canonical tuned weights for molecular training. Backbones can select this
3
+ # preset explicitly, and task-specific experiments may override the group. The
4
+ # package directive mounts the values under model.module.loss_weights.
5
+ do_sub_a: 0.2
6
+ sub_a_class: 0.03
7
+ do_sub_e: 0.25
8
+ sub_e_class: 0.5
9
+ do_del: 0.4
10
+ ins_rate: 0.15
11
+ ins_state: 0.01
12
+ ins_e: 0.4
13
+ x: 2.0 # was 1.0
14
+ c: 0.5
15
+ ins_e_ii: 0.03