Release GEOM scaffold substituent LoRA rank-16 checkpoint after 25 epochs
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- geom/scaffold_murcko_substituent_lora_r16/README.md +40 -0
- geom/scaffold_murcko_substituent_lora_r16/atom_tokens.txt +10 -0
- geom/scaffold_murcko_substituent_lora_r16/charge_tokens.txt +5 -0
- geom/scaffold_murcko_substituent_lora_r16/config.yaml +461 -0
- geom/scaffold_murcko_substituent_lora_r16/distributions.json +0 -0
- geom/scaffold_murcko_substituent_lora_r16/distributions.pt +3 -0
- geom/scaffold_murcko_substituent_lora_r16/edge_tokens.txt +4 -0
- geom/scaffold_murcko_substituent_lora_r16/epoch_025.ckpt +3 -0
- geom/scaffold_murcko_substituent_lora_r16/evaluate.py +221 -0
- geom/scaffold_murcko_substituent_lora_r16/manifest.json +750 -0
- geom/scaffold_murcko_substituent_lora_r16/metadata.json +41 -0
- geom/scaffold_murcko_substituent_lora_r16/panels/test_murcko_512_seed42.json +0 -0
- geom/scaffold_murcko_substituent_lora_r16/panels/val_murcko_512_seed42.json +0 -0
- geom/scaffold_murcko_substituent_lora_r16/panels/verification.json +10 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/README.md +202 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/callbacks/callbacks.yaml +20 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/chembl3d/chembl3d.yaml +8 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/chembl3d/implicit_h.yaml +5 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/chembl3d/max100.yaml +7 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/chembl3d/max100_implicit_h.yaml +5 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/crossdocked/finetune.yaml +67 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/crossdocked/scaffold_decoration.yaml +31 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/geom/geom.yaml +11 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/geom/implicit_h.yaml +5 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/geom/scaffold_decoration.yaml +38 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/molecular.yaml +136 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/qm9/qm9.yaml +106 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/qm9/scaffold_decoration.yaml +32 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/default.yaml +25 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/chembl3d/chembl3d.yaml +5 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/chembl3d/implicit_h.yaml +5 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/chembl3d/implicit_h_2x4090.yaml +10 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/chembl3d/train_2x4090.yaml +40 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/core.yaml +13 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/crossdocked/finetune.yaml +16 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/crossdocked/scaffold_decoration.yaml +9 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/crossdocked/scaffold_decoration_2x4090.yaml +51 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/geom/geom.yaml +20 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/geom/implicit_h.yaml +5 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/geom/scaffold_decoration.yaml +39 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/geom/scaffold_decoration_2x4090.yaml +27 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/geom/scaffold_decoration_scratch_2x4090.yaml +44 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/qm9/qm9.yaml +20 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/qm9/scaffold_decoration.yaml +27 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/qm9/train_2x4090.yaml +29 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/embeddings/geom.yaml +28 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/embeddings/qm9.yaml +29 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/heads/head.yaml +75 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/insertion_head/gmm.yaml +16 -0
- geom/scaffold_murcko_substituent_lora_r16/runtime/configs/insertion_head/unimodal.yaml +13 -0
geom/scaffold_murcko_substituent_lora_r16/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# GEOM scaffold decoration: 25 completed fine-tuning epochs
|
| 2 |
+
|
| 3 |
+
This is the original checkpoint from the latest GEOM Murcko scaffold fine-tuning run,
|
| 4 |
+
with rank-16 LoRA, trainable output heads, and substituent-constrained insertion
|
| 5 |
+
supervision. It starts from GEOM explicit-H epoch 100 EMA weights. The stored
|
| 6 |
+
Lightning epoch is 24; 25 fine-tuning epochs have completed (199,100 steps).
|
| 7 |
+
|
| 8 |
+
This conditional checkpoint requires a scaffold. Use its saved architecture and
|
| 9 |
+
configuration; the unconditional `morph generate` interface/catalog does not load it.
|
| 10 |
+
Both current and EMA networks and optimizer state are retained. EMA is used for evaluation.
|
| 11 |
+
Scaffold atom identities, internal bonds and charges are preserved; positions can move.
|
| 12 |
+
Substituent assignment affects training supervision and does not require hidden target
|
| 13 |
+
bonds at generation time.
|
| 14 |
+
|
| 15 |
+
## Files and reproduction
|
| 16 |
+
|
| 17 |
+
- `epoch_025.ckpt`: unmodified original checkpoint; `metadata.json` records its SHA-256.
|
| 18 |
+
- `training_config.yaml`: original composed training configuration, including provenance paths.
|
| 19 |
+
- `config.yaml`: equivalent configuration with portable asset/data paths and base loading disabled.
|
| 20 |
+
- Ordered atom/edge/charge vocabularies and `distributions.pt`: exact model assets.
|
| 21 |
+
- `panels/`: fixed 512-scaffold validation and test selections, with eight attempts per scaffold.
|
| 22 |
+
- `training_source.tar.gz`: original frozen training source, training manifest, and insertion-assignment audit.
|
| 23 |
+
- `runtime/`: evaluation source snapshot, including corrected raw-graph RDKit stability.
|
| 24 |
+
- `evaluate.py`: evaluation/preflight/aggregation driver; `manifest.json` hashes every release file.
|
| 25 |
+
|
| 26 |
+
In an existing compatible Morph environment, set `PYTHONPATH` to `runtime/src:runtime`
|
| 27 |
+
and run `evaluate.py preflight --bundle <this-folder> --data-root <GEOM-root>
|
| 28 |
+
--output <results-folder>`. The GEOM root must contain the matching processed data and
|
| 29 |
+
scaffold caches. The script sets portable asset environment variables itself.
|
| 30 |
+
|
| 31 |
+
The cluster evaluation uses the held-out **test panel, 512 × 8 attempts × seeds 42/43/44**,
|
| 32 |
+
100 integration steps, EMA weights, and no inference scaffold jitter. It reports native
|
| 33 |
+
scaffold metrics, strict and scaffold-aware PoseBusters, raw-graph stability, chemistry,
|
| 34 |
+
and distribution/geometry diagnostics. Native PoseBusters omits the separate full offline
|
| 35 |
+
energy/flatness checks. All scalar metrics are aggregated into one `summary.csv`.
|
| 36 |
+
|
| 37 |
+
The evaluation driver requires a completed upload-verification JSON before generation;
|
| 38 |
+
this is a provenance guard for this release. Generated coordinates are not relaxed by this
|
| 39 |
+
scaffold evaluation. The checkpoint/configuration hashes and original training archive
|
| 40 |
+
allow the training and evaluation implementations to be distinguished.
|
geom/scaffold_murcko_substituent_lora_r16/atom_tokens.txt
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Br
|
| 2 |
+
C
|
| 3 |
+
Cl
|
| 4 |
+
F
|
| 5 |
+
H
|
| 6 |
+
I
|
| 7 |
+
N
|
| 8 |
+
O
|
| 9 |
+
P
|
| 10 |
+
S
|
geom/scaffold_murcko_substituent_lora_r16/charge_tokens.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-2
|
| 2 |
+
-1
|
| 3 |
+
0
|
| 4 |
+
1
|
| 5 |
+
2
|
geom/scaffold_murcko_substituent_lora_r16/config.yaml
ADDED
|
@@ -0,0 +1,461 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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.001
|
| 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.0001
|
| 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.finetune.scaffold.LightningModuleRatesScaffoldFinetune
|
| 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.finetune.scaffold.ScaffoldConditionalDiTBackboneWithHeads
|
| 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 |
+
xattn_encoder_args: ${model.xattn_encoder}
|
| 146 |
+
use_distance_bias: true
|
| 147 |
+
pretrained_ckpt: null
|
| 148 |
+
pretrained_prefer_ema: true
|
| 149 |
+
freeze_pretrained_backbone: true
|
| 150 |
+
freeze_output_heads: false
|
| 151 |
+
exclude_scaffold_from_sub_loss: true
|
| 152 |
+
exclude_scaffold_from_x_loss: false
|
| 153 |
+
freeze_keep_positions: false
|
| 154 |
+
freeze_keep_charges: true
|
| 155 |
+
rotate: true
|
| 156 |
+
n_augmentations: 1
|
| 157 |
+
integrator: ${integrator.integrator}
|
| 158 |
+
beta_sched:
|
| 159 |
+
_target_: torch.distributions.Beta
|
| 160 |
+
concentration1: 2.0
|
| 161 |
+
concentration0: 1.0
|
| 162 |
+
linear_sched:
|
| 163 |
+
_target_: torch.distributions.Uniform
|
| 164 |
+
low: 0.0
|
| 165 |
+
high: 1.0
|
| 166 |
+
sample_time_strategy: linear
|
| 167 |
+
head_node_dim: ${model.backbone.out_node_nf}
|
| 168 |
+
head_edge_dim: ${model.backbone.out_edge_nf}
|
| 169 |
+
head_node_adapter_dim: 256
|
| 170 |
+
head_edge_adapter_dim: 256
|
| 171 |
+
head_insertion_adapter_dim: 256
|
| 172 |
+
head_insertion_edge_dim: 256
|
| 173 |
+
head_independent_adapters: true
|
| 174 |
+
head_initialization:
|
| 175 |
+
output_std: 0.001
|
| 176 |
+
coordinate_output_std: 0.0
|
| 177 |
+
do_del_probability: 0.5
|
| 178 |
+
do_sub_a_probability: 0.5
|
| 179 |
+
do_sub_e_probability: 0.5
|
| 180 |
+
ins_rate: 0.6931471805599453
|
| 181 |
+
token_weighting:
|
| 182 |
+
type_loss_token_weights: uniform
|
| 183 |
+
weight_alpha: 0.4
|
| 184 |
+
lora:
|
| 185 |
+
enabled: true
|
| 186 |
+
rank: 16
|
| 187 |
+
alpha: 16.0
|
| 188 |
+
dropout: 0.0
|
| 189 |
+
targets:
|
| 190 |
+
- qkv
|
| 191 |
+
- proj
|
| 192 |
+
- mlp.gate_value
|
| 193 |
+
- mlp.out_proj
|
| 194 |
+
freeze_base: true
|
| 195 |
+
backbone:
|
| 196 |
+
_target_: morph.model.backbones.conditional_dit.ConditionalDiTBackbone
|
| 197 |
+
_recursive_: false
|
| 198 |
+
d_input: ${embeddings.atom_type_embedding.out_dim}
|
| 199 |
+
d_cond: ${oc.eval:"${embeddings.time_embedding.out_dim} + ${embeddings.node_count_embedding.out_dim}"}
|
| 200 |
+
d_model: 512
|
| 201 |
+
out_node_nf: 256
|
| 202 |
+
out_edge_nf: 256
|
| 203 |
+
num_layers: 8
|
| 204 |
+
nhead: 16
|
| 205 |
+
mlp_ratio: 4.0
|
| 206 |
+
ffn_hidden_dim: null
|
| 207 |
+
ffn_multiple_of: 64
|
| 208 |
+
qk_norm: true
|
| 209 |
+
coordinate_output_init_std: ${model.head_initialization.coordinate_output_std}
|
| 210 |
+
center_coordinate_output: true
|
| 211 |
+
in_edge_nf: ${embeddings.edge_type_embedding.out_dim}
|
| 212 |
+
edge_pair_dim: 256
|
| 213 |
+
pair_bias_hidden_dim: 32
|
| 214 |
+
num_atom_types: ${len:${data.vocab.atom_tokens}}
|
| 215 |
+
lora: ${model.lora}
|
| 216 |
+
rbf_embedding_args:
|
| 217 |
+
_target_: morph.model.layers.embedding.RBFEmbedding
|
| 218 |
+
num_rbf: 128
|
| 219 |
+
rbf_dmax: 3.5
|
| 220 |
+
out_dim: 64
|
| 221 |
+
dropout: 0.0
|
| 222 |
+
trainable: false
|
| 223 |
+
ctx_dim: 128
|
| 224 |
+
use_cross_attn: true
|
| 225 |
+
use_node_cond: true
|
| 226 |
+
use_edge_cond: true
|
| 227 |
+
xattn_encoder:
|
| 228 |
+
_target_: morph.model.finetune.base.LightweightContextEncoder
|
| 229 |
+
num_atom_types: ${len:${data.vocab.atom_tokens}}
|
| 230 |
+
num_charges: ${len:${data.vocab.charge_tokens}}
|
| 231 |
+
atom_embed_dim: 64
|
| 232 |
+
charge_embed_dim: 16
|
| 233 |
+
pos_embed_dim: 32
|
| 234 |
+
ctx_dim: ${model.backbone.ctx_dim}
|
| 235 |
+
num_attn_layers: 4
|
| 236 |
+
nhead: 8
|
| 237 |
+
mlp_ratio: 4.0
|
| 238 |
+
dropout: 0.0
|
| 239 |
+
use_pair_bias: true
|
| 240 |
+
num_edge_types: ${len:${data.vocab.edge_tokens}}
|
| 241 |
+
edge_embed_dim: 32
|
| 242 |
+
num_rbf: 32
|
| 243 |
+
rbf_dmax: 5.0
|
| 244 |
+
pair_bias_hidden_dim: 32
|
| 245 |
+
schedule:
|
| 246 |
+
_target_: morph.flow_matching.schedules.SmoothstepSchedule
|
| 247 |
+
shift: 0.8
|
| 248 |
+
trainer:
|
| 249 |
+
trainer:
|
| 250 |
+
deterministic: warn
|
| 251 |
+
devices: 2
|
| 252 |
+
accelerator: gpu
|
| 253 |
+
strategy: ddp_find_unused_parameters_false
|
| 254 |
+
precision: bf16-mixed
|
| 255 |
+
max_epochs: 50
|
| 256 |
+
accumulate_grad_batches: 1
|
| 257 |
+
num_sanity_val_steps: 0
|
| 258 |
+
gradient_clip_val: null
|
| 259 |
+
gradient_clip_algorithm: norm
|
| 260 |
+
check_val_every_n_epoch: 1
|
| 261 |
+
num_val_samples: 4096
|
| 262 |
+
limit_val_batches: null
|
| 263 |
+
limit_predict_batches: 4
|
| 264 |
+
enable_progress_bar: false
|
| 265 |
+
max_time:
|
| 266 |
+
hours: 0
|
| 267 |
+
seconds: 169927
|
| 268 |
+
do_train: true
|
| 269 |
+
do_validate: false
|
| 270 |
+
do_predict: false
|
| 271 |
+
checkpoint_path: null
|
| 272 |
+
final_checkpoint_path: final.ckpt
|
| 273 |
+
callbacks: {}
|
| 274 |
+
logging:
|
| 275 |
+
enabled: false
|
| 276 |
+
project: morph-geom-scaffold-decoration
|
| 277 |
+
name: ${oc.env:MORPH_RUN_ID,base}
|
| 278 |
+
save_dir: .
|
| 279 |
+
offline: false
|
| 280 |
+
group: geom-e100-murcko-original-50ep-20261010
|
| 281 |
+
tags:
|
| 282 |
+
- substituent-insertion
|
| 283 |
+
- rank-16
|
| 284 |
+
- scaffold-decoration
|
| 285 |
+
- bemis-murcko
|
| 286 |
+
- geom-e100
|
| 287 |
+
- lora
|
| 288 |
+
- trainable-heads
|
| 289 |
+
- movable-scaffold
|
| 290 |
+
- jitter-0.1A
|
| 291 |
+
- scaffold-metrics
|
| 292 |
+
integrator:
|
| 293 |
+
integrator:
|
| 294 |
+
_target_: morph.flow_matching.integration.RateIntegrator
|
| 295 |
+
vocab: ${data.vocab}
|
| 296 |
+
distributions: None
|
| 297 |
+
insertion_head_mode: ${insertion_head.mode}
|
| 298 |
+
insertion_dimension: ${insertion_head.dimension}
|
| 299 |
+
insertion_num_components: ${insertion_head.num_components}
|
| 300 |
+
time_strategy: log
|
| 301 |
+
time_beta_alpha: 2.0
|
| 302 |
+
time_beta_beta: 1.0
|
| 303 |
+
num_integration_steps: 100
|
| 304 |
+
ins_noise_scale: ${data.ins_noise_scale}
|
| 305 |
+
renoise_insertions: true
|
| 306 |
+
exact_schedule_integration: true
|
| 307 |
+
del_schedule: ${data.interpolator.del_schedule}
|
| 308 |
+
ins_schedule: ${data.interpolator.ins_schedule}
|
| 309 |
+
sub_schedule: ${data.interpolator.sub_schedule}
|
| 310 |
+
sub_e_schedule: ${data.interpolator.sub_e_schedule}
|
| 311 |
+
data:
|
| 312 |
+
root_path: ${oc.env:PROJECT_ROOT}/data
|
| 313 |
+
preprocess_workers: 10
|
| 314 |
+
preprocess_chunk_size: 128
|
| 315 |
+
statistics_workers: ${data.preprocess_workers}
|
| 316 |
+
hydrogen_mode: explicit
|
| 317 |
+
cache_name: ${data.dataset_name}${if:${eq:${data.hydrogen_mode},implicit},_implicit_h,''}
|
| 318 |
+
source_dir: ${oc.env:GEOM_SOURCE_DIR,null}
|
| 319 |
+
max_atoms: 72
|
| 320 |
+
allowed_atom_symbols:
|
| 321 |
+
- H
|
| 322 |
+
- C
|
| 323 |
+
- 'N'
|
| 324 |
+
- O
|
| 325 |
+
- S
|
| 326 |
+
- F
|
| 327 |
+
- Cl
|
| 328 |
+
- Br
|
| 329 |
+
- P
|
| 330 |
+
- I
|
| 331 |
+
n_atoms_strategy: uniform
|
| 332 |
+
uniform_n_atoms_padding: 5
|
| 333 |
+
optimal_transport: equivariant
|
| 334 |
+
ins_noise_scale: 0.65
|
| 335 |
+
move_noise_scale: 0.5
|
| 336 |
+
allow_charged: true
|
| 337 |
+
preprocessing:
|
| 338 |
+
_target_: morph.dataset.core.preprocessing.Preprocessing
|
| 339 |
+
_recursive_: false
|
| 340 |
+
root: ${oc.env:MORPH_GEOM_ROOT}
|
| 341 |
+
num_workers: ${data.statistics_workers}
|
| 342 |
+
train_dataset: ${data.datamodule.datasets.train}
|
| 343 |
+
atom_tokens_path: ${oc.env:MORPH_SCAFFOLD_BUNDLE}/atom_tokens.txt
|
| 344 |
+
edge_tokens_path: ${oc.env:MORPH_SCAFFOLD_BUNDLE}/edge_tokens.txt
|
| 345 |
+
charge_tokens_path: ${oc.env:MORPH_SCAFFOLD_BUNDLE}/charge_tokens.txt
|
| 346 |
+
distributions_path: ${oc.env:MORPH_SCAFFOLD_BUNDLE}/distributions.pt
|
| 347 |
+
vocab: null
|
| 348 |
+
interpolator:
|
| 349 |
+
_target_: morph.flow_matching.interpolation.Interpolator
|
| 350 |
+
distributions: null
|
| 351 |
+
optimal_transport: ${data.optimal_transport}
|
| 352 |
+
ins_noise_scale: ${data.ins_noise_scale}
|
| 353 |
+
move_noise_scale: ${data.move_noise_scale}
|
| 354 |
+
atom_type_noise_prob: 0.0
|
| 355 |
+
pre_align_iters: 2
|
| 356 |
+
c_move: 1.0
|
| 357 |
+
c_sub: 0.0
|
| 358 |
+
c_ins: 6.125
|
| 359 |
+
c_del: 6.125
|
| 360 |
+
del_schedule: ${schedule}
|
| 361 |
+
ins_schedule: ${schedule}
|
| 362 |
+
sub_schedule:
|
| 363 |
+
_target_: morph.flow_matching.schedules.SmoothstepSchedule
|
| 364 |
+
shift: 1.5
|
| 365 |
+
sub_e_schedule:
|
| 366 |
+
_target_: morph.flow_matching.schedules.SmoothstepSchedule
|
| 367 |
+
shift: 1.5
|
| 368 |
+
jitter_scale: ${data.jitter_scale}
|
| 369 |
+
insertion_assignment: ${data.insertion_assignment}
|
| 370 |
+
datamodule:
|
| 371 |
+
_target_: morph.dataset.conditional.scaffold.datamodule.ScaffoldLightningDataModule
|
| 372 |
+
vocab: ${data.vocab}
|
| 373 |
+
distributions: null
|
| 374 |
+
representation: ${representation}
|
| 375 |
+
datasets:
|
| 376 |
+
train:
|
| 377 |
+
_target_: ${data.dataset_target}
|
| 378 |
+
root: ${data.preprocessing.root}
|
| 379 |
+
preprocess_workers: ${data.preprocess_workers}
|
| 380 |
+
preprocess_chunk_size: ${data.preprocess_chunk_size}
|
| 381 |
+
hydrogen_mode: ${data.hydrogen_mode}
|
| 382 |
+
source_dir: ${data.source_dir}
|
| 383 |
+
max_atoms: ${data.max_atoms}
|
| 384 |
+
allowed_atom_symbols: ${data.allowed_atom_symbols}
|
| 385 |
+
vocab: ${data.vocab}
|
| 386 |
+
distributions: null
|
| 387 |
+
val:
|
| 388 |
+
- _target_: ${data.dataset_target}
|
| 389 |
+
root: ${data.preprocessing.root}
|
| 390 |
+
preprocess_workers: ${data.preprocess_workers}
|
| 391 |
+
preprocess_chunk_size: ${data.preprocess_chunk_size}
|
| 392 |
+
hydrogen_mode: ${data.hydrogen_mode}
|
| 393 |
+
source_dir: ${data.source_dir}
|
| 394 |
+
max_atoms: ${data.max_atoms}
|
| 395 |
+
allowed_atom_symbols: ${data.allowed_atom_symbols}
|
| 396 |
+
vocab: ${data.vocab}
|
| 397 |
+
distributions: null
|
| 398 |
+
test:
|
| 399 |
+
- _target_: ${data.dataset_target}
|
| 400 |
+
root: ${data.preprocessing.root}
|
| 401 |
+
preprocess_workers: ${data.preprocess_workers}
|
| 402 |
+
preprocess_chunk_size: ${data.preprocess_chunk_size}
|
| 403 |
+
hydrogen_mode: ${data.hydrogen_mode}
|
| 404 |
+
source_dir: ${data.source_dir}
|
| 405 |
+
max_atoms: ${data.max_atoms}
|
| 406 |
+
allowed_atom_symbols: ${data.allowed_atom_symbols}
|
| 407 |
+
vocab: ${data.vocab}
|
| 408 |
+
distributions: null
|
| 409 |
+
interpolator: ${data.interpolator}
|
| 410 |
+
rotate: ${model.rotate}
|
| 411 |
+
n_augmentations: ${model.n_augmentations}
|
| 412 |
+
num_workers:
|
| 413 |
+
train: 20
|
| 414 |
+
val: 0
|
| 415 |
+
test: 0
|
| 416 |
+
batch_size:
|
| 417 |
+
train: 320
|
| 418 |
+
val: 32
|
| 419 |
+
test: 32
|
| 420 |
+
n_atoms_strategy: ${data.n_atoms_strategy}
|
| 421 |
+
uniform_n_atoms_padding: ${data.uniform_n_atoms_padding}
|
| 422 |
+
time_dist: ${model.module.time_dist}
|
| 423 |
+
scaffold_groups_dir: ${data.scaffold_groups_dir}
|
| 424 |
+
scaffold_kind: ${data.scaffold_kind}
|
| 425 |
+
enumerate_slicings: ${data.enumerate_slicings}
|
| 426 |
+
eval_panel: ${data.eval_panel}
|
| 427 |
+
train_prefetch_factor: 1
|
| 428 |
+
dataset_name: geom
|
| 429 |
+
dataset_target: morph.dataset.unconditional.geom.FlowMatchingGEOMDataset
|
| 430 |
+
scaffold_groups_dir: ${data.preprocessing.root}/processed/scaffold_groups
|
| 431 |
+
scaffold_kind: murcko
|
| 432 |
+
jitter_scale: 0.1
|
| 433 |
+
insertion_assignment: substituent
|
| 434 |
+
enumerate_slicings: false
|
| 435 |
+
eval_panel:
|
| 436 |
+
directory: ${oc.env:MORPH_SCAFFOLD_BUNDLE}/panels
|
| 437 |
+
n_scaffolds: 512
|
| 438 |
+
samples_per_scaffold: 8
|
| 439 |
+
seed: 42
|
| 440 |
+
embeddings:
|
| 441 |
+
atom_type_embedding:
|
| 442 |
+
_target_: morph.model.layers.embedding.Embedding
|
| 443 |
+
num_embeddings: ${len:${data.vocab.atom_tokens}}
|
| 444 |
+
embedding_dim: 64
|
| 445 |
+
out_dim: 128
|
| 446 |
+
edge_type_embedding:
|
| 447 |
+
_target_: morph.model.layers.embedding.Embedding
|
| 448 |
+
num_embeddings: ${len:${data.vocab.edge_tokens}}
|
| 449 |
+
embedding_dim: 64
|
| 450 |
+
out_dim: 128
|
| 451 |
+
time_embedding:
|
| 452 |
+
_target_: morph.model.layers.embedding.TimeEmbedding
|
| 453 |
+
embedding_dim: 128
|
| 454 |
+
out_dim: 128
|
| 455 |
+
node_count_embedding:
|
| 456 |
+
_target_: morph.model.layers.embedding.ExtrapolatableCountEmbedding
|
| 457 |
+
embedding_dim: 64
|
| 458 |
+
out_dim: 128
|
| 459 |
+
min_period: 128.0
|
| 460 |
+
max_period: 1024.0
|
| 461 |
+
max_count: 96.0
|
geom/scaffold_murcko_substituent_lora_r16/distributions.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
geom/scaffold_murcko_substituent_lora_r16/distributions.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:40a31704ab58d0349daff35083d43dcf4771ef368fd9c8a8503c94fe844016c5
|
| 3 |
+
size 63581
|
geom/scaffold_murcko_substituent_lora_r16/edge_tokens.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<NO_BOND>
|
| 2 |
+
1
|
| 3 |
+
2
|
| 4 |
+
3
|
geom/scaffold_murcko_substituent_lora_r16/epoch_025.ckpt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0f3b9d75897c951fdfe437bb10735fb371ea2f5e9ea982471c3c7bd73a160484
|
| 3 |
+
size 638268597
|
geom/scaffold_murcko_substituent_lora_r16/evaluate.py
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Evaluate the released scaffold checkpoint on a fixed panel for three seeds."""
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
import argparse
|
| 5 |
+
import csv
|
| 6 |
+
import hashlib
|
| 7 |
+
import json
|
| 8 |
+
import math
|
| 9 |
+
import os
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
import statistics
|
| 12 |
+
import time
|
| 13 |
+
import types
|
| 14 |
+
|
| 15 |
+
import pytorch_lightning as pl
|
| 16 |
+
import torch
|
| 17 |
+
from omegaconf import OmegaConf
|
| 18 |
+
from rdkit import Chem, rdBase
|
| 19 |
+
|
| 20 |
+
import morph.config # noqa: F401
|
| 21 |
+
from morph.inference.generate import _build_module, load_checkpoint
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def sha(path):
|
| 25 |
+
with Path(path).open("rb") as f:
|
| 26 |
+
return hashlib.file_digest(f, "sha256").hexdigest()
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def clean(value):
|
| 30 |
+
if isinstance(value, torch.Tensor):
|
| 31 |
+
return clean(value.item())
|
| 32 |
+
if isinstance(value, float) and not math.isfinite(value):
|
| 33 |
+
return None
|
| 34 |
+
if isinstance(value, dict):
|
| 35 |
+
return {key: clean(item) for key, item in value.items()}
|
| 36 |
+
if isinstance(value, (list, tuple)):
|
| 37 |
+
return [clean(item) for item in value]
|
| 38 |
+
return value
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def write_json(path, value):
|
| 42 |
+
path.write_text(json.dumps(clean(value), indent=2, allow_nan=False) + "\n")
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def configuration(bundle, data_root, seed, output):
|
| 46 |
+
os.environ["MORPH_SCAFFOLD_BUNDLE"] = str(bundle)
|
| 47 |
+
os.environ["MORPH_GEOM_ROOT"] = str(data_root)
|
| 48 |
+
os.environ.setdefault("PROJECT_ROOT", str(bundle / "runtime"))
|
| 49 |
+
os.environ.setdefault("HYDRA_JOBS", str(output))
|
| 50 |
+
cfg = OmegaConf.load(bundle / "config.yaml")
|
| 51 |
+
OmegaConf.set_struct(cfg, False)
|
| 52 |
+
cfg.seed = seed
|
| 53 |
+
cfg.callbacks = {}
|
| 54 |
+
cfg.logging.enabled = False
|
| 55 |
+
cfg.trainer.do_train = False
|
| 56 |
+
cfg.trainer.do_validate = True
|
| 57 |
+
cfg.trainer.do_predict = False
|
| 58 |
+
cfg.trainer.trainer.devices = 1
|
| 59 |
+
cfg.trainer.trainer.strategy = "auto"
|
| 60 |
+
cfg.trainer.trainer.enable_checkpointing = False
|
| 61 |
+
cfg.trainer.trainer.num_val_samples = 4096
|
| 62 |
+
cfg.trainer.trainer.limit_val_batches = 128
|
| 63 |
+
cfg.trainer.trainer.default_root_dir = str(output)
|
| 64 |
+
cfg.trainer.trainer.pop("max_time", None)
|
| 65 |
+
cfg.data.datamodule.num_workers.train = 0
|
| 66 |
+
cfg.data.datamodule.num_workers.val = 0
|
| 67 |
+
cfg.data.datamodule.num_workers.test = 0
|
| 68 |
+
return cfg
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def preflight(args):
|
| 72 |
+
torch.set_num_threads(1)
|
| 73 |
+
bundle = args.bundle.resolve()
|
| 74 |
+
metadata = json.loads((bundle / "metadata.json").read_text())
|
| 75 |
+
checkpoint = bundle / "epoch_025.ckpt"
|
| 76 |
+
assert sha(checkpoint) == metadata["checkpoint_sha256"]
|
| 77 |
+
raw = torch.load(checkpoint, map_location="cpu", weights_only=False, mmap=True)
|
| 78 |
+
assert raw["epoch"] == 24 and raw["global_step"] == 199100
|
| 79 |
+
assert any("lora_" in key for key in raw["state_dict"])
|
| 80 |
+
cfg = configuration(bundle, args.data_root.resolve(), 42, args.output.resolve())
|
| 81 |
+
assert cfg.model.lora.rank == 16 and cfg.data.insertion_assignment == "substituent"
|
| 82 |
+
assert cfg.model.module.pretrained_ckpt is None and cfg.model.module.use_ema_for_eval
|
| 83 |
+
assert cfg.model.module.freeze_keep_charges and not cfg.model.module.freeze_keep_positions
|
| 84 |
+
module, vocab, distributions = _build_module(cfg)
|
| 85 |
+
load_checkpoint(module, checkpoint)
|
| 86 |
+
assert len(vocab.atom_tokens) == 10
|
| 87 |
+
for name, expected in metadata["panel_sha256"].items():
|
| 88 |
+
assert sha(bundle / "panels" / name) == expected
|
| 89 |
+
write_json(args.output / "preflight.json", {
|
| 90 |
+
"status": "passed", "checkpoint_sha256": metadata["checkpoint_sha256"],
|
| 91 |
+
"epoch_zero_based": raw["epoch"], "completed_finetuning_epochs": 25,
|
| 92 |
+
"global_step": raw["global_step"], "strict_state_dict_load": True,
|
| 93 |
+
"ema_available": any(k.startswith("model_ema.") for k in raw["state_dict"]),
|
| 94 |
+
"lora_rank": 16, "insertion_assignment": "substituent",
|
| 95 |
+
"atom_tokens": list(vocab.atom_tokens), "rdkit_version": rdBase.rdkitVersion,
|
| 96 |
+
})
|
| 97 |
+
print("Preflight passed: epoch 25, rank-16 LoRA, strict checkpoint load, verified panels.", flush=True)
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
class Population(pl.Callback):
|
| 101 |
+
def __init__(self, output):
|
| 102 |
+
self.output = output
|
| 103 |
+
|
| 104 |
+
def on_validation_batch_end(self, trainer, module, outputs, batch, batch_idx, dataloader_idx=0):
|
| 105 |
+
if batch_idx % 16 == 0:
|
| 106 |
+
print(f"Generated {len(module._scaffold_rows)}/4096 attempts", flush=True)
|
| 107 |
+
|
| 108 |
+
def on_validation_epoch_end(self, trainer, module):
|
| 109 |
+
rows = module._scaffold_rows
|
| 110 |
+
assert len(rows) == 4096 and {r["sample_id"] for r in rows} == set(range(4096))
|
| 111 |
+
assert len({r["scaffold_id"] for r in rows}) == 512
|
| 112 |
+
assert len(module._validation_rdkit_mols) == len(rows)
|
| 113 |
+
with (self.output / "attempts.jsonl").open("w") as f, Chem.SDWriter(str(self.output / "generated.sdf")) as writer:
|
| 114 |
+
for row, mol in zip(rows, module._validation_rdkit_mols, strict=True):
|
| 115 |
+
entry = dict(row)
|
| 116 |
+
entry["sdf_written"] = False
|
| 117 |
+
if mol is not None:
|
| 118 |
+
mol.SetProp("_Name", f"sample_{row['sample_id']:05d}")
|
| 119 |
+
try:
|
| 120 |
+
writer.write(mol)
|
| 121 |
+
entry["sdf_written"] = True
|
| 122 |
+
except Exception as exc:
|
| 123 |
+
entry["sdf_error"] = str(exc)
|
| 124 |
+
f.write(json.dumps(clean(entry), allow_nan=False) + "\n")
|
| 125 |
+
print("Saved all attempts and original generated SDFs; computing scaffold and chemistry scores.", flush=True)
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
def evaluate(args):
|
| 129 |
+
from run import setup
|
| 130 |
+
|
| 131 |
+
start = time.monotonic()
|
| 132 |
+
bundle = args.bundle.resolve()
|
| 133 |
+
work = args.output.resolve()
|
| 134 |
+
upload = json.loads((work / "upload_verification.json").read_text())
|
| 135 |
+
assert upload["status"] == "passed", "Upload must be verified before evaluation"
|
| 136 |
+
output = work / f"seed_{args.seed}"
|
| 137 |
+
output.mkdir(parents=True, exist_ok=False)
|
| 138 |
+
(output / "chunks").mkdir()
|
| 139 |
+
metadata = json.loads((bundle / "metadata.json").read_text())
|
| 140 |
+
assert sha(bundle / "epoch_025.ckpt") == metadata["checkpoint_sha256"]
|
| 141 |
+
cfg = configuration(bundle, args.data_root.resolve(), args.seed, output)
|
| 142 |
+
module, datamodule, trainer = setup(cfg, extra_callbacks=[Population(output)])
|
| 143 |
+
datamodule.setup("test")
|
| 144 |
+
panel = datamodule.test_datasets[0]
|
| 145 |
+
assert len(panel) == 4096 and len(panel.entries) == 512 and panel.samples_per_scaffold == 8
|
| 146 |
+
assert Path(panel.path).name == "test_murcko_512_seed42.json"
|
| 147 |
+
assert sha(panel.path) == metadata["panel_sha256"]["test_murcko_512_seed42.json"]
|
| 148 |
+
assert module.use_ema_for_eval
|
| 149 |
+
# Save every raw graph before sanitization failures can remove it from SDFs.
|
| 150 |
+
original_update = module._update_task_metrics
|
| 151 |
+
chunks = []
|
| 152 |
+
|
| 153 |
+
def capture(self, context, mols, rdkit_mols):
|
| 154 |
+
path = output / "chunks" / f"batch_{len(chunks):04d}.pt"
|
| 155 |
+
torch.save(mols, path)
|
| 156 |
+
chunks.append(path.name)
|
| 157 |
+
return original_update(context, mols, rdkit_mols)
|
| 158 |
+
|
| 159 |
+
module._update_task_metrics = types.MethodType(capture, module)
|
| 160 |
+
OmegaConf.save(cfg, output / "config.yaml", resolve=True)
|
| 161 |
+
values = trainer.validate(module, dataloaders=datamodule.test_dataloader(), ckpt_path=str(bundle / "epoch_025.ckpt"))
|
| 162 |
+
assert len(values) == 1
|
| 163 |
+
metrics = {k.removeprefix("val/"): v for k, v in values[0].items()}
|
| 164 |
+
required = {"validity", "novelty", "rdkit-atom-stability", "rdkit-molecule-stability",
|
| 165 |
+
"posebusters/validity", "scaffold/posebusters/validity", "scaffold/retention",
|
| 166 |
+
"scaffold/recovery", "scaffold/unique_yield", "scaffold/rmsd_aligned"}
|
| 167 |
+
assert required <= metrics.keys(), sorted(required - metrics.keys())
|
| 168 |
+
for key, value in {"n_scaffolds": 512, "n_samples": 4096, "min_samples_per_scaffold": 8, "max_samples_per_scaffold": 8}.items():
|
| 169 |
+
assert metrics[f"scaffold/{key}"] == value
|
| 170 |
+
assert len(chunks) == 128
|
| 171 |
+
report = {
|
| 172 |
+
"status": "completed", "split": "test", "seed": args.seed,
|
| 173 |
+
"n_attempts": 4096, "n_scaffolds": 512, "samples_per_scaffold": 8,
|
| 174 |
+
"weights": "EMA", "integration_steps": 100, "checkpoint_sha256": metadata["checkpoint_sha256"],
|
| 175 |
+
"uploaded_revision": upload["revision"], "metrics": metrics,
|
| 176 |
+
"rdkit_stability_population": "all raw generated graphs",
|
| 177 |
+
"posebusters_protocol": "native scaffold evaluation: chemistry and distance geometry; scaffold-aware inherited-clash attribution; excludes full offline energy and flatness",
|
| 178 |
+
"raw_graph_chunks": chunks, "panel_sha256": sha(panel.path),
|
| 179 |
+
"elapsed_seconds": time.monotonic()-start, "job_id": os.environ.get("SLURM_JOB_ID"),
|
| 180 |
+
}
|
| 181 |
+
write_json(output / "metrics.json", report)
|
| 182 |
+
print(json.dumps(clean(report), indent=2), flush=True)
|
| 183 |
+
|
| 184 |
+
|
| 185 |
+
def aggregate(args):
|
| 186 |
+
work = args.output.resolve()
|
| 187 |
+
reports = [json.loads((work / f"seed_{seed}/metrics.json").read_text()) for seed in (42, 43, 44)]
|
| 188 |
+
assert all(r["status"] == "completed" for r in reports)
|
| 189 |
+
keys = set(reports[0]["metrics"])
|
| 190 |
+
assert all(set(r["metrics"]) == keys for r in reports)
|
| 191 |
+
assert len({r["checkpoint_sha256"] for r in reports}) == 1
|
| 192 |
+
assert len({r["panel_sha256"] for r in reports}) == 1
|
| 193 |
+
with (work / "summary.csv").open("w", newline="") as f:
|
| 194 |
+
writer = csv.DictWriter(f, fieldnames=["model", "completed_epochs", "split", "metric", "seed_42", "seed_43", "seed_44", "mean", "std", "n_seeds"])
|
| 195 |
+
writer.writeheader()
|
| 196 |
+
for key in sorted(keys):
|
| 197 |
+
values = [r["metrics"][key] for r in reports]
|
| 198 |
+
finite = [x for x in values if x is not None and math.isfinite(x)]
|
| 199 |
+
writer.writerow({"model": "geom-scaffold-murcko-substituent-lora-r16", "completed_epochs": 25,
|
| 200 |
+
"split": "test", "metric": key, **dict(zip(["seed_42", "seed_43", "seed_44"], values)),
|
| 201 |
+
"mean": statistics.mean(finite) if finite else None,
|
| 202 |
+
"std": statistics.stdev(finite) if len(finite)>1 else None, "n_seeds": len(finite)})
|
| 203 |
+
write_json(work / "verification.json", {"status": "passed", "n_seeds": 3, "n_attempts": 12288, "n_metrics": len(keys),
|
| 204 |
+
"summary_sha256": sha(work / "summary.csv"), "checkpoint_sha256": reports[0]["checkpoint_sha256"]})
|
| 205 |
+
print(f"Verified {len(keys)} metrics across 3 seeds; all metrics in {work / 'summary.csv'}", flush=True)
|
| 206 |
+
|
| 207 |
+
|
| 208 |
+
def main():
|
| 209 |
+
p = argparse.ArgumentParser()
|
| 210 |
+
p.add_argument("mode", choices=["preflight", "evaluate", "aggregate"])
|
| 211 |
+
p.add_argument("--bundle", type=Path, required=True)
|
| 212 |
+
p.add_argument("--data-root", type=Path, required=True)
|
| 213 |
+
p.add_argument("--output", type=Path, required=True)
|
| 214 |
+
p.add_argument("--seed", type=int, choices=[42, 43, 44], default=42)
|
| 215 |
+
args = p.parse_args()
|
| 216 |
+
args.output.mkdir(parents=True, exist_ok=True)
|
| 217 |
+
{"preflight": preflight, "evaluate": evaluate, "aggregate": aggregate}[args.mode](args)
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
if __name__ == "__main__":
|
| 221 |
+
main()
|
geom/scaffold_murcko_substituent_lora_r16/manifest.json
ADDED
|
@@ -0,0 +1,750 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"README.md": {
|
| 3 |
+
"bytes": 2752,
|
| 4 |
+
"sha256": "3879125c6ede15b8b268f316c5c2163b1af0fb795582c3e4685acb029f52b74f"
|
| 5 |
+
},
|
| 6 |
+
"atom_tokens.txt": {
|
| 7 |
+
"bytes": 22,
|
| 8 |
+
"sha256": "c9b712563ad2509593aa48fddbb5145aa42a70c4791255b8eea2984f549cae6a"
|
| 9 |
+
},
|
| 10 |
+
"charge_tokens.txt": {
|
| 11 |
+
"bytes": 12,
|
| 12 |
+
"sha256": "e2533aa090751f1006a74d165aa2d4a7ac23dbf73a65eb624c2a81216cc7dff5"
|
| 13 |
+
},
|
| 14 |
+
"config.yaml": {
|
| 15 |
+
"bytes": 14715,
|
| 16 |
+
"sha256": "9db9f6c09bc55fb7b39b3b3b37155cefcf3255a8c5eb899fd80c08edf71aa7f1"
|
| 17 |
+
},
|
| 18 |
+
"distributions.json": {
|
| 19 |
+
"bytes": 220286,
|
| 20 |
+
"sha256": "17bcf85c09486e5070aa8b3be4f4411fa01e6b3cf1b39c5488a5f46149f52e0f"
|
| 21 |
+
},
|
| 22 |
+
"distributions.pt": {
|
| 23 |
+
"bytes": 63581,
|
| 24 |
+
"sha256": "40a31704ab58d0349daff35083d43dcf4771ef368fd9c8a8503c94fe844016c5"
|
| 25 |
+
},
|
| 26 |
+
"edge_tokens.txt": {
|
| 27 |
+
"bytes": 16,
|
| 28 |
+
"sha256": "42b635ef938d2ec5a601044e4b01f3f84ed121f1bfaac984d86f180a8ccba3fd"
|
| 29 |
+
},
|
| 30 |
+
"epoch_025.ckpt": {
|
| 31 |
+
"bytes": 638268597,
|
| 32 |
+
"sha256": "0f3b9d75897c951fdfe437bb10735fb371ea2f5e9ea982471c3c7bd73a160484"
|
| 33 |
+
},
|
| 34 |
+
"evaluate.py": {
|
| 35 |
+
"bytes": 10649,
|
| 36 |
+
"sha256": "ad57177b2289610ec10983c9f20480adca7e393166ffec78e9641d3546bc433c"
|
| 37 |
+
},
|
| 38 |
+
"metadata.json": {
|
| 39 |
+
"bytes": 1511,
|
| 40 |
+
"sha256": "f1200bd618873ce5ba3e1d0a3569cd852c6b1fbe6c7523863dfb567541228c1d"
|
| 41 |
+
},
|
| 42 |
+
"panels/test_murcko_512_seed42.json": {
|
| 43 |
+
"bytes": 226522,
|
| 44 |
+
"sha256": "5df2f8b632dd261098ee86581b748487163b10893d2a4462f3e52cd25130905b"
|
| 45 |
+
},
|
| 46 |
+
"panels/val_murcko_512_seed42.json": {
|
| 47 |
+
"bytes": 224341,
|
| 48 |
+
"sha256": "b30a2063ba1c74414a2bda387f9dc42ade8c82540d6ec36c58956c12bee64e44"
|
| 49 |
+
},
|
| 50 |
+
"panels/verification.json": {
|
| 51 |
+
"bytes": 282,
|
| 52 |
+
"sha256": "b8a24405b78b49524bd09fd2593f8686b7910680709aed1956b140c45ffbd342"
|
| 53 |
+
},
|
| 54 |
+
"runtime/README.md": {
|
| 55 |
+
"bytes": 8819,
|
| 56 |
+
"sha256": "5214473be19c41f94f4bace3188e2620cbff69610ee15d495aa97934bd7b30eb"
|
| 57 |
+
},
|
| 58 |
+
"runtime/configs/callbacks/callbacks.yaml": {
|
| 59 |
+
"bytes": 699,
|
| 60 |
+
"sha256": "dce0adebf5956dce687d64a074238f9c12866373bfe21df6658d967d6bfd1f90"
|
| 61 |
+
},
|
| 62 |
+
"runtime/configs/data/chembl3d/chembl3d.yaml": {
|
| 63 |
+
"bytes": 278,
|
| 64 |
+
"sha256": "a96974d90353a850c4a1d0bac27de5f1fc8724b81cc5bbc122aab6f76f3051c5"
|
| 65 |
+
},
|
| 66 |
+
"runtime/configs/data/chembl3d/implicit_h.yaml": {
|
| 67 |
+
"bytes": 81,
|
| 68 |
+
"sha256": "08da196d0288cf1fe4dba8dd407c49d9bee003607504beb59f79e5d6b9eaef0c"
|
| 69 |
+
},
|
| 70 |
+
"runtime/configs/data/chembl3d/max100.yaml": {
|
| 71 |
+
"bytes": 246,
|
| 72 |
+
"sha256": "052dba7b3f3efce990019518823476bd6bf1381bb5f606822c9fc7a485e6d0bf"
|
| 73 |
+
},
|
| 74 |
+
"runtime/configs/data/chembl3d/max100_implicit_h.yaml": {
|
| 75 |
+
"bytes": 79,
|
| 76 |
+
"sha256": "152325f11c7d1500469d4ee381100ae12247e6a2e0b90e5ef7501b405144bb2d"
|
| 77 |
+
},
|
| 78 |
+
"runtime/configs/data/crossdocked/finetune.yaml": {
|
| 79 |
+
"bytes": 2709,
|
| 80 |
+
"sha256": "ba3da996e4c0fd720d6403974f3a3ae851d5defb32a705e931a7bf3f031421f4"
|
| 81 |
+
},
|
| 82 |
+
"runtime/configs/data/crossdocked/scaffold_decoration.yaml": {
|
| 83 |
+
"bytes": 1171,
|
| 84 |
+
"sha256": "4498b88a65912705d49b4a3bf583f41329bbf9637f7250ee85bfbd677a8cb22d"
|
| 85 |
+
},
|
| 86 |
+
"runtime/configs/data/geom/geom.yaml": {
|
| 87 |
+
"bytes": 428,
|
| 88 |
+
"sha256": "736c04e86c029bed65ce3ed022f937dd418ddc70d4b9fc064b38d979bf29ee6d"
|
| 89 |
+
},
|
| 90 |
+
"runtime/configs/data/geom/implicit_h.yaml": {
|
| 91 |
+
"bytes": 73,
|
| 92 |
+
"sha256": "c6b3ff5496af997de0c28e5aa7265903d6d0c8b59aab001ab21d6a64baeb772a"
|
| 93 |
+
},
|
| 94 |
+
"runtime/configs/data/geom/scaffold_decoration.yaml": {
|
| 95 |
+
"bytes": 1630,
|
| 96 |
+
"sha256": "46ca8472be2cd145e526555c0130ccfbfa797c056f4000a9db382dc00edfbed4"
|
| 97 |
+
},
|
| 98 |
+
"runtime/configs/data/molecular.yaml": {
|
| 99 |
+
"bytes": 5005,
|
| 100 |
+
"sha256": "f79ade5ddbf7d08f2eecbb2aa9c3e6b182b8a8e7e48960aff5e5edda5601bdc9"
|
| 101 |
+
},
|
| 102 |
+
"runtime/configs/data/qm9/qm9.yaml": {
|
| 103 |
+
"bytes": 3648,
|
| 104 |
+
"sha256": "3beea93868a1e889b049dcc2ccbc3b7489fa4672e964138654bc512ea01ab9f2"
|
| 105 |
+
},
|
| 106 |
+
"runtime/configs/data/qm9/scaffold_decoration.yaml": {
|
| 107 |
+
"bytes": 1202,
|
| 108 |
+
"sha256": "54cf67421a15625ed9e53e1cb959dc5210106004715cbf6169c9d1bce0a87cfa"
|
| 109 |
+
},
|
| 110 |
+
"runtime/configs/default.yaml": {
|
| 111 |
+
"bytes": 1294,
|
| 112 |
+
"sha256": "bcf9744acbf53afa4305ffd6e9cf95e6f99571750488eaa8cad85896a51aca66"
|
| 113 |
+
},
|
| 114 |
+
"runtime/configs/defaults/chembl3d/chembl3d.yaml": {
|
| 115 |
+
"bytes": 90,
|
| 116 |
+
"sha256": "f09553bc670e6c87ac8c1f8bbd0a8df73f1e83b02a3dcf9d6d06b915ac3bce93"
|
| 117 |
+
},
|
| 118 |
+
"runtime/configs/defaults/chembl3d/implicit_h.yaml": {
|
| 119 |
+
"bytes": 102,
|
| 120 |
+
"sha256": "a0ee1440984eb4c9d3c96a5d1c18df9f59b8e42c499f8a340ccd8deb8c454cd8"
|
| 121 |
+
},
|
| 122 |
+
"runtime/configs/defaults/chembl3d/implicit_h_2x4090.yaml": {
|
| 123 |
+
"bytes": 331,
|
| 124 |
+
"sha256": "518571405333a40e1602ee4c77fd153b56fd53e77aaa2aaf530796142f58d4b8"
|
| 125 |
+
},
|
| 126 |
+
"runtime/configs/defaults/chembl3d/train_2x4090.yaml": {
|
| 127 |
+
"bytes": 826,
|
| 128 |
+
"sha256": "0e6b01b264ab1ae70ae7f144ecd0a03d242e24f02feb087e3d5e2b7bc24790da"
|
| 129 |
+
},
|
| 130 |
+
"runtime/configs/defaults/core.yaml": {
|
| 131 |
+
"bytes": 431,
|
| 132 |
+
"sha256": "0dcfb68e2fece1dc277f647d3b3769af882cf8175e0c3b479bc50029e2538b1c"
|
| 133 |
+
},
|
| 134 |
+
"runtime/configs/defaults/crossdocked/finetune.yaml": {
|
| 135 |
+
"bytes": 364,
|
| 136 |
+
"sha256": "d244463c3049387369b5d1d709986246e7cc6a77218a2147df0820b9fd8c5173"
|
| 137 |
+
},
|
| 138 |
+
"runtime/configs/defaults/crossdocked/scaffold_decoration.yaml": {
|
| 139 |
+
"bytes": 240,
|
| 140 |
+
"sha256": "db421328b9df620fee7f19c99cf10bc6a492f6eb81e17df67e72c7f1bd1da70f"
|
| 141 |
+
},
|
| 142 |
+
"runtime/configs/defaults/crossdocked/scaffold_decoration_2x4090.yaml": {
|
| 143 |
+
"bytes": 1187,
|
| 144 |
+
"sha256": "e6b3e0d004213db5d1291db43c21e8ada0f8b3be4b634a2615eb3a0fb58c7d23"
|
| 145 |
+
},
|
| 146 |
+
"runtime/configs/defaults/geom/geom.yaml": {
|
| 147 |
+
"bytes": 425,
|
| 148 |
+
"sha256": "f447a1bdd39e211b5cf43c4cce56e708da6472d58f79e87885621ec4899c1c8e"
|
| 149 |
+
},
|
| 150 |
+
"runtime/configs/defaults/geom/implicit_h.yaml": {
|
| 151 |
+
"bytes": 98,
|
| 152 |
+
"sha256": "9d3a188e6bd2a2b01609ba0d652184bb8a2f7e27fd89d4a3031568051cae605e"
|
| 153 |
+
},
|
| 154 |
+
"runtime/configs/defaults/geom/scaffold_decoration.yaml": {
|
| 155 |
+
"bytes": 1192,
|
| 156 |
+
"sha256": "dda529d12a8dfd3131dddc3baf7893ea6443c5f9fc9736704d8198f669ae4b7b"
|
| 157 |
+
},
|
| 158 |
+
"runtime/configs/defaults/geom/scaffold_decoration_2x4090.yaml": {
|
| 159 |
+
"bytes": 692,
|
| 160 |
+
"sha256": "301bf8d7446a6d9c10064ffc6c73b704ef15b4fe9bcc48aa8ce89ff732c632a1"
|
| 161 |
+
},
|
| 162 |
+
"runtime/configs/defaults/geom/scaffold_decoration_scratch_2x4090.yaml": {
|
| 163 |
+
"bytes": 955,
|
| 164 |
+
"sha256": "728e19428775722e8107f5ee069be1f9533bd43b22061648978369f686bad887"
|
| 165 |
+
},
|
| 166 |
+
"runtime/configs/defaults/qm9/qm9.yaml": {
|
| 167 |
+
"bytes": 429,
|
| 168 |
+
"sha256": "46070ea792300c0817c0acdff256181b21ef17dfe9f72070bb12da27dc28d534"
|
| 169 |
+
},
|
| 170 |
+
"runtime/configs/defaults/qm9/scaffold_decoration.yaml": {
|
| 171 |
+
"bytes": 694,
|
| 172 |
+
"sha256": "0fecd61454aec70caf87aa397e01eb0eaa2eb5072256d75c6c541196c5aedaa4"
|
| 173 |
+
},
|
| 174 |
+
"runtime/configs/defaults/qm9/train_2x4090.yaml": {
|
| 175 |
+
"bytes": 554,
|
| 176 |
+
"sha256": "43a835246afb7126786e8ffa71c8b80ed9db1ef3a16e5240f1eec7882a4ef5ba"
|
| 177 |
+
},
|
| 178 |
+
"runtime/configs/embeddings/geom.yaml": {
|
| 179 |
+
"bytes": 803,
|
| 180 |
+
"sha256": "06793f4d446d899197e3db28d064592af9049612ee78cb0718a63e3d6fdc3151"
|
| 181 |
+
},
|
| 182 |
+
"runtime/configs/embeddings/qm9.yaml": {
|
| 183 |
+
"bytes": 849,
|
| 184 |
+
"sha256": "de57af7f1ff9b44dbb952f852c0177789196105b77f396298ff8e0218c0626b7"
|
| 185 |
+
},
|
| 186 |
+
"runtime/configs/heads/head.yaml": {
|
| 187 |
+
"bytes": 2475,
|
| 188 |
+
"sha256": "238e2346041e0aedccd16a6ed4066e163004c0e45a2cbc6fd1f6d17e16eb44ed"
|
| 189 |
+
},
|
| 190 |
+
"runtime/configs/insertion_head/gmm.yaml": {
|
| 191 |
+
"bytes": 488,
|
| 192 |
+
"sha256": "1e26914eed9b4971e0f6ff0b61bbdb34103233d346719a55ba6273dd3d785c05"
|
| 193 |
+
},
|
| 194 |
+
"runtime/configs/insertion_head/unimodal.yaml": {
|
| 195 |
+
"bytes": 495,
|
| 196 |
+
"sha256": "547a6391c3b341e3e369f8f4c7aab9752c67dfbbb533388d25956e9011b305e8"
|
| 197 |
+
},
|
| 198 |
+
"runtime/configs/integrator/integrator.yaml": {
|
| 199 |
+
"bytes": 1580,
|
| 200 |
+
"sha256": "8f0d9aafb0b2727cd58154e1fd97df693c8b7d4f5a3fb5efcb9188553f54660f"
|
| 201 |
+
},
|
| 202 |
+
"runtime/configs/logging/wandb_logger.yaml": {
|
| 203 |
+
"bytes": 139,
|
| 204 |
+
"sha256": "a9a2787e048d4eb70f2ff3c49d4355f1a5a382047c8619203b1f9131d829928d"
|
| 205 |
+
},
|
| 206 |
+
"runtime/configs/loss_weights/calibrated_geom.yaml": {
|
| 207 |
+
"bytes": 644,
|
| 208 |
+
"sha256": "d4763c84aa9e1eb77fb2b456384332a4b3a84b072d560918b2357222a43f4ca1"
|
| 209 |
+
},
|
| 210 |
+
"runtime/configs/loss_weights/calibrated_geom_frozen.yaml": {
|
| 211 |
+
"bytes": 1141,
|
| 212 |
+
"sha256": "a08acb61d67a852051dbded08f8bb67f21101888fd0a22a96a522781d28c570d"
|
| 213 |
+
},
|
| 214 |
+
"runtime/configs/loss_weights/tuned_weights.yaml": {
|
| 215 |
+
"bytes": 420,
|
| 216 |
+
"sha256": "2bb5884465666d6fc638f787fd79257e4126c69a5cc55b55615fc45e02e65894"
|
| 217 |
+
},
|
| 218 |
+
"runtime/configs/loss_weights/uniform.yaml": {
|
| 219 |
+
"bytes": 336,
|
| 220 |
+
"sha256": "3c14d6443048f69d436fe03792703a33c67f368ecbb349de2fd145da4c96eabc"
|
| 221 |
+
},
|
| 222 |
+
"runtime/configs/model/backbones/dit.yaml": {
|
| 223 |
+
"bytes": 4039,
|
| 224 |
+
"sha256": "65b0f08be8fb307b8b01e7b460fd083fe60d48148fbece378d7e5a23dd4a9fb0"
|
| 225 |
+
},
|
| 226 |
+
"runtime/configs/model/finetune/lora_finetune.yaml": {
|
| 227 |
+
"bytes": 443,
|
| 228 |
+
"sha256": "973cb978622d19e08a762acf9e918a2279f02ad8501b33d3adb3476ca450726c"
|
| 229 |
+
},
|
| 230 |
+
"runtime/configs/model/finetune/pocket_finetune.yaml": {
|
| 231 |
+
"bytes": 959,
|
| 232 |
+
"sha256": "4d17768a2a884b6e083f06103c5220a737f68cfea87fa4882f112d79a3e54bfa"
|
| 233 |
+
},
|
| 234 |
+
"runtime/configs/model/finetune/scaffold_finetune.yaml": {
|
| 235 |
+
"bytes": 6097,
|
| 236 |
+
"sha256": "dbe7adc88454cc52ea4aab9d420b93d5efa78e03003e5e85de6b6733fa1046b3"
|
| 237 |
+
},
|
| 238 |
+
"runtime/configs/model/finetune/scaffold_pocket_finetune.yaml": {
|
| 239 |
+
"bytes": 634,
|
| 240 |
+
"sha256": "b09d57280abc777773bba4c3d1b8c947b85b2fa73c2e7ea21924c49691a98d93"
|
| 241 |
+
},
|
| 242 |
+
"runtime/configs/optimizer/muon_aux_adam.yaml": {
|
| 243 |
+
"bytes": 1212,
|
| 244 |
+
"sha256": "3b0a6189f3ba81f85f7d26c6f6ad7f64dcb25098a14e411211d7a62983a7180c"
|
| 245 |
+
},
|
| 246 |
+
"runtime/configs/schedule/beta.yaml": {
|
| 247 |
+
"bytes": 78,
|
| 248 |
+
"sha256": "75c485edfd70016b255282adcf5de25dfb95c9e32bb6587017fb8935ffe64eaa"
|
| 249 |
+
},
|
| 250 |
+
"runtime/configs/schedule/cubic.yaml": {
|
| 251 |
+
"bytes": 54,
|
| 252 |
+
"sha256": "a998a2d3390ab5daf4df079852ae8daa907687cf059f55c500409c9493949c0c"
|
| 253 |
+
},
|
| 254 |
+
"runtime/configs/schedule/fast_power.yaml": {
|
| 255 |
+
"bytes": 126,
|
| 256 |
+
"sha256": "22f36106bd43ca253ffea412e00539f2b07efbc49109b97c1232df6a827a2baf"
|
| 257 |
+
},
|
| 258 |
+
"runtime/configs/schedule/linear.yaml": {
|
| 259 |
+
"bytes": 55,
|
| 260 |
+
"sha256": "f7881af26080ab5569e67b39f6eae2733c033b9623020e6271959f09fac45fa0"
|
| 261 |
+
},
|
| 262 |
+
"runtime/configs/schedule/smoothstep.yaml": {
|
| 263 |
+
"bytes": 70,
|
| 264 |
+
"sha256": "f6e8651953d93f0d18c997d40c199b3d80ddd352a2041cc51e29adc9a7f22778"
|
| 265 |
+
},
|
| 266 |
+
"runtime/configs/trainer/trainer.yaml": {
|
| 267 |
+
"bytes": 1402,
|
| 268 |
+
"sha256": "6f78e83ad46529bee7a2878b20727ff403420a515c1629bd73a608a2fb654f5f"
|
| 269 |
+
},
|
| 270 |
+
"runtime/pyproject.toml": {
|
| 271 |
+
"bytes": 4537,
|
| 272 |
+
"sha256": "d88a9882c2e441ce342ac72907b38585a6d9f8e45474b9417020bb3ecfa47ef2"
|
| 273 |
+
},
|
| 274 |
+
"runtime/run.py": {
|
| 275 |
+
"bytes": 9958,
|
| 276 |
+
"sha256": "1911e4fc827f2dd0344ab5a508faeb43cd364fc88c3a547223e34704aa7142c0"
|
| 277 |
+
},
|
| 278 |
+
"runtime/src/morph/__init__.py": {
|
| 279 |
+
"bytes": 79,
|
| 280 |
+
"sha256": "bb402ea5c6f79e569205cc2bf4168d06430753ce8499ca4ffb8614743626fd59"
|
| 281 |
+
},
|
| 282 |
+
"runtime/src/morph/__main__.py": {
|
| 283 |
+
"bytes": 149,
|
| 284 |
+
"sha256": "95a7983479559ca2b15c7afa3881b3142ef4636583501184469b972df7646d4f"
|
| 285 |
+
},
|
| 286 |
+
"runtime/src/morph/_vendor/__init__.py": {
|
| 287 |
+
"bytes": 72,
|
| 288 |
+
"sha256": "8480cd966a03870a7142e1763094bf00e221d2c3c2b1af1d4d458fb8b7f37a20"
|
| 289 |
+
},
|
| 290 |
+
"runtime/src/morph/_vendor/geom_drugs_preprocessing.py": {
|
| 291 |
+
"bytes": 11328,
|
| 292 |
+
"sha256": "33a9c21d29df269a5f342a0b0e8bced0fc620559f0cb3a7a4cfabd5c369ceccb"
|
| 293 |
+
},
|
| 294 |
+
"runtime/src/morph/_vendor/muon.py": {
|
| 295 |
+
"bytes": 16405,
|
| 296 |
+
"sha256": "c61af8c2c4a635cc682b84e279851cb54fedc6fb935d8eb11aafbeb1c5e81fc6"
|
| 297 |
+
},
|
| 298 |
+
"runtime/src/morph/cli.py": {
|
| 299 |
+
"bytes": 9723,
|
| 300 |
+
"sha256": "27eee3fd6d6410747f12b19b670a74f50a51b842a50b1eff4e75c46d0d08a986"
|
| 301 |
+
},
|
| 302 |
+
"runtime/src/morph/config.py": {
|
| 303 |
+
"bytes": 704,
|
| 304 |
+
"sha256": "bd3562c030611f87cc514308f155ad93740dd59927732f71b2e15009012d78ff"
|
| 305 |
+
},
|
| 306 |
+
"runtime/src/morph/dataset/__init__.py": {
|
| 307 |
+
"bytes": 620,
|
| 308 |
+
"sha256": "44ae493354fed0fec4b410f46e0c1fb0351b5fbe5f404ff50f77181e60a39cee"
|
| 309 |
+
},
|
| 310 |
+
"runtime/src/morph/dataset/conditional/__init__.py": {
|
| 311 |
+
"bytes": 316,
|
| 312 |
+
"sha256": "8152efe1b0878297add6646862f56304e38459b894a77817adbd652bee7e334a"
|
| 313 |
+
},
|
| 314 |
+
"runtime/src/morph/dataset/conditional/pocket/README.md": {
|
| 315 |
+
"bytes": 19246,
|
| 316 |
+
"sha256": "2d2d8e20160e5554b40cc54258e43a05938c40bd5232565b47494b94259e562c"
|
| 317 |
+
},
|
| 318 |
+
"runtime/src/morph/dataset/conditional/pocket/__init__.py": {
|
| 319 |
+
"bytes": 190,
|
| 320 |
+
"sha256": "c69f5024a5a90a02f08b31402e16e6eac8598b55e9c6433bda72c0394abd0963"
|
| 321 |
+
},
|
| 322 |
+
"runtime/src/morph/dataset/conditional/pocket/build.py": {
|
| 323 |
+
"bytes": 13844,
|
| 324 |
+
"sha256": "fa645b28b00a39b8abd3550d3e4d2988b6c89e8cd5fac4b52e764877d8661759"
|
| 325 |
+
},
|
| 326 |
+
"runtime/src/morph/dataset/conditional/pocket/crossdocked.py": {
|
| 327 |
+
"bytes": 12798,
|
| 328 |
+
"sha256": "9eab93363712132e5b1062d808bc935558b35fb5869ef6b2a638aef98470067b"
|
| 329 |
+
},
|
| 330 |
+
"runtime/src/morph/dataset/conditional/pocket/datamodule.py": {
|
| 331 |
+
"bytes": 4261,
|
| 332 |
+
"sha256": "cfdcedea2b96b96261af5a17eb4dddc7f471e2b0b7b444b630139d3103f82349"
|
| 333 |
+
},
|
| 334 |
+
"runtime/src/morph/dataset/conditional/pocket/evaluation.py": {
|
| 335 |
+
"bytes": 9050,
|
| 336 |
+
"sha256": "270574b07aa19667f97336a6a38e6e9c93a7e09fde82f80d409640b27762adc6"
|
| 337 |
+
},
|
| 338 |
+
"runtime/src/morph/dataset/conditional/pocket/processing.py": {
|
| 339 |
+
"bytes": 7734,
|
| 340 |
+
"sha256": "eb9059ea7e240995992a86920e9e4e77b1fa6130d63327fa82a86239ff766250"
|
| 341 |
+
},
|
| 342 |
+
"runtime/src/morph/dataset/conditional/pocket/scaffold_pocket.py": {
|
| 343 |
+
"bytes": 5518,
|
| 344 |
+
"sha256": "987fc333b34e3e2d25ed7407a5228696573f1c39ef93901c201f7957dde4fa39"
|
| 345 |
+
},
|
| 346 |
+
"runtime/src/morph/dataset/conditional/replay.py": {
|
| 347 |
+
"bytes": 7061,
|
| 348 |
+
"sha256": "fc8ef66f1be371c4252015d8f4b7e555a976e669cf3b2606a44403552bfc0554"
|
| 349 |
+
},
|
| 350 |
+
"runtime/src/morph/dataset/conditional/scaffold/__init__.py": {
|
| 351 |
+
"bytes": 229,
|
| 352 |
+
"sha256": "ef9b1d37a3a18e820dd1b9afefe1849d066d70cbdd93a02b87c09f76e0a9b3b0"
|
| 353 |
+
},
|
| 354 |
+
"runtime/src/morph/dataset/conditional/scaffold/cutters.py": {
|
| 355 |
+
"bytes": 15539,
|
| 356 |
+
"sha256": "08c3992621a3f930d2595361a86e13280f2f0045c6875eb5c0045ccb9946e5bf"
|
| 357 |
+
},
|
| 358 |
+
"runtime/src/morph/dataset/conditional/scaffold/datamodule.py": {
|
| 359 |
+
"bytes": 2182,
|
| 360 |
+
"sha256": "3a1c4ffb8599970e6fe81cd9d462dcabcb44091e446b4eb045868022cb1b19a1"
|
| 361 |
+
},
|
| 362 |
+
"runtime/src/morph/dataset/conditional/scaffold/libinvent_filter_conditions.json": {
|
| 363 |
+
"bytes": 560,
|
| 364 |
+
"sha256": "ac33112e64f47991be40259aa694219a7f1d47f36a4a130cf329aa98205529b2"
|
| 365 |
+
},
|
| 366 |
+
"runtime/src/morph/dataset/conditional/scaffold/libinvent_reactions.smirks": {
|
| 367 |
+
"bytes": 4272,
|
| 368 |
+
"sha256": "0eaf5444865fef1c5c6d5b87ec97f9480a4765fde97cfa6dbbe57d718f9f74ef"
|
| 369 |
+
},
|
| 370 |
+
"runtime/src/morph/dataset/conditional/scaffold/lmdb.py": {
|
| 371 |
+
"bytes": 4864,
|
| 372 |
+
"sha256": "18ee5fcb3fd7ecad0b0b5e1f2bb25e5196e05e492a5e061ef17139a2efcdadc3"
|
| 373 |
+
},
|
| 374 |
+
"runtime/src/morph/dataset/conditional/scaffold/panel.py": {
|
| 375 |
+
"bytes": 9440,
|
| 376 |
+
"sha256": "54aa9377cfd0b3a6883adc6955b7b7164bfc030a20fd901d75c221f551b61036"
|
| 377 |
+
},
|
| 378 |
+
"runtime/src/morph/dataset/conditional/scaffold/wrappers.py": {
|
| 379 |
+
"bytes": 8473,
|
| 380 |
+
"sha256": "69d58714aef4dbf3d4fb953ff62befc64f021eb9afc5fbc04dd9e7f7f8638ecc"
|
| 381 |
+
},
|
| 382 |
+
"runtime/src/morph/dataset/core/__init__.py": {
|
| 383 |
+
"bytes": 376,
|
| 384 |
+
"sha256": "7bab9c675f0850efc50e14a9898accfde5f8d1c1e2420414ac8c0986822d27e0"
|
| 385 |
+
},
|
| 386 |
+
"runtime/src/morph/dataset/core/atomic_data.py": {
|
| 387 |
+
"bytes": 708,
|
| 388 |
+
"sha256": "7d59ec16ed5b3cf82b57b49dd4d7799862709353a65f4d473d4571ba91b86fa6"
|
| 389 |
+
},
|
| 390 |
+
"runtime/src/morph/dataset/core/batch.py": {
|
| 391 |
+
"bytes": 23924,
|
| 392 |
+
"sha256": "7b2b2afd749b621b1ca890d192e4dc9378b61ead9ef34b90f04dc449e6bad369"
|
| 393 |
+
},
|
| 394 |
+
"runtime/src/morph/dataset/core/containers.py": {
|
| 395 |
+
"bytes": 19637,
|
| 396 |
+
"sha256": "adae656c3fbbe5cfe32f378a419c7e1076f653163ffe7d2c1d1d0abc71a99cd7"
|
| 397 |
+
},
|
| 398 |
+
"runtime/src/morph/dataset/core/conversion.py": {
|
| 399 |
+
"bytes": 2224,
|
| 400 |
+
"sha256": "0842565c503048a86a517c202dd0cc7c07e9296a841601b178ec38c43f903a6a"
|
| 401 |
+
},
|
| 402 |
+
"runtime/src/morph/dataset/core/flow_matching_wrapper.py": {
|
| 403 |
+
"bytes": 8406,
|
| 404 |
+
"sha256": "650d791f765f90f5f86353d3edbeb65f2d44bc9089b9123ec407c970c144beb0"
|
| 405 |
+
},
|
| 406 |
+
"runtime/src/morph/dataset/core/insertion_data.py": {
|
| 407 |
+
"bytes": 14393,
|
| 408 |
+
"sha256": "7e99e4d59b29ea537708b5f7887ed3e61b4b31ebf80d55fe5a0c6823ff8a439c"
|
| 409 |
+
},
|
| 410 |
+
"runtime/src/morph/dataset/core/insertion_targets.py": {
|
| 411 |
+
"bytes": 6614,
|
| 412 |
+
"sha256": "2e62e89125310572735d916e97c8a544cfb3eb76fb167ecd134b5f8b0424df8c"
|
| 413 |
+
},
|
| 414 |
+
"runtime/src/morph/dataset/core/lightning_datamodule.py": {
|
| 415 |
+
"bytes": 7495,
|
| 416 |
+
"sha256": "1facb3c332fd3d306631c84aede122be89b54bafbd17eeab25981b1e4a6af7f3"
|
| 417 |
+
},
|
| 418 |
+
"runtime/src/morph/dataset/core/lmdb.py": {
|
| 419 |
+
"bytes": 10111,
|
| 420 |
+
"sha256": "748b7a10f8fb20f74c267de393cc3e1933ea86debde99d8fdaaef94e0a9afd29"
|
| 421 |
+
},
|
| 422 |
+
"runtime/src/morph/dataset/core/preprocessing.py": {
|
| 423 |
+
"bytes": 20145,
|
| 424 |
+
"sha256": "da9cffd6beb6da63ee749dd8b60d4d0509bcd937778014739b04ffc599dde066"
|
| 425 |
+
},
|
| 426 |
+
"runtime/src/morph/dataset/core/properties.py": {
|
| 427 |
+
"bytes": 1952,
|
| 428 |
+
"sha256": "4dc63574f5fde284245078adf50fb2d8a9ac16443b8276154c03b7703cc2e937"
|
| 429 |
+
},
|
| 430 |
+
"runtime/src/morph/dataset/core/representation.py": {
|
| 431 |
+
"bytes": 6591,
|
| 432 |
+
"sha256": "0ecac55e1faf9748826ec8f4c7f1a274263214ea3f68cc69de7047b55dd6a65f"
|
| 433 |
+
},
|
| 434 |
+
"runtime/src/morph/dataset/core/tokenized_decode.py": {
|
| 435 |
+
"bytes": 6559,
|
| 436 |
+
"sha256": "483afb3d468113da33cc8699998e6439fcde2264ee7ca479724206360584a2b8"
|
| 437 |
+
},
|
| 438 |
+
"runtime/src/morph/dataset/core/vocab.py": {
|
| 439 |
+
"bytes": 2236,
|
| 440 |
+
"sha256": "f8618488f7bcdc8a58d8b9f3443b764eac60985a33ead1bcc2d17d3bdc213329"
|
| 441 |
+
},
|
| 442 |
+
"runtime/src/morph/dataset/unconditional/__init__.py": {
|
| 443 |
+
"bytes": 403,
|
| 444 |
+
"sha256": "d7cd3b85745ad1a4d884c0a11a64b3ab9cedcc64e30f604dbe83f5beb14fa97b"
|
| 445 |
+
},
|
| 446 |
+
"runtime/src/morph/dataset/unconditional/chembl3d.py": {
|
| 447 |
+
"bytes": 9854,
|
| 448 |
+
"sha256": "d5cfd1ee4ddd3085b95b9a678d761d4f0beef99ac5ecfb21d3dfb3cae59653eb"
|
| 449 |
+
},
|
| 450 |
+
"runtime/src/morph/dataset/unconditional/geom.py": {
|
| 451 |
+
"bytes": 4071,
|
| 452 |
+
"sha256": "12bc792c2a61b3e6c29ae265b9997ba610765e268408e873918b5a65225945be"
|
| 453 |
+
},
|
| 454 |
+
"runtime/src/morph/dataset/unconditional/qm9.py": {
|
| 455 |
+
"bytes": 9799,
|
| 456 |
+
"sha256": "a23fdb22e86597ae19cf4b8435f82ffcb9c16c32d0dc729a5ca1019aef8fd78a"
|
| 457 |
+
},
|
| 458 |
+
"runtime/src/morph/flow_matching/__init__.py": {
|
| 459 |
+
"bytes": 78,
|
| 460 |
+
"sha256": "674f4630aa8421d7e75c913741c6efb1a163fbc38ce909c6cdb011f9ba9ef48e"
|
| 461 |
+
},
|
| 462 |
+
"runtime/src/morph/flow_matching/assignment.py": {
|
| 463 |
+
"bytes": 16050,
|
| 464 |
+
"sha256": "b6ad66538f5bd7f14e0eee2a0ffd25a4110d1504e057a0a9eb63a354d9f6aadb"
|
| 465 |
+
},
|
| 466 |
+
"runtime/src/morph/flow_matching/integration.py": {
|
| 467 |
+
"bytes": 33356,
|
| 468 |
+
"sha256": "f64b7b9ed2a79c11932b72e498e57eef924b5c85a05aa6893ddfe11e2d4595e9"
|
| 469 |
+
},
|
| 470 |
+
"runtime/src/morph/flow_matching/interpolation.py": {
|
| 471 |
+
"bytes": 23963,
|
| 472 |
+
"sha256": "81939bb12a705f92394d1d2b78d4cf13b592bb20a129524020cc5236074c8072"
|
| 473 |
+
},
|
| 474 |
+
"runtime/src/morph/flow_matching/prior.py": {
|
| 475 |
+
"bytes": 2389,
|
| 476 |
+
"sha256": "0f9b77274238b23be7a2ad88ee8e6dcbb785817fcfa3a35aa863b489d2a6e05d"
|
| 477 |
+
},
|
| 478 |
+
"runtime/src/morph/flow_matching/sampling_step.py": {
|
| 479 |
+
"bytes": 2806,
|
| 480 |
+
"sha256": "c768682a47da1b7852838e20b39317528717fc0485cbc35030b3ca71d7d845bb"
|
| 481 |
+
},
|
| 482 |
+
"runtime/src/morph/flow_matching/scaffold_insertion.py": {
|
| 483 |
+
"bytes": 2886,
|
| 484 |
+
"sha256": "18e0d7093dfaab98b253d202c4fc4649b8b8de96c9a22144c5eeb5041f73aef8"
|
| 485 |
+
},
|
| 486 |
+
"runtime/src/morph/flow_matching/schedules.py": {
|
| 487 |
+
"bytes": 6776,
|
| 488 |
+
"sha256": "6fd8396a05052ae7831babc75ca40a7e748fb9edffe82bb2559533afa949b2a9"
|
| 489 |
+
},
|
| 490 |
+
"runtime/src/morph/inference/__init__.py": {
|
| 491 |
+
"bytes": 732,
|
| 492 |
+
"sha256": "63047340b4c7ed784e969b7d54035ab737282ee2acc6eeb26ba6cb3d52b4f573"
|
| 493 |
+
},
|
| 494 |
+
"runtime/src/morph/inference/bundles.py": {
|
| 495 |
+
"bytes": 6395,
|
| 496 |
+
"sha256": "f6e2d46e6e428452a58208e78c83da01d6c786f10f7062643a093fb6750dafe6"
|
| 497 |
+
},
|
| 498 |
+
"runtime/src/morph/inference/catalog.py": {
|
| 499 |
+
"bytes": 6215,
|
| 500 |
+
"sha256": "53a27b86d39641fd4964da82f4b1875598a0cdb1533f981074c6b7a14b4174b7"
|
| 501 |
+
},
|
| 502 |
+
"runtime/src/morph/inference/generate.py": {
|
| 503 |
+
"bytes": 11889,
|
| 504 |
+
"sha256": "c3181fbf6187cf22b476431ed7c0fdea4c74ea8e97acf270f486318e43646d19"
|
| 505 |
+
},
|
| 506 |
+
"runtime/src/morph/inference/hub.py": {
|
| 507 |
+
"bytes": 9739,
|
| 508 |
+
"sha256": "fa1f43937d66f0ab4b7b9c11ed749aef8d23444b2df3257c36ff72ecd3b821ca"
|
| 509 |
+
},
|
| 510 |
+
"runtime/src/morph/inference/module.py": {
|
| 511 |
+
"bytes": 3820,
|
| 512 |
+
"sha256": "415e0f9c624c191855874b8dd88d5e7aa18941632bc403a9c0b685bbf74f1d60"
|
| 513 |
+
},
|
| 514 |
+
"runtime/src/morph/inference/registry.py": {
|
| 515 |
+
"bytes": 4314,
|
| 516 |
+
"sha256": "8ca3e4246e00707ed0d646e6e760acebd5e3d3443e5e8d5f71f3b54653993fa9"
|
| 517 |
+
},
|
| 518 |
+
"runtime/src/morph/model/README.md": {
|
| 519 |
+
"bytes": 10319,
|
| 520 |
+
"sha256": "9c06b5b90300f7449048640417116aa8869dc1a75f106cbdd9344a89f6e446d3"
|
| 521 |
+
},
|
| 522 |
+
"runtime/src/morph/model/__init__.py": {
|
| 523 |
+
"bytes": 80,
|
| 524 |
+
"sha256": "1c7c3875387d5ba7f9166a804ea5a7ef7bd469728c1ad5c5003150d44e33be51"
|
| 525 |
+
},
|
| 526 |
+
"runtime/src/morph/model/backbones/__init__.py": {
|
| 527 |
+
"bytes": 64,
|
| 528 |
+
"sha256": "a1a1419590c11aa6ed429f8b6b293470e30fe767f5571d2517b0883efb071e0c"
|
| 529 |
+
},
|
| 530 |
+
"runtime/src/morph/model/backbones/conditional_dit.py": {
|
| 531 |
+
"bytes": 25614,
|
| 532 |
+
"sha256": "15aacd0afd334a6d296556a00e5e8849a5dbf021b37c55f1f96af6c9fe706c80"
|
| 533 |
+
},
|
| 534 |
+
"runtime/src/morph/model/backbones/dit.py": {
|
| 535 |
+
"bytes": 31994,
|
| 536 |
+
"sha256": "7d9e1f25cc4174bb9f2e03f57679c4b2d28a292740e3833ac38870d172bbe805"
|
| 537 |
+
},
|
| 538 |
+
"runtime/src/morph/model/build.py": {
|
| 539 |
+
"bytes": 3442,
|
| 540 |
+
"sha256": "e69f4231815f09c094d787f11edc49e222cbdc970edc6e416b6b94a9b88d4b21"
|
| 541 |
+
},
|
| 542 |
+
"runtime/src/morph/model/finetune/__init__.py": {
|
| 543 |
+
"bytes": 282,
|
| 544 |
+
"sha256": "8746b1e29e5a3b3b1805389257270b90f5d30995783f2cf41b9fb533c485fc0c"
|
| 545 |
+
},
|
| 546 |
+
"runtime/src/morph/model/finetune/base/__init__.py": {
|
| 547 |
+
"bytes": 803,
|
| 548 |
+
"sha256": "6e0ded0b3a5c2a76ccb85b05cf63bcc54e145bd1be07d933a737d6151433d856"
|
| 549 |
+
},
|
| 550 |
+
"runtime/src/morph/model/finetune/base/conditional_backbone.py": {
|
| 551 |
+
"bytes": 2853,
|
| 552 |
+
"sha256": "1353e96443eacf3ce88473a30d02ab4f1c8b6a9c90763ea61c58d353b806b378"
|
| 553 |
+
},
|
| 554 |
+
"runtime/src/morph/model/finetune/base/context_encoder.py": {
|
| 555 |
+
"bytes": 13655,
|
| 556 |
+
"sha256": "095784c710fd921c9da4114dd867df636513a696beece28cfa9a79e1d8193320"
|
| 557 |
+
},
|
| 558 |
+
"runtime/src/morph/model/finetune/base/finetune_base.py": {
|
| 559 |
+
"bytes": 10575,
|
| 560 |
+
"sha256": "06b38586346545b6ff19e689944d4c5a6da04431d0b10eefc58c8ee43e88ef46"
|
| 561 |
+
},
|
| 562 |
+
"runtime/src/morph/model/finetune/pocket/__init__.py": {
|
| 563 |
+
"bytes": 455,
|
| 564 |
+
"sha256": "bd83b0aec910454a989214169a9160ef744ec1f115044fceba8fcb3d1d208edd"
|
| 565 |
+
},
|
| 566 |
+
"runtime/src/morph/model/finetune/pocket/pocket_context.py": {
|
| 567 |
+
"bytes": 2913,
|
| 568 |
+
"sha256": "c9d00636bbaa7ba413f4299894e6db28b82e02680005d261d1f7cb52df26ea91"
|
| 569 |
+
},
|
| 570 |
+
"runtime/src/morph/model/finetune/pocket/scaffold_pocket_context.py": {
|
| 571 |
+
"bytes": 1476,
|
| 572 |
+
"sha256": "7c5e3424c7b68ea1dff5d516c1010e0fd5bb417966262eea3896908b6971847f"
|
| 573 |
+
},
|
| 574 |
+
"runtime/src/morph/model/finetune/scaffold/__init__.py": {
|
| 575 |
+
"bytes": 366,
|
| 576 |
+
"sha256": "6345e71c8b03ee5eb0dcd105c0532acf73a1795bf6360b2847be600bcecd40ba"
|
| 577 |
+
},
|
| 578 |
+
"runtime/src/morph/model/finetune/scaffold/scaffold.py": {
|
| 579 |
+
"bytes": 5643,
|
| 580 |
+
"sha256": "54c27926aff97448521be3cd28e8560dda696ae1f9208dbbe3ad79a8e856597f"
|
| 581 |
+
},
|
| 582 |
+
"runtime/src/morph/model/finetune/scaffold/scaffold_context.py": {
|
| 583 |
+
"bytes": 6086,
|
| 584 |
+
"sha256": "d9446254770e3c3ea2c634a0636ab82a718514a7cb69760d756e9235cfbe2814"
|
| 585 |
+
},
|
| 586 |
+
"runtime/src/morph/model/layers/__init__.py": {
|
| 587 |
+
"bytes": 189,
|
| 588 |
+
"sha256": "79671fbdea358c330a45b7fd3d842119b32b1d548804b3d441bbfb7dbd703b69"
|
| 589 |
+
},
|
| 590 |
+
"runtime/src/morph/model/layers/attention.py": {
|
| 591 |
+
"bytes": 22828,
|
| 592 |
+
"sha256": "366f4b7618097715e5a50acbcf7fae3f1fe7015810e6dfd69ce2e657862cdfba"
|
| 593 |
+
},
|
| 594 |
+
"runtime/src/morph/model/layers/embedding.py": {
|
| 595 |
+
"bytes": 14356,
|
| 596 |
+
"sha256": "efe924190da5904e05495f421dcc313134cebe0dee9bf665060e1e5781cd95ef"
|
| 597 |
+
},
|
| 598 |
+
"runtime/src/morph/model/layers/gmm.py": {
|
| 599 |
+
"bytes": 6753,
|
| 600 |
+
"sha256": "628e90c73bdbb3e70104214f80bbf8a94896ddbe22a9a3fc40cce34b20d2565f"
|
| 601 |
+
},
|
| 602 |
+
"runtime/src/morph/model/layers/heads.py": {
|
| 603 |
+
"bytes": 30913,
|
| 604 |
+
"sha256": "7113c29a6be81c93ca980dc19d0847d2015ac36702683e4f1adedd549aed46ae"
|
| 605 |
+
},
|
| 606 |
+
"runtime/src/morph/model/layers/kernels.py": {
|
| 607 |
+
"bytes": 12483,
|
| 608 |
+
"sha256": "be0c52b69c7612946244755e2865de0491440a41163cf828168eb750a8f929cf"
|
| 609 |
+
},
|
| 610 |
+
"runtime/src/morph/model/layers/lora.py": {
|
| 611 |
+
"bytes": 5947,
|
| 612 |
+
"sha256": "7194750605e7b5df9a02e4c4a39cf29c982f117c40198c99c73211c85ecdfe4b"
|
| 613 |
+
},
|
| 614 |
+
"runtime/src/morph/model/lightning/__init__.py": {
|
| 615 |
+
"bytes": 339,
|
| 616 |
+
"sha256": "c53943a4eb1e45568cebfb538655cc5eb7ead46284bbcd515800102c89177e52"
|
| 617 |
+
},
|
| 618 |
+
"runtime/src/morph/model/lightning/_optimizer.py": {
|
| 619 |
+
"bytes": 19578,
|
| 620 |
+
"sha256": "f77519db8d3458c05aec1543cb4cd487995cf398abcc71b62ea1835cb132165e"
|
| 621 |
+
},
|
| 622 |
+
"runtime/src/morph/model/lightning/_sampling.py": {
|
| 623 |
+
"bytes": 15588,
|
| 624 |
+
"sha256": "ab5f423a6910939552a62c2da645ea1e9afcd763bc8b7e0dbfc75953825a9dca"
|
| 625 |
+
},
|
| 626 |
+
"runtime/src/morph/model/lightning/_setup.py": {
|
| 627 |
+
"bytes": 6537,
|
| 628 |
+
"sha256": "835f510094110c4dbc590a88d9b94d41474ae87b442785a949328feda5b9afce"
|
| 629 |
+
},
|
| 630 |
+
"runtime/src/morph/model/lightning/_training.py": {
|
| 631 |
+
"bytes": 2747,
|
| 632 |
+
"sha256": "2d298e8b0833cce18e4bdef76e67bf81b49a9fdca9920868e2e4083fcc398fc4"
|
| 633 |
+
},
|
| 634 |
+
"runtime/src/morph/model/lightning/_validation.py": {
|
| 635 |
+
"bytes": 12558,
|
| 636 |
+
"sha256": "82c9e1a9e2c54827c7ec92dcdb857c6d2bf050b73416ff028e022c86a2710a75"
|
| 637 |
+
},
|
| 638 |
+
"runtime/src/morph/model/lightning/base.py": {
|
| 639 |
+
"bytes": 9294,
|
| 640 |
+
"sha256": "ce9159e7b387ece0a3ce010b164f675b81980d2f617b5b05d00f96695ee33e28"
|
| 641 |
+
},
|
| 642 |
+
"runtime/src/morph/model/losses/__init__.py": {
|
| 643 |
+
"bytes": 393,
|
| 644 |
+
"sha256": "dc20020e6686703a5b0abd0e77b451fc4beace021f22fd6f92d988a48cb4b526"
|
| 645 |
+
},
|
| 646 |
+
"runtime/src/morph/model/losses/flow.py": {
|
| 647 |
+
"bytes": 21766,
|
| 648 |
+
"sha256": "a8e63b363e8e800c5d22d80454999bd8c5d91bb75ff2f9842800bed8e3377e04"
|
| 649 |
+
},
|
| 650 |
+
"runtime/src/morph/model/losses/functional.py": {
|
| 651 |
+
"bytes": 11765,
|
| 652 |
+
"sha256": "42ae52f604a0cb8b7fe08955cfd273945ca068727994f20b02c80cdee3a00e1b"
|
| 653 |
+
},
|
| 654 |
+
"runtime/src/morph/utils/__init__.py": {
|
| 655 |
+
"bytes": 78,
|
| 656 |
+
"sha256": "eb76ca86f046931eaea693a696317e8b3ce0b8ad8695a92e3744fd1892f2b9b8"
|
| 657 |
+
},
|
| 658 |
+
"runtime/src/morph/utils/checkpoints.py": {
|
| 659 |
+
"bytes": 2301,
|
| 660 |
+
"sha256": "750302eb039e3947a5d4c84e4e7d04eb46e974cc0031ef1d197a3573e20eae4b"
|
| 661 |
+
},
|
| 662 |
+
"runtime/src/morph/utils/edge_alignment.py": {
|
| 663 |
+
"bytes": 4896,
|
| 664 |
+
"sha256": "0edcde93cfa3a2d825e783ea5cf64715aa248e59ffb8c6a23d4490d74976a71e"
|
| 665 |
+
},
|
| 666 |
+
"runtime/src/morph/utils/graph_math.py": {
|
| 667 |
+
"bytes": 6755,
|
| 668 |
+
"sha256": "2bae326c3538d757aac66dcfc4a0b5d023b17bd987d814d3dab9a57f9ce60552"
|
| 669 |
+
},
|
| 670 |
+
"runtime/src/morph/utils/loss_accumulation.py": {
|
| 671 |
+
"bytes": 15115,
|
| 672 |
+
"sha256": "0f3eca42145e715290576dd86f4bcfb1553714ec4cabeda9246cfaf1e4f4323c"
|
| 673 |
+
},
|
| 674 |
+
"runtime/src/morph/utils/lr_schedulers.py": {
|
| 675 |
+
"bytes": 5554,
|
| 676 |
+
"sha256": "b954c12df413ca6676263ef1af960e2a4ff52692acfd4223e72a6e02122a3638"
|
| 677 |
+
},
|
| 678 |
+
"runtime/src/morph/utils/metrics/DIFFDEC_LICENSE": {
|
| 679 |
+
"bytes": 1074,
|
| 680 |
+
"sha256": "729bec7640e96b6357728566e43ac7dec9b7393f15c8ee96edf1e699c00e91f1"
|
| 681 |
+
},
|
| 682 |
+
"runtime/src/morph/utils/metrics/__init__.py": {
|
| 683 |
+
"bytes": 7120,
|
| 684 |
+
"sha256": "ab3cfce2cc6ce7d7cdacedefe91d195c6783e0d6d21762beb6cb4446f47deb32"
|
| 685 |
+
},
|
| 686 |
+
"runtime/src/morph/utils/metrics/chemistry.py": {
|
| 687 |
+
"bytes": 36408,
|
| 688 |
+
"sha256": "db05302c87b6880167be67dc1d5f7b35924bb84f6a7a0b5b32d2d62e54a00735"
|
| 689 |
+
},
|
| 690 |
+
"runtime/src/morph/utils/metrics/denovo.py": {
|
| 691 |
+
"bytes": 26664,
|
| 692 |
+
"sha256": "57517d1124c6067a1682e13f6faa439ecbceb3d8c12ea0d13f6da0db503cd5c9"
|
| 693 |
+
},
|
| 694 |
+
"runtime/src/morph/utils/metrics/diffdec.py": {
|
| 695 |
+
"bytes": 7879,
|
| 696 |
+
"sha256": "37d334fb306afd114de2f50ee4ad5dc48f7565adaa6a077a08e01fc1460599c8"
|
| 697 |
+
},
|
| 698 |
+
"runtime/src/morph/utils/metrics/distribution.py": {
|
| 699 |
+
"bytes": 3348,
|
| 700 |
+
"sha256": "0a6c25c4e65843308059a3effc44e1072837e747926074c1d7c47ba7ee72cb46"
|
| 701 |
+
},
|
| 702 |
+
"runtime/src/morph/utils/metrics/plotting.py": {
|
| 703 |
+
"bytes": 4270,
|
| 704 |
+
"sha256": "686d491d7fbc83cf35f772649a869dc1a271966d2a4fa6162d6e2334db735723"
|
| 705 |
+
},
|
| 706 |
+
"runtime/src/morph/utils/metrics/posebusters_energy.py": {
|
| 707 |
+
"bytes": 3567,
|
| 708 |
+
"sha256": "a705c1baa499a5a4e95329f941f6c762fb49feb505819ed0a35b34daf46ac521"
|
| 709 |
+
},
|
| 710 |
+
"runtime/src/morph/utils/metrics/posecheck_strain.py": {
|
| 711 |
+
"bytes": 6531,
|
| 712 |
+
"sha256": "1fd8340484f542d6a9abce041b8caee20901b9d704bc354f37baf67c76d156a2"
|
| 713 |
+
},
|
| 714 |
+
"runtime/src/morph/utils/metrics/scaffold.py": {
|
| 715 |
+
"bytes": 6312,
|
| 716 |
+
"sha256": "44965940eb17c661734ab0a816123ac5e50a33103aaca217596cca697fd8be6d"
|
| 717 |
+
},
|
| 718 |
+
"runtime/src/morph/utils/metrics/scaffold_posebusters.py": {
|
| 719 |
+
"bytes": 3825,
|
| 720 |
+
"sha256": "d5372df116119a55074cab7ceae085568be4edbb0c932b0961a1ed19bb453f83"
|
| 721 |
+
},
|
| 722 |
+
"runtime/src/morph/utils/metrics/tensor.py": {
|
| 723 |
+
"bytes": 13503,
|
| 724 |
+
"sha256": "3fcb867cde5d47f81725acc3b862fc56af5ecce23dee3a11ebe6d05c1772c6fe"
|
| 725 |
+
},
|
| 726 |
+
"runtime/src/morph/utils/rdkit_utils.py": {
|
| 727 |
+
"bytes": 9053,
|
| 728 |
+
"sha256": "0da70d65eb85d9906e4b611ffa087a870f6133df6ea99a9b21a35b55ad57ffc5"
|
| 729 |
+
},
|
| 730 |
+
"runtime/src/morph/utils/run_config.py": {
|
| 731 |
+
"bytes": 8025,
|
| 732 |
+
"sha256": "0c289120887a051379523af528ebc9310f356f3b92efb898ddaf773dbf698aa2"
|
| 733 |
+
},
|
| 734 |
+
"runtime/src/morph/utils/vocab_utils.py": {
|
| 735 |
+
"bytes": 6343,
|
| 736 |
+
"sha256": "7b5506971b5092865b86311173b24d7fb70a881f123c57fd8696c412a25d618b"
|
| 737 |
+
},
|
| 738 |
+
"runtime/uv.lock": {
|
| 739 |
+
"bytes": 615473,
|
| 740 |
+
"sha256": "4b85cc8b6e28d7fe42533df16cc9633d909fd91296b38b3d8ebce3dbbf8317aa"
|
| 741 |
+
},
|
| 742 |
+
"training_config.yaml": {
|
| 743 |
+
"bytes": 15526,
|
| 744 |
+
"sha256": "7243310c19f0d90399db52845e8ad0446d66e303b64863cbce444058e1bf06bf"
|
| 745 |
+
},
|
| 746 |
+
"training_source.tar.gz": {
|
| 747 |
+
"bytes": 510894,
|
| 748 |
+
"sha256": "f2ee1bf919ad17d664f0614252f43bdcf39b2474e5a1069a37429a520adb8a2f"
|
| 749 |
+
}
|
| 750 |
+
}
|
geom/scaffold_murcko_substituent_lora_r16/metadata.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"task": "scaffold_decoration",
|
| 3 |
+
"dataset": "GEOM-Drugs",
|
| 4 |
+
"hydrogens": "explicit",
|
| 5 |
+
"completed_epochs": 25,
|
| 6 |
+
"checkpoint_epoch_zero_based": 24,
|
| 7 |
+
"global_step": 199100,
|
| 8 |
+
"checkpoint_sha256": "0f3b9d75897c951fdfe437bb10735fb371ea2f5e9ea982471c3c7bd73a160484",
|
| 9 |
+
"checkpoint_bytes": 638268597,
|
| 10 |
+
"original_checkpoint": "/cluster/project/krause/frankem/morph-chem/logs/training/geom-scaffold-substituent-lora-r16-20261012T095326Z/run/every_n_epochs/epoch=24-step=199100.ckpt",
|
| 11 |
+
"training_job_id": 16886672,
|
| 12 |
+
"model": "geom-scaffold-murcko-substituent-lora-r16",
|
| 13 |
+
"lora_rank": 16,
|
| 14 |
+
"lora_alpha": 16,
|
| 15 |
+
"base_model": "geom-explicit-h",
|
| 16 |
+
"base_completed_epochs": 100,
|
| 17 |
+
"base_checkpoint_sha256": "0ab5ad7247b5518858c8cb6aa7c4102352e8fe09cbb6744c33a4c784c85b8587",
|
| 18 |
+
"insertion_assignment": "substituent",
|
| 19 |
+
"freeze_keep_positions": false,
|
| 20 |
+
"freeze_keep_charges": true,
|
| 21 |
+
"default_eval_weights": "ema",
|
| 22 |
+
"integration_steps": 100,
|
| 23 |
+
"original_checkpoint_including_optimizer": true,
|
| 24 |
+
"source_training_archive": "training_source.tar.gz",
|
| 25 |
+
"evaluation_runtime": "runtime",
|
| 26 |
+
"panel_sha256": {
|
| 27 |
+
"val_murcko_512_seed42.json": "b30a2063ba1c74414a2bda387f9dc42ade8c82540d6ec36c58956c12bee64e44",
|
| 28 |
+
"test_murcko_512_seed42.json": "5df2f8b632dd261098ee86581b748487163b10893d2a4462f3e52cd25130905b"
|
| 29 |
+
},
|
| 30 |
+
"evaluation_protocol": {
|
| 31 |
+
"split": "test",
|
| 32 |
+
"n_scaffolds": 512,
|
| 33 |
+
"samples_per_scaffold": 8,
|
| 34 |
+
"seeds": [
|
| 35 |
+
42,
|
| 36 |
+
43,
|
| 37 |
+
44
|
| 38 |
+
]
|
| 39 |
+
},
|
| 40 |
+
"not_unconditional_catalog_entry": true
|
| 41 |
+
}
|
geom/scaffold_murcko_substituent_lora_r16/panels/test_murcko_512_seed42.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
geom/scaffold_murcko_substituent_lora_r16/panels/val_murcko_512_seed42.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
geom/scaffold_murcko_substituent_lora_r16/panels/verification.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"panel": "val_murcko_512_seed42.json",
|
| 3 |
+
"samples": 4096,
|
| 4 |
+
"scaffolds": 512,
|
| 5 |
+
"samples_per_scaffold": 8,
|
| 6 |
+
"two_rank_disjoint_coverage": true,
|
| 7 |
+
"reference_roundtrip_checks": 16,
|
| 8 |
+
"all_reference_retention_rmsd_recovery_checks_passed": true,
|
| 9 |
+
"model_generation_run": false
|
| 10 |
+
}
|
geom/scaffold_murcko_substituent_lora_r16/runtime/README.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Morph
|
| 2 |
+
|
| 3 |
+
Flow-matching molecular generation on QM9, GEOM-Drugs, and ChEMBL3D, including
|
| 4 |
+
scaffold-decoration fine-tuning. A molecular diffusion transformer (DiT)
|
| 5 |
+
predicts clean coordinates, atom and bond types, charges, and edit posteriors.
|
| 6 |
+
The sampler combines those predictions with time schedules to move, insert,
|
| 7 |
+
delete, and substitute atoms and bonds.
|
| 8 |
+
|
| 9 |
+
## Pretrained models
|
| 10 |
+
|
| 11 |
+
[Checkpoints on Hugging Face](https://huggingface.co/maltefranke/morph)
|
| 12 |
+
include QM9 with explicit hydrogens (epochs 1,000 and 1,500), GEOM-Drugs with
|
| 13 |
+
explicit hydrogens (epochs 50 and 100), and ChEMBL3D with explicit hydrogens
|
| 14 |
+
(epochs 200, 300, 400) or implicit hydrogens (epochs 100, 200, 300). Download and generate without preparing a dataset:
|
| 15 |
+
|
| 16 |
+
```bash
|
| 17 |
+
uv sync --locked
|
| 18 |
+
source .venv/bin/activate
|
| 19 |
+
hf auth login
|
| 20 |
+
morph models list
|
| 21 |
+
morph models download chembl3d-implicit-h --epoch 300
|
| 22 |
+
# Run generation on a compute worker:
|
| 23 |
+
morph generate --model chembl3d-implicit-h --epoch 300 \
|
| 24 |
+
--device cuda --batch 64 --batch-size 16 --output molecules.sdf
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
Python loading is equally direct:
|
| 28 |
+
|
| 29 |
+
```python
|
| 30 |
+
from morph.inference import load_pretrained
|
| 31 |
+
|
| 32 |
+
model = load_pretrained("chembl3d-implicit-h", epoch=300, device="cuda")
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
The loader fetches the selected weights, config, vocabularies and distributions
|
| 36 |
+
and constructs only one network (EMA by default; `use_ema=False` selects current
|
| 37 |
+
weights). `morph models list` discovers shortcuts from the Hub's `catalog.json`;
|
| 38 |
+
`--offline` reads the cached catalog. Adding a release requires updating that
|
| 39 |
+
manifest, with each entry pointing to its model release. You can also pass any
|
| 40 |
+
Hugging Face `owner/repo` with `subfolder` and `revision`, or load a local bundle
|
| 41 |
+
with `load_pretrained(weights_dir="/path/to/bundle")`. See [inference](docs/inference.md) for sampling,
|
| 42 |
+
offline use, checkpoint selection and adding new model releases.
|
| 43 |
+
|
| 44 |
+
## Reproducibility
|
| 45 |
+
|
| 46 |
+
Each model has a **training bundle** with its original training configuration,
|
| 47 |
+
launch settings, frozen source, dependency versions and data references.
|
| 48 |
+
The bundles live alongside the corresponding model files on Hugging Face:
|
| 49 |
+
|
| 50 |
+
| Model | Configuration and source |
|
| 51 |
+
| --- | --- |
|
| 52 |
+
| QM9, explicit H | [Training bundle](https://huggingface.co/maltefranke/morph/resolve/main/qm9/explicit_h/training_bundle.tar.gz) |
|
| 53 |
+
| GEOM-Drugs, explicit H | [Training bundle](https://huggingface.co/maltefranke/morph/resolve/main/geom/explicit_h/training_bundle.tar.gz) |
|
| 54 |
+
| ChEMBL3D, explicit H | [Training bundle](https://huggingface.co/maltefranke/morph/resolve/main/chembl3d/explicit_h/training_bundle.tar.gz) |
|
| 55 |
+
| ChEMBL3D, implicit H | [Training bundle](https://huggingface.co/maltefranke/morph/resolve/main/chembl3d/implicit_h/training_bundle.tar.gz) |
|
| 56 |
+
|
| 57 |
+
For example, download and unpack the GEOM training bundle:
|
| 58 |
+
|
| 59 |
+
```bash
|
| 60 |
+
hf download maltefranke/morph geom/explicit_h/training_bundle.tar.gz --local-dir .
|
| 61 |
+
tar -xzf geom/explicit_h/training_bundle.tar.gz
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
Each bundle also includes a portable training recipe; its changes from the
|
| 65 |
+
original run are recorded alongside it. See the [training bundle guide](docs/reproducibility.md)
|
| 66 |
+
for setup, data requirements and resuming. Version identifiers and checksums
|
| 67 |
+
are recorded in the release metadata and bundle manifests.
|
| 68 |
+
|
| 69 |
+
## Training quick start
|
| 70 |
+
|
| 71 |
+
Preprocessed splits, vocabularies, and statistics are available in the public
|
| 72 |
+
[Morph data repository](https://huggingface.co/datasets/maltefranke/morph-data).
|
| 73 |
+
Download a cache into this checkout and skip preprocessing:
|
| 74 |
+
|
| 75 |
+
```bash
|
| 76 |
+
hf download maltefranke/morph-data --type dataset --include 'qm9/**' --local-dir data
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
Replace `qm9/**` with `geom/**`, `chembl3d/**`, `chembl3d_max100/**`, or
|
| 80 |
+
`chembl3d_max100_implicit_h/**` as needed. The released ChEMBL3D checkpoints use
|
| 81 |
+
the two `max100` caches; the dataset card documents the matching training bundles.
|
| 82 |
+
|
| 83 |
+
Install [uv](https://docs.astral.sh/uv/) and use Python 3.11 or newer.
|
| 84 |
+
From the repository root:
|
| 85 |
+
|
| 86 |
+
```bash
|
| 87 |
+
bash setup_env.sh
|
| 88 |
+
source .venv/bin/activate
|
| 89 |
+
source .env
|
| 90 |
+
|
| 91 |
+
# Choose qm9, geom, or chembl3d; the workflow is the same for each.
|
| 92 |
+
dataset=chembl3d
|
| 93 |
+
python scripts/preprocess.py "$dataset"
|
| 94 |
+
python run.py defaults="$dataset/$dataset"
|
| 95 |
+
```
|
| 96 |
+
|
| 97 |
+
Setup installs the versions in `uv.lock` and creates `.env` only when it is
|
| 98 |
+
absent. Local outputs default to `outputs/`. To choose another artifact root,
|
| 99 |
+
set `MORPH_SCRATCH` before running setup. Training uses W&B by default; add
|
| 100 |
+
`logging.enabled=false` for a local run without W&B logging.
|
| 101 |
+
|
| 102 |
+
`scripts/preprocess.py` downloads missing source files into `data/<dataset>/raw/`,
|
| 103 |
+
processes the train/validation/test splits, and computes vocabularies and training
|
| 104 |
+
statistics in `data/<dataset>/processed/`. Rerunning it reuses completed files.
|
| 105 |
+
No manual download or source directory is required. Run preprocessing once on a
|
| 106 |
+
CPU worker before starting distributed training; add `--workers 20` to choose
|
| 107 |
+
the number of preprocessing workers.
|
| 108 |
+
|
| 109 |
+
GEOM and ChEMBL3D support heavy-atom graphs with implicit hydrogens. Choose
|
| 110 |
+
`--hydrogen-mode implicit` when preprocessing, then select the matching recipe:
|
| 111 |
+
|
| 112 |
+
```bash
|
| 113 |
+
python scripts/preprocess.py "$dataset" --hydrogen-mode implicit
|
| 114 |
+
python run.py defaults="$dataset/implicit_h"
|
| 115 |
+
```
|
| 116 |
+
|
| 117 |
+
Set `dataset` to `geom` or `chembl3d` for this option. It uses a separate
|
| 118 |
+
`data/<dataset>_implicit_h/` cache with its own vocabularies and statistics.
|
| 119 |
+
See [training and data options](docs/training.md) for filters and optional local
|
| 120 |
+
source overrides.
|
| 121 |
+
|
| 122 |
+
GPU training compiles both current and EMA models by default. For short smoke
|
| 123 |
+
tests, use `MORPH_COMPILE=0`. The full training defaults require a GPU; a small
|
| 124 |
+
CPU run can be requested explicitly:
|
| 125 |
+
|
| 126 |
+
```bash
|
| 127 |
+
MORPH_COMPILE=0 python run.py logging.enabled=false \
|
| 128 |
+
trainer.trainer.accelerator=cpu trainer.trainer.devices=1 \
|
| 129 |
+
trainer.trainer.strategy=auto integrator.integrator.num_integration_steps=2 \
|
| 130 |
+
trainer.trainer.precision=32-true +trainer.trainer.fast_dev_run=true \
|
| 131 |
+
data.datamodule.num_workers.train=0 data.datamodule.batch_size.train=2 \
|
| 132 |
+
data.datamodule.batch_size.val=2 data.datamodule.batch_size.test=2
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
## Scaffold decoration
|
| 136 |
+
|
| 137 |
+
Fine-tune a pretrained unconditional DiT while conditioning on retained atoms:
|
| 138 |
+
|
| 139 |
+
```bash
|
| 140 |
+
python run.py defaults=qm9/scaffold_decoration \
|
| 141 |
+
model.module.pretrained_ckpt=/path/to/unconditional.ckpt \
|
| 142 |
+
data.scaffold_kind=rgroup
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
Supported retained structures are Murcko scaffolds, BRICS fragments (`rgroup`),
|
| 146 |
+
heavy atoms, and fragments for linker generation. See
|
| 147 |
+
[training and fine-tuning](docs/training.md) for their semantics and LoRA options.
|
| 148 |
+
|
| 149 |
+
## Reading the implementation
|
| 150 |
+
|
| 151 |
+
The main data path is:
|
| 152 |
+
|
| 153 |
+
```text
|
| 154 |
+
Dataset → prior/target alignment → interpolation → collated training batch
|
| 155 |
+
→ DiT endpoint/edit predictions → per-graph losses → optimizer/EMA
|
| 156 |
+
```
|
| 157 |
+
|
| 158 |
+
Sampling repeatedly decodes predictions, applies task masks, integrates edits,
|
| 159 |
+
and recenters coordinates. Output coordinates are restored to Angstroms.
|
| 160 |
+
|
| 161 |
+
| Entry point | Purpose |
|
| 162 |
+
| --- | --- |
|
| 163 |
+
| [run.py](run.py) | Training, validation, and prediction orchestration |
|
| 164 |
+
| [scripts/preprocess.py](scripts/preprocess.py) | Automatic dataset download, processing and statistics |
|
| 165 |
+
| [model/build.py](src/morph/model/build.py) | Shared model and metric construction |
|
| 166 |
+
| [flow_matching/](src/morph/flow_matching/) | Assignment, interpolation, schedules, and integration |
|
| 167 |
+
| [dataset/core/](src/morph/dataset/core/) | Molecular batches and structured insertion targets |
|
| 168 |
+
| [model/lightning/](src/morph/model/lightning/) | Training lifecycle, losses, sampling, and EMA |
|
| 169 |
+
| [configs/](configs/) | Dataset and model recipes |
|
| 170 |
+
| [tests/model/](tests/model/) | Regression tests grouped by subject |
|
| 171 |
+
|
| 172 |
+
The [model contract](src/morph/model/README.md) documents tensor shapes,
|
| 173 |
+
coordinate conventions, conditioning ports, and the loss-to-head mapping.
|
| 174 |
+
|
| 175 |
+
## Further documentation
|
| 176 |
+
|
| 177 |
+
- [Training, configurations, and fine-tuning](docs/training.md)
|
| 178 |
+
- [Inference and model bundles](docs/inference.md)
|
| 179 |
+
- [Reproducing released models and training runs](docs/reproducibility.md)
|
| 180 |
+
- [Runtime, compilation, and performance](docs/performance.md)
|
| 181 |
+
- [Euler cluster setup and SLURM](docs/euler.md)
|
| 182 |
+
- [Development and regression checks](docs/development.md)
|
| 183 |
+
- [Release metadata](docs/release.md)
|
| 184 |
+
|
| 185 |
+
## Citation
|
| 186 |
+
|
| 187 |
+
If you use Morph, please cite our [paper](https://arxiv.org/abs/2606.07239):
|
| 188 |
+
|
| 189 |
+
```bibtex
|
| 190 |
+
@misc{franke2026generativemolecularmorphingflexiblesize,
|
| 191 |
+
title={Generative Molecular Morphing for Flexible-Size Design via Unbalanced Optimal Transport},
|
| 192 |
+
author={Malte Franke and Stefan P. Schmid and Zarko Ivkovic and Kjell Jorner and Andreas Krause},
|
| 193 |
+
year={2026},
|
| 194 |
+
eprint={2606.07239},
|
| 195 |
+
archivePrefix={arXiv},
|
| 196 |
+
primaryClass={cs.LG},
|
| 197 |
+
url={https://arxiv.org/abs/2606.07239},
|
| 198 |
+
}
|
| 199 |
+
```
|
| 200 |
+
|
| 201 |
+
Machine-readable citation metadata is available in [CITATION.cff](CITATION.cff).
|
| 202 |
+
License details are pending.
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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}
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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,''}
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/crossdocked/finetune.yaml
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
defaults:
|
| 2 |
+
- /data/molecular@_here_
|
| 3 |
+
- _self_
|
| 4 |
+
|
| 5 |
+
dataset_name: crossdocked
|
| 6 |
+
dataset_target: morph.dataset.conditional.pocket.CrossDockedPocketDataset
|
| 7 |
+
hydrogen_mode: implicit
|
| 8 |
+
root: ${data.root_path}/crossdocked
|
| 9 |
+
source_dir: ${oc.env:MORPH_CROSSDOCKED_RAW,null}
|
| 10 |
+
pretrained_assets_root: ${oc.env:MORPH_PRETRAINED_ASSETS}
|
| 11 |
+
pretrain_root: ${data.root_path}/chembl3d_implicit_h
|
| 12 |
+
pretrain_source_dir: ${oc.env:CHEMBL3D_SOURCE_DIR,null}
|
| 13 |
+
pretrain_max_atoms: null
|
| 14 |
+
pretrain_allowed_atom_symbols: null
|
| 15 |
+
finetune_fraction: 0.5 # p / 100, sampled per example with replacement
|
| 16 |
+
train_epoch_size: null # source draws per epoch; defaults to retained fine-tuning size
|
| 17 |
+
pocket_vocab: null # Filled from TRAIN pocket elements during datamodule setup.
|
| 18 |
+
max_pocket_atoms: 512
|
| 19 |
+
val_fraction: 0.02
|
| 20 |
+
|
| 21 |
+
# Load the exact artifacts associated with the pretrained checkpoint.
|
| 22 |
+
# Never discover a new ligand vocabulary/normalization for fine-tuning.
|
| 23 |
+
preprocessing:
|
| 24 |
+
root: ${data.pretrained_assets_root}
|
| 25 |
+
train_dataset: null
|
| 26 |
+
atom_tokens_path: ${data.preprocessing.root}/atom_tokens.txt
|
| 27 |
+
edge_tokens_path: ${data.preprocessing.root}/edge_tokens.txt
|
| 28 |
+
charge_tokens_path: ${data.preprocessing.root}/charge_tokens.txt
|
| 29 |
+
distributions_path: ${data.preprocessing.root}/distributions.pt
|
| 30 |
+
|
| 31 |
+
datamodule:
|
| 32 |
+
_target_: morph.dataset.conditional.pocket.datamodule.PocketLightningDataModule
|
| 33 |
+
pocket_vocab: ${data.pocket_vocab}
|
| 34 |
+
finetune_fraction: ${data.finetune_fraction}
|
| 35 |
+
train_epoch_size: ${data.train_epoch_size}
|
| 36 |
+
mix_seed: ${seed}
|
| 37 |
+
pretrain_dataset:
|
| 38 |
+
_target_: morph.dataset.unconditional.chembl3d.FlowMatchingChEMBL3DDataset
|
| 39 |
+
root: ${data.pretrain_root}
|
| 40 |
+
source_dir: ${data.pretrain_source_dir}
|
| 41 |
+
hydrogen_mode: ${data.hydrogen_mode}
|
| 42 |
+
max_atoms: ${data.pretrain_max_atoms}
|
| 43 |
+
allowed_atom_symbols: ${data.pretrain_allowed_atom_symbols}
|
| 44 |
+
preprocess_workers: ${data.preprocess_workers}
|
| 45 |
+
preprocess_chunk_size: ${data.preprocess_chunk_size}
|
| 46 |
+
datasets:
|
| 47 |
+
train:
|
| 48 |
+
root: ${data.root}
|
| 49 |
+
allowed_atom_symbols: null
|
| 50 |
+
max_pocket_atoms: ${data.max_pocket_atoms}
|
| 51 |
+
val_fraction: ${data.val_fraction}
|
| 52 |
+
val:
|
| 53 |
+
- _target_: ${data.dataset_target}
|
| 54 |
+
root: ${data.root}
|
| 55 |
+
source_dir: ${data.source_dir}
|
| 56 |
+
hydrogen_mode: ${data.hydrogen_mode}
|
| 57 |
+
max_pocket_atoms: ${data.max_pocket_atoms}
|
| 58 |
+
val_fraction: ${data.val_fraction}
|
| 59 |
+
preprocess_workers: ${data.preprocess_workers}
|
| 60 |
+
test:
|
| 61 |
+
- _target_: ${data.dataset_target}
|
| 62 |
+
root: ${data.root}
|
| 63 |
+
source_dir: ${data.source_dir}
|
| 64 |
+
hydrogen_mode: ${data.hydrogen_mode}
|
| 65 |
+
max_pocket_atoms: ${data.max_pocket_atoms}
|
| 66 |
+
val_fraction: ${data.val_fraction}
|
| 67 |
+
preprocess_workers: ${data.preprocess_workers}
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/crossdocked/scaffold_decoration.yaml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
defaults:
|
| 2 |
+
- /data/crossdocked/finetune@_here_
|
| 3 |
+
- _self_
|
| 4 |
+
|
| 5 |
+
# Morph's DiffDec task uses LibINVENT reaction cuts. Other shared cutters can
|
| 6 |
+
# be selected explicitly (murcko, rgroup, linker).
|
| 7 |
+
scaffold_kind: libinvent
|
| 8 |
+
scaffold_groups_dir: ${data.root}/scaffold_groups
|
| 9 |
+
enumerate_slicings: true
|
| 10 |
+
# Fixed scaffold/pocket pairs with repeated draws enable retention, recovery,
|
| 11 |
+
# within-condition uniqueness/diversity, RMSD, and scaffold-aware PoseBusters.
|
| 12 |
+
# Unlike a topology-only panel, identical scaffolds in different pockets remain
|
| 13 |
+
# distinct conditions. Splits with fewer pairs use all of them.
|
| 14 |
+
eval_panel:
|
| 15 |
+
n_scaffolds: 512
|
| 16 |
+
samples_per_scaffold: 8
|
| 17 |
+
seed: 42
|
| 18 |
+
# Denoise movable scaffold coordinates; physical Angstroms, training only.
|
| 19 |
+
jitter_scale: 0.1
|
| 20 |
+
insertion_assignment: nearest
|
| 21 |
+
interpolator:
|
| 22 |
+
insertion_assignment: ${data.insertion_assignment}
|
| 23 |
+
jitter_scale: ${data.jitter_scale}
|
| 24 |
+
|
| 25 |
+
datamodule:
|
| 26 |
+
_target_: morph.dataset.conditional.pocket.scaffold_pocket.ScaffoldPocketDataModule
|
| 27 |
+
scaffold_groups_dir: ${data.scaffold_groups_dir}
|
| 28 |
+
scaffold_kind: ${data.scaffold_kind}
|
| 29 |
+
enumerate_slicings: ${data.enumerate_slicings}
|
| 30 |
+
eval_panel: ${data.eval_panel}
|
| 31 |
+
rotate: true
|
geom/scaffold_murcko_substituent_lora_r16/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]
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/geom/scaffold_decoration.yaml
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 decoration atoms while denoising the retained 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 |
+
# Physical Angstroms, per coordinate axis. Used only by training interpolation.
|
| 19 |
+
jitter_scale: 0.1
|
| 20 |
+
# "substituent" restricts insertion parents to the target branch or its
|
| 21 |
+
# scaffold attachments. This changes training supervision, not atom OT.
|
| 22 |
+
insertion_assignment: nearest
|
| 23 |
+
interpolator:
|
| 24 |
+
jitter_scale: ${data.jitter_scale}
|
| 25 |
+
insertion_assignment: ${data.insertion_assignment}
|
| 26 |
+
# Exhaustive evaluation when eval_panel=null; training always draws randomly.
|
| 27 |
+
enumerate_slicings: false
|
| 28 |
+
eval_panel:
|
| 29 |
+
directory: ${data.scaffold_groups_dir}/eval_panels
|
| 30 |
+
n_scaffolds: 512
|
| 31 |
+
samples_per_scaffold: 8
|
| 32 |
+
seed: 42
|
| 33 |
+
datamodule:
|
| 34 |
+
_target_: morph.dataset.conditional.scaffold.datamodule.ScaffoldLightningDataModule
|
| 35 |
+
scaffold_groups_dir: ${data.scaffold_groups_dir}
|
| 36 |
+
scaffold_kind: ${data.scaffold_kind}
|
| 37 |
+
enumerate_slicings: ${data.enumerate_slicings}
|
| 38 |
+
eval_panel: ${data.eval_panel}
|
geom/scaffold_murcko_substituent_lora_r16/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}
|
geom/scaffold_murcko_substituent_lora_r16/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}
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/data/qm9/scaffold_decoration.yaml
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
# while denoising the retained 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 |
+
# Physical Angstroms, per coordinate axis. Used only by training interpolation.
|
| 17 |
+
jitter_scale: 0.1
|
| 18 |
+
interpolator:
|
| 19 |
+
jitter_scale: ${data.jitter_scale}
|
| 20 |
+
# Exhaustive evaluation when eval_panel=null; training always draws randomly.
|
| 21 |
+
enumerate_slicings: false
|
| 22 |
+
eval_panel:
|
| 23 |
+
directory: ${data.scaffold_groups_dir}/eval_panels
|
| 24 |
+
n_scaffolds: 512
|
| 25 |
+
samples_per_scaffold: 8
|
| 26 |
+
seed: 42
|
| 27 |
+
datamodule:
|
| 28 |
+
_target_: morph.dataset.conditional.scaffold.datamodule.ScaffoldLightningDataModule
|
| 29 |
+
scaffold_groups_dir: ${data.scaffold_groups_dir}
|
| 30 |
+
scaffold_kind: ${data.scaffold_kind}
|
| 31 |
+
enumerate_slicings: ${data.enumerate_slicings}
|
| 32 |
+
eval_panel: ${data.eval_panel}
|
geom/scaffold_murcko_substituent_lora_r16/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}
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/crossdocked/finetune.yaml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# @package _global_
|
| 2 |
+
defaults:
|
| 3 |
+
- /defaults/core
|
| 4 |
+
- /data: crossdocked/finetune
|
| 5 |
+
- /embeddings: geom
|
| 6 |
+
- override /model: finetune/pocket_finetune
|
| 7 |
+
- _self_
|
| 8 |
+
|
| 9 |
+
trainer:
|
| 10 |
+
trainer:
|
| 11 |
+
# ReplaySampler already partitions its stream between DDP ranks.
|
| 12 |
+
use_distributed_sampler: false
|
| 13 |
+
check_val_every_n_epoch: 1
|
| 14 |
+
|
| 15 |
+
logging:
|
| 16 |
+
project: morph-crossdocked-finetune
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/crossdocked/scaffold_decoration.yaml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# @package _global_
|
| 2 |
+
defaults:
|
| 3 |
+
- /defaults/crossdocked/finetune
|
| 4 |
+
- override /data: crossdocked/scaffold_decoration
|
| 5 |
+
- override /model: finetune/scaffold_pocket_finetune
|
| 6 |
+
- _self_
|
| 7 |
+
|
| 8 |
+
logging:
|
| 9 |
+
project: morph-crossdocked-scaffold-finetune
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/crossdocked/scaffold_decoration_2x4090.yaml
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# @package _global_
|
| 2 |
+
defaults:
|
| 3 |
+
- /defaults/crossdocked/scaffold_decoration
|
| 4 |
+
- _self_
|
| 5 |
+
|
| 6 |
+
data:
|
| 7 |
+
pretrain_root: ${data.root_path}/chembl3d_max100_implicit_h
|
| 8 |
+
pretrain_max_atoms: 100
|
| 9 |
+
finetune_fraction: 0.5
|
| 10 |
+
# 400 optimizer updates per epoch at global batch 256.
|
| 11 |
+
train_epoch_size: 102400
|
| 12 |
+
datamodule:
|
| 13 |
+
train_prefetch_factor: 1
|
| 14 |
+
batch_size:
|
| 15 |
+
train: 32
|
| 16 |
+
val: 8
|
| 17 |
+
test: 8
|
| 18 |
+
num_workers:
|
| 19 |
+
train: 6
|
| 20 |
+
val: 2
|
| 21 |
+
test: 2
|
| 22 |
+
|
| 23 |
+
model:
|
| 24 |
+
module:
|
| 25 |
+
# LoRA, conditioning modules, and complete prediction heads train with replay.
|
| 26 |
+
# Peak Muon/Adam rates are inherited from scaffold_pocket_finetune.
|
| 27 |
+
optimizer_config:
|
| 28 |
+
scheduler:
|
| 29 |
+
warmup_steps: 1000
|
| 30 |
+
total_steps: 40000
|
| 31 |
+
|
| 32 |
+
trainer:
|
| 33 |
+
trainer:
|
| 34 |
+
accelerator: gpu
|
| 35 |
+
devices: 2
|
| 36 |
+
accumulate_grad_batches: 4
|
| 37 |
+
max_epochs: 100
|
| 38 |
+
check_val_every_n_epoch: 5
|
| 39 |
+
# Evaluate the complete repeated panel; truncation biases conditional scores.
|
| 40 |
+
num_val_samples: null
|
| 41 |
+
do_validate: false
|
| 42 |
+
do_predict: false
|
| 43 |
+
final_checkpoint_path: final.ckpt
|
| 44 |
+
|
| 45 |
+
callbacks:
|
| 46 |
+
model_checkpoints:
|
| 47 |
+
every_n_epochs: 5
|
| 48 |
+
every_n_epochs_checkpoint:
|
| 49 |
+
every_n_epochs: 5
|
| 50 |
+
save_top_k: -1
|
| 51 |
+
save_last: link
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/geom/scaffold_decoration.yaml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 while allowing scaffold coordinates to move.
|
| 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 |
+
- /defaults/core
|
| 20 |
+
- /data: geom/scaffold_decoration
|
| 21 |
+
- /embeddings: geom
|
| 22 |
+
- override /model: finetune/scaffold_finetune
|
| 23 |
+
- _self_
|
| 24 |
+
|
| 25 |
+
# Evaluate each completed epoch; retain checkpoints every five epochs.
|
| 26 |
+
trainer:
|
| 27 |
+
trainer:
|
| 28 |
+
check_val_every_n_epoch: 1
|
| 29 |
+
|
| 30 |
+
callbacks:
|
| 31 |
+
model_checkpoints:
|
| 32 |
+
every_n_epochs: 5
|
| 33 |
+
every_n_epochs_checkpoint:
|
| 34 |
+
every_n_epochs: 5
|
| 35 |
+
save_top_k: -1
|
| 36 |
+
save_last: link
|
| 37 |
+
|
| 38 |
+
logging:
|
| 39 |
+
project: morph-${data.dataset_name}-scaffold-decoration
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/geom/scaffold_decoration_2x4090.yaml
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# @package _global_
|
| 2 |
+
defaults:
|
| 3 |
+
- /defaults/geom/scaffold_decoration
|
| 4 |
+
- _self_
|
| 5 |
+
|
| 6 |
+
# Starting point for future GEOM scaffold runs on two 24-GiB GPUs.
|
| 7 |
+
# The epoch-100 Murcko runs used 160/GPU with accumulation 2; reported GPU
|
| 8 |
+
# memory usage was only 33% (full) / 29% (LoRA). Double the microbatch while
|
| 9 |
+
# preserving the effective batch: 2 GPUs * 320 * 1 = 640.
|
| 10 |
+
# Profile peak memory and throughput before choosing still larger batches.
|
| 11 |
+
data:
|
| 12 |
+
datamodule:
|
| 13 |
+
train_prefetch_factor: 1
|
| 14 |
+
batch_size:
|
| 15 |
+
train: 320
|
| 16 |
+
val: 32
|
| 17 |
+
test: 32
|
| 18 |
+
num_workers:
|
| 19 |
+
train: 20
|
| 20 |
+
val: 0
|
| 21 |
+
test: 0
|
| 22 |
+
|
| 23 |
+
trainer:
|
| 24 |
+
trainer:
|
| 25 |
+
accelerator: gpu
|
| 26 |
+
devices: 2
|
| 27 |
+
accumulate_grad_batches: 1
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/geom/scaffold_decoration_scratch_2x4090.yaml
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# @package _global_
|
| 2 |
+
# Train GEOM-Drugs Murcko decoration from scratch, using the scaffold protocol.
|
| 3 |
+
defaults:
|
| 4 |
+
- /defaults/geom/scaffold_decoration_2x4090
|
| 5 |
+
- _self_
|
| 6 |
+
|
| 7 |
+
seed: 42
|
| 8 |
+
|
| 9 |
+
data:
|
| 10 |
+
scaffold_kind: murcko
|
| 11 |
+
jitter_scale: 0.1
|
| 12 |
+
|
| 13 |
+
model:
|
| 14 |
+
module:
|
| 15 |
+
pretrained_ckpt: null
|
| 16 |
+
freeze_pretrained_backbone: false
|
| 17 |
+
freeze_output_heads: false
|
| 18 |
+
freeze_keep_positions: false
|
| 19 |
+
exclude_scaffold_from_x_loss: false
|
| 20 |
+
optimizer_config:
|
| 21 |
+
optimizer:
|
| 22 |
+
lr: 1e-3
|
| 23 |
+
aux_optimizer:
|
| 24 |
+
lr: 1e-4
|
| 25 |
+
lora:
|
| 26 |
+
enabled: false
|
| 27 |
+
freeze_base: false
|
| 28 |
+
|
| 29 |
+
trainer:
|
| 30 |
+
trainer:
|
| 31 |
+
max_epochs: 50
|
| 32 |
+
check_val_every_n_epoch: 1
|
| 33 |
+
num_val_samples: 4096
|
| 34 |
+
enable_progress_bar: false
|
| 35 |
+
max_time:
|
| 36 |
+
hours: 47
|
| 37 |
+
checkpoint_path: null
|
| 38 |
+
final_checkpoint_path: final.ckpt
|
| 39 |
+
do_validate: false
|
| 40 |
+
do_predict: false
|
| 41 |
+
|
| 42 |
+
logging:
|
| 43 |
+
group: geom-murcko-scratch
|
| 44 |
+
tags: [geom, explicit-h, murcko, scaffold-decoration, scratch, full-model, movable, jitter-0.1A]
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/runtime/configs/defaults/qm9/scaffold_decoration.yaml
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 while scaffold coordinates may move.
|
| 6 |
+
defaults:
|
| 7 |
+
- core
|
| 8 |
+
- /data: qm9/scaffold_decoration
|
| 9 |
+
- /embeddings: qm9
|
| 10 |
+
- override /model: finetune/scaffold_finetune
|
| 11 |
+
- _self_
|
| 12 |
+
|
| 13 |
+
# Evaluate each completed epoch; retain checkpoints every five epochs.
|
| 14 |
+
trainer:
|
| 15 |
+
trainer:
|
| 16 |
+
check_val_every_n_epoch: 1
|
| 17 |
+
|
| 18 |
+
callbacks:
|
| 19 |
+
model_checkpoints:
|
| 20 |
+
every_n_epochs: 5
|
| 21 |
+
every_n_epochs_checkpoint:
|
| 22 |
+
every_n_epochs: 5
|
| 23 |
+
save_top_k: -1
|
| 24 |
+
save_last: link
|
| 25 |
+
|
| 26 |
+
logging:
|
| 27 |
+
project: morph-${data.dataset_name}-scaffold-decoration
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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
|
geom/scaffold_murcko_substituent_lora_r16/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}}
|
geom/scaffold_murcko_substituent_lora_r16/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}}
|