NealKapadia commited on
Commit
4fa42ce
·
verified ·
1 Parent(s): c3cfe9c

Upload folder using huggingface_hub

Browse files
README.md CHANGED
@@ -1,3 +1,118 @@
1
  ---
2
  license: mit
 
 
 
 
 
 
 
 
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  license: mit
3
+ library_name: pytorch
4
+ tags:
5
+ - chemistry
6
+ - molecule-generation
7
+ - generative-model
8
+ - vae
9
+ - selfies
10
+ - rdkit
11
+ - drug-discovery
12
+ - electrolyte
13
+ - batteries
14
+ - cheminformatics
15
  ---
16
+
17
+ # MolForge — a conditional SELFIES-VAE for de-novo molecule & battery-electrolyte design
18
+
19
+ MolForge is a ~42M-parameter **conditional variational autoencoder** over
20
+ [SELFIES](https://github.com/aspuru-guzik-group/selfies) string representations of
21
+ molecules. It learns a smooth 256-dimensional latent space you can **sample, traverse,
22
+ and optimize**, and because it decodes SELFIES, **~100% of generated strings are valid
23
+ molecules**. It was built for de-novo design of drug-like molecules and, in particular,
24
+ **battery-electrolyte solvents / additives** across chemistries (Li / Na / K / Mg / Zn / …).
25
+
26
+ - **Code / library:** https://github.com/NealKapadia/molforge
27
+ - **Weights (this repo):** `checkpoints/best.pt`
28
+ - **Architecture:** embedding 512 → bidirectional GRU encoder (1024 × 2 layers) →
29
+ latent 256 → GRU decoder (1024 × 2 layers), conditioned on **11 RDKit descriptors**,
30
+ with an auxiliary latent→property head. Decoder word-dropout 0.25 (Bowman et al.) for a
31
+ meaningful latent. SELFIES robust alphabet, 79 tokens, max length 120.
32
+ - **Training data:** the Molport "All Stock" compound catalog (~6.1M drug-like molecules
33
+ after filtering: heavy atoms 3–60, organic element set). Validity-critical fix: trained
34
+ with the **default** SELFIES constraints (S=6 / P=5 allowed) so sulfonyl/phosphate
35
+ electrolyte motifs round-trip.
36
+ - **Selected checkpoint:** `best.pt` = early-stopped epoch (~12M molecules seen), selected by
37
+ `val_token_acc + 0.25·valid_rate`.
38
+
39
+ ## Conditioning properties (fixed order)
40
+
41
+ `MolWt, MolLogP, TPSA, QED, NumHDonors, NumHAcceptors, NumRotatableBonds, NumAromaticRings, NumRings, FractionCSP3, HeavyAtomCount`
42
+
43
+ ## Evaluation (best.pt, 5,000 samples @ temperature 0.9)
44
+
45
+ | Metric | Value |
46
+ |---|---|
47
+ | Validity | **1.000** |
48
+ | Uniqueness | 0.998 |
49
+ | Novelty (vs. training set) | 0.995 |
50
+ | Internal diversity | 0.894 |
51
+ | Reconstruction (exact) | 0.945 |
52
+ | Reconstruction (token acc) | 0.998 |
53
+
54
+ Latent→property head R² (held-out): MolWt 0.994, TPSA 0.977, MolLogP 0.962,
55
+ NumHAcceptors / NumRotatableBonds 0.969, QED 0.926, NumHDonors 0.922.
56
+
57
+ > On the standard generative benchmark columns (validity / uniqueness / novelty /
58
+ > diversity) this model is competitive with — and on several columns exceeds — the
59
+ > autoregressive **ElectrolyteGPT** (Kim et al., *JACS Au*, 2026, 6, 2288–2302). The
60
+ > structural advantage is the **latent space**: smooth interpolation and gradient-based
61
+ > property optimization, which a left-to-right token model does not offer.
62
+
63
+ ## Files
64
+
65
+ ```
66
+ checkpoints/best.pt # the SELFIES-VAE generator weights
67
+ checkpoints/electrolyte_model.pt # optional: formulation property model (conductivity etc.)
68
+ processed/vocab.json # SELFIES token vocabulary
69
+ processed/descriptor_stats.json # descriptor normalization (mean/std)
70
+ processed/meta.json # vocab size, max length, property order, constraints
71
+ ```
72
+
73
+ This is exactly the layout the `molforge` library expects under `MOLVAE_ART_DIR`.
74
+
75
+ ## Usage
76
+
77
+ ```bash
78
+ pip install "git+https://github.com/NealKapadia/molforge.git"
79
+ ```
80
+
81
+ ```python
82
+ from huggingface_hub import snapshot_download
83
+ from molforge import MolForge
84
+
85
+ art = snapshot_download("NealKapadia/Molforge") # downloads checkpoints/ + processed/
86
+ mf = MolForge(device="cpu", artifacts_dir=art) # or device="cuda"
87
+
88
+ mf.generate(10) # 10 valid, novel SMILES
89
+ mf.generate(5, spec={"MolWt": 250, "QED": 0.8}) # property-targeted
90
+ z = mf.encode("OCCN(CCO)CCO"); mf.decode(z) # latent round-trip
91
+ mf.properties("CCO") # RDKit descriptors
92
+ ```
93
+
94
+ Or set the path manually instead of `artifacts_dir=`:
95
+ `export MOLVAE_ART_DIR=/path/to/download` (Windows: `$env:MOLVAE_ART_DIR="..."`).
96
+
97
+ ## Limitations & intended use
98
+
99
+ - **Research / educational use** for molecular design and screening — **not** a substitute
100
+ for experimental validation, synthesis feasibility, or safety assessment.
101
+ - **Soft conditioning:** `spec` targets nudge generation toward a value; they are not exact.
102
+ For hard constraints, over-generate and filter by RDKit-computed properties.
103
+ - The base generator is **drug-like**; very small electrolyte molecules (EC/DEC/MeCN) are
104
+ somewhat out-of-distribution for the base checkpoint.
105
+ - The electrolyte property model has labeled data for **Li / Na / K** only; the generator
106
+ proposes candidates for any chemistry, but quantitative ranking beyond Li/Na/K needs
107
+ additional labeled data.
108
+
109
+ ## Training data & license
110
+
111
+ Trained on structures from the **Molport "All Stock"** catalog. Please review Molport's
112
+ terms for the underlying catalog data. The weights and code are released under the license
113
+ declared in the metadata above — **confirm/replace this license before relying on it**.
114
+
115
+ ## Citation
116
+
117
+ If you use MolForge, please cite this repository and the SELFIES paper
118
+ (Krenn et al., *Mach. Learn.: Sci. Technol.* 2020).
checkpoints/best.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7fd88d8b1b0fb049dd3a006d9b1746d1f543bbffe5158550c9401c1ceb460ed8
3
+ size 503633904
checkpoints/electrolyte_model.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3dd43f5a5626969616fc8b5db142d0f40331a333d5ea157eba7d6f8869ffc8c6
3
+ size 828396
processed/descriptor_stats.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"properties": ["MolWt", "MolLogP", "TPSA", "QED", "NumHDonors", "NumHAcceptors", "NumRotatableBonds", "NumAromaticRings", "NumRings", "FractionCSP3", "HeavyAtomCount"], "mean": [365.96527099609375, 3.1327805519104004, 70.4820556640625, 0.640363872051239, 1.0642004013061523, 4.472788333892822, 4.757150173187256, 2.3169329166412354, 3.2396657466888428, 0.345050185918808, 25.594316482543945], "std": [93.11808776855469, 1.6074011325836182, 27.75464630126953, 0.18775396049022675, 0.9152066111564636, 1.7360092401504517, 2.4416964054107666, 1.108630895614624, 1.2000303268432617, 0.2074769288301468, 6.741006851196289]}
processed/meta.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "shards": [
3
+ "shard_000",
4
+ "shard_001",
5
+ "shard_002",
6
+ "shard_003",
7
+ "shard_004",
8
+ "shard_005",
9
+ "shard_006",
10
+ "shard_007",
11
+ "shard_008",
12
+ "shard_009",
13
+ "shard_010",
14
+ "shard_011",
15
+ "shard_012",
16
+ "shard_013",
17
+ "shard_014",
18
+ "shard_015"
19
+ ],
20
+ "total": 7116053,
21
+ "max_len": 120,
22
+ "vocab_size": 79,
23
+ "properties": [
24
+ "MolWt",
25
+ "MolLogP",
26
+ "TPSA",
27
+ "QED",
28
+ "NumHDonors",
29
+ "NumHAcceptors",
30
+ "NumRotatableBonds",
31
+ "NumAromaticRings",
32
+ "NumRings",
33
+ "FractionCSP3",
34
+ "HeavyAtomCount"
35
+ ],
36
+ "constraints": "default"
37
+ }
processed/vocab.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"itos": ["<pad>", "<bos>", "<eos>", "<unk>", "[#B-1]", "[#B]", "[#Br]", "[#Branch1]", "[#Branch2]", "[#Branch3]", "[#C+1]", "[#C-1]", "[#C]", "[#Cl]", "[#I]", "[#N+1]", "[#N]", "[#O+1]", "[#P+1]", "[#P-1]", "[#P]", "[#S+1]", "[#S-1]", "[#S]", "[=B+1]", "[=B-1]", "[=B]", "[=Br]", "[=Branch1]", "[=Branch2]", "[=Branch3]", "[=C+1]", "[=C-1]", "[=C]", "[=Cl]", "[=I]", "[=N+1]", "[=N-1]", "[=N]", "[=O+1]", "[=O]", "[=P+1]", "[=P-1]", "[=P]", "[=Ring1]", "[=Ring2]", "[=Ring3]", "[=S+1]", "[=S-1]", "[=S]", "[B+1]", "[B-1]", "[B]", "[Br]", "[Branch1]", "[Branch2]", "[Branch3]", "[C+1]", "[C-1]", "[C]", "[Cl]", "[F]", "[H]", "[I]", "[N+1]", "[N-1]", "[N]", "[O+1]", "[O-1]", "[O]", "[P+1]", "[P-1]", "[P]", "[Ring1]", "[Ring2]", "[Ring3]", "[S+1]", "[S-1]", "[S]"], "constraints": "hypervalent", "max_len": 120}