Joblib
yinuozhang commited on
Commit
adff1ee
·
1 Parent(s): e769c8d

tested light download

Browse files
Files changed (2) hide show
  1. download_light.py +71 -44
  2. inference.py +14 -16
download_light.py CHANGED
@@ -1,23 +1,23 @@
1
  #!/usr/bin/env python3
2
  from __future__ import annotations
3
 
4
- import os
5
  from pathlib import Path
6
- from typing import Dict, List, Optional, Tuple
7
 
8
  from huggingface_hub import snapshot_download
9
  from inference import (
10
  PeptiVersePredictor,
11
  read_best_manifest_csv,
12
- canon_model,
 
13
  )
14
 
15
  # -----------------------------
16
  # Config
17
  # -----------------------------
18
- root = Path(__file__).resolve().parent # current script folder
19
- MODEL_REPO = "ChatterjeeLab/PeptiVerse"
20
- DEFAULT_ASSETS_DIR = Path(root) # where downloaded models live
21
  DEFAULT_MANIFEST = Path("./basic_models.txt")
22
 
23
  BANNED_MODELS = {"svm", "enet", "svm_gpu", "enet_gpu"}
@@ -26,25 +26,41 @@ BANNED_MODELS = {"svm", "enet", "svm_gpu", "enet_gpu"}
26
  def _norm_prop_disk(prop_key: str) -> str:
27
  return "half_life" if prop_key == "halflife" else prop_key
28
 
29
- def _resolve_expected_model_dir(prop_key: str, model_name: str, mode: str) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
30
  disk_prop = _norm_prop_disk(prop_key)
31
  base = f"training_classifiers/{disk_prop}"
32
 
33
- # binding affinity is special: its label is pooled/unpooled and folder uses wt_<mode>_<pooled|unpooled>
 
34
  if prop_key == "binding_affinity":
35
- pooled_or_unpooled = model_name # "pooled" or "unpooled"
36
- return f"{base}/wt_{mode}_{pooled_or_unpooled}"
37
-
38
- # halflife special folders
39
- if prop_key == "halflife":
40
- if model_name in {"xgb_wt_log", "xgb_smiles"}:
41
- return f"{base}/{model_name}"
42
- if mode == "wt" and model_name == "transformer":
43
  return f"{base}/transformer_wt_log"
44
- if model_name == "xgb":
45
- return f"{base}/{'xgb_wt_log' if mode == 'wt' else 'xgb_smiles'}"
46
 
47
- return f"{base}/{model_name}_{mode}"
 
 
 
 
48
 
49
 
50
  def build_allow_patterns_from_manifest(manifest_path: Path) -> List[str]:
@@ -52,19 +68,19 @@ def build_allow_patterns_from_manifest(manifest_path: Path) -> List[str]:
52
 
53
  allow: List[str] = []
54
 
55
- # For each property, fetch best artifacts for wt + smiles
56
  for prop_key, row in best.items():
57
- for mode, label in [("wt", row.best_wt), ("smiles", row.best_smiles)]:
58
- m = canon_model(label)
59
- if m is None:
60
  continue
61
 
62
- if m in BANNED_MODELS:
63
- m = "xgb"
64
 
65
- model_dir = _resolve_expected_model_dir(prop_key, m, mode)
 
 
 
 
66
 
67
- # fetch only "basic" artifacts, not everything in the folder
68
  allow += [
69
  f"{model_dir}/best_model.json",
70
  f"{model_dir}/best_model.pt",
@@ -72,6 +88,7 @@ def build_allow_patterns_from_manifest(manifest_path: Path) -> List[str]:
72
  f"{model_dir}/best_model*.json",
73
  ]
74
 
 
75
  seen = set()
76
  out = []
77
  for p in allow:
@@ -106,41 +123,51 @@ def download_assets(
106
  def main():
107
  import argparse
108
 
109
- ap = argparse.ArgumentParser(description="Lightweight PeptiVerse inference with on-demand model download.")
110
- ap.add_argument("--repo", default=MODEL_REPO, help="HF repo id containing weights/assets.")
111
- ap.add_argument("--manifest", default=str(DEFAULT_MANIFEST), help="Path to best_models.txt")
112
- ap.add_argument("--assets", default=str(DEFAULT_ASSETS_DIR), help="Where to store downloaded assets")
113
- ap.add_argument("--device", default=None, help="cuda / cpu / cuda:0, etc")
114
-
115
- ap.add_argument("--property", default="hemolysis", help="Property key (e.g. hemolysis, solubility, ...)")
116
- ap.add_argument("--mode", default="wt", choices=["wt", "smiles"], help="Input type: wt=AA sequence, smiles=SMILES")
117
- ap.add_argument("--input", default="GIGAVLKVLTTGLPALISWIKRKRQQ", help="Sequence or SMILES string")
118
- ap.add_argument("--target_seq", default=None, help="Target WT sequence for binding_affinity")
119
- ap.add_argument("--binder", default=None, help="Binder string (AA or SMILES) for binding_affinity")
 
 
 
120
  args = ap.parse_args()
121
 
122
  manifest_path = Path(args.manifest)
123
  if not manifest_path.exists():
124
  raise FileNotFoundError(f"Manifest not found: {manifest_path}")
125
 
126
- assets_dir = download_assets(args.repo, manifest_path=manifest_path, out_dir=Path(args.assets))
 
 
 
 
 
 
 
 
 
127
 
128
- """ OPTIONAL TEST CODE
129
  predictor = PeptiVersePredictor(
130
- manifest_path="basic_models.txt", # use the downloaded copy to be consistent
131
  classifier_weight_root=str(assets_dir),
132
  device=args.device,
133
  )
134
-
135
  if args.property == "binding_affinity":
136
  if not args.target_seq or not args.binder:
137
  raise ValueError("For binding_affinity, provide --target_seq and --binder.")
138
  out = predictor.predict_binding_affinity(args.mode, target_seq=args.target_seq, binder_str=args.binder)
139
  else:
140
  out = predictor.predict_property(args.property, args.mode, args.input)
141
-
142
  print(out)
143
  """
144
 
145
  if __name__ == "__main__":
146
- main()
 
1
  #!/usr/bin/env python3
2
  from __future__ import annotations
3
 
 
4
  from pathlib import Path
5
+ from typing import List, Optional, Tuple
6
 
7
  from huggingface_hub import snapshot_download
8
  from inference import (
9
  PeptiVersePredictor,
10
  read_best_manifest_csv,
11
+ _parse_model_and_emb,
12
+ EMB_TAG_TO_FOLDER_SUFFIX,
13
  )
14
 
15
  # -----------------------------
16
  # Config
17
  # -----------------------------
18
+ root = Path(__file__).resolve().parent
19
+ MODEL_REPO = "ChatterjeeLab/PeptiVerse"
20
+ DEFAULT_ASSETS_DIR = Path(root)
21
  DEFAULT_MANIFEST = Path("./basic_models.txt")
22
 
23
  BANNED_MODELS = {"svm", "enet", "svm_gpu", "enet_gpu"}
 
26
  def _norm_prop_disk(prop_key: str) -> str:
27
  return "half_life" if prop_key == "halflife" else prop_key
28
 
29
+
30
+ def _resolve_expected_model_dir(
31
+ prop_key: str, model_name: str, emb_tag: Optional[str]
32
+ ) -> str:
33
+ """
34
+ Resolve the subfolder path inside training_classifiers/<property>/.
35
+
36
+ Args:
37
+ prop_key: manifest property key, e.g. 'hemolysis', 'halflife'.
38
+ model_name: canonical model string, e.g. 'xgb', 'cnn', 'transformer'.
39
+ emb_tag: embedding tag from manifest: 'wt', 'peptideclm', or 'chemberta'.
40
+ None means WT (falls back to 'wt').
41
+ """
42
  disk_prop = _norm_prop_disk(prop_key)
43
  base = f"training_classifiers/{disk_prop}"
44
 
45
+ folder_suffix = EMB_TAG_TO_FOLDER_SUFFIX.get(emb_tag or "wt", emb_tag or "wt")
46
+
47
  if prop_key == "binding_affinity":
48
+ return f"{base}/{model_name}"
49
+
50
+ # ------------------------------------------------------------------
51
+ # halflife WT: folders carry a _log suffix
52
+ # ------------------------------------------------------------------
53
+ if prop_key == "halflife" and (emb_tag is None or emb_tag == "wt"):
54
+ if model_name == "transformer":
 
55
  return f"{base}/transformer_wt_log"
56
+ if model_name in {"xgb", "xgb_reg"}:
57
+ return f"{base}/xgb_wt_log"
58
 
59
+ # ------------------------------------------------------------------
60
+ # Default: <model>_<folder_suffix>
61
+ # e.g. cnn_chemberta, xgb_peptideclm, transformer_wt
62
+ # ------------------------------------------------------------------
63
+ return f"{base}/{model_name}_{folder_suffix}"
64
 
65
 
66
  def build_allow_patterns_from_manifest(manifest_path: Path) -> List[str]:
 
68
 
69
  allow: List[str] = []
70
 
 
71
  for prop_key, row in best.items():
72
+ for col, parsed in [("wt", row.best_wt), ("smiles", row.best_smiles)]:
73
+ if parsed is None:
 
74
  continue
75
 
76
+ model_name, emb_tag = parsed
 
77
 
78
+ # Replace banned models with xgb
79
+ if model_name in BANNED_MODELS:
80
+ model_name = "xgb"
81
+
82
+ model_dir = _resolve_expected_model_dir(prop_key, model_name, emb_tag)
83
 
 
84
  allow += [
85
  f"{model_dir}/best_model.json",
86
  f"{model_dir}/best_model.pt",
 
88
  f"{model_dir}/best_model*.json",
89
  ]
90
 
91
+ # Deduplicate while preserving order
92
  seen = set()
93
  out = []
94
  for p in allow:
 
123
  def main():
124
  import argparse
125
 
126
+ ap = argparse.ArgumentParser(
127
+ description="Lightweight PeptiVerse inference with on-demand model download."
128
+ )
129
+ ap.add_argument("--repo", default=MODEL_REPO, help="HF repo id containing weights/assets.")
130
+ ap.add_argument("--manifest", default=str(DEFAULT_MANIFEST), help="Path to best_models.txt")
131
+ ap.add_argument("--assets", default=str(DEFAULT_ASSETS_DIR), help="Where to store downloaded assets")
132
+ ap.add_argument("--device", default=None, help="cuda / cpu / cuda:0, etc")
133
+ ap.add_argument("--dry-run", action="store_true", help="Print allow-patterns without downloading")
134
+
135
+ ap.add_argument("--property", default="hemolysis")
136
+ ap.add_argument("--mode", default="wt", choices=["wt", "smiles"])
137
+ ap.add_argument("--input", default="GIGAVLKVLTTGLPALISWIKRKRQQ")
138
+ ap.add_argument("--target_seq", default="GIGAVLKVLTTGLPALISWIKRKRQQ")
139
+ ap.add_argument("--binder", default="GIGAVLKV")
140
  args = ap.parse_args()
141
 
142
  manifest_path = Path(args.manifest)
143
  if not manifest_path.exists():
144
  raise FileNotFoundError(f"Manifest not found: {manifest_path}")
145
 
146
+ if args.dry_run:
147
+ patterns = build_allow_patterns_from_manifest(manifest_path)
148
+ print(f"Would download {len(patterns)} patterns:")
149
+ for p in patterns:
150
+ print(" ", p)
151
+ return
152
+
153
+ assets_dir = download_assets(
154
+ args.repo, manifest_path=manifest_path, out_dir=Path(args.assets)
155
+ )
156
 
157
+ """TEST CODE
158
  predictor = PeptiVersePredictor(
159
+ manifest_path=manifest_path,
160
  classifier_weight_root=str(assets_dir),
161
  device=args.device,
162
  )
 
163
  if args.property == "binding_affinity":
164
  if not args.target_seq or not args.binder:
165
  raise ValueError("For binding_affinity, provide --target_seq and --binder.")
166
  out = predictor.predict_binding_affinity(args.mode, target_seq=args.target_seq, binder_str=args.binder)
167
  else:
168
  out = predictor.predict_property(args.property, args.mode, args.input)
 
169
  print(out)
170
  """
171
 
172
  if __name__ == "__main__":
173
+ main()
inference.py CHANGED
@@ -19,13 +19,7 @@ seed_everything(1986)
19
 
20
  EMB_TAG_TO_FOLDER_SUFFIX = {
21
  "wt": "wt",
22
- "peptideclm": "smiles",
23
- "chemberta": "chemberta",
24
- }
25
-
26
- EMB_TAG_TO_RUNTIME_MODE = {
27
- "wt": "wt",
28
- "peptideclm": "smiles",
29
  "chemberta": "chemberta",
30
  }
31
 
@@ -778,7 +772,7 @@ class PeptiVersePredictor:
778
 
779
  # infer emb_tag
780
  if emb_tag is None:
781
- emb_tag = col
782
 
783
  model_dir = self._resolve_dir(prop_key, model_name, emb_tag)
784
  kind, obj, art = load_artifact(model_dir, self.device)
@@ -1054,7 +1048,7 @@ if __name__ == "__main__":
1054
  root = Path(__file__).resolve().parent # current script folder
1055
 
1056
  predictor = PeptiVersePredictor(
1057
- manifest_path=root / "best_models.txt",
1058
  classifier_weight_root=root
1059
  )
1060
  print(predictor.training_root)
@@ -1065,17 +1059,21 @@ if __name__ == "__main__":
1065
  smiles = "C(C)C[C@@H]1NC(=O)[C@@H]2CCCN2C(=O)[C@@H](CC(C)C)NC(=O)[C@@H](CC(C)C)N(C)C(=O)[C@H](C)NC(=O)[C@H](Cc2ccccc2)NC1=O"
1066
 
1067
  print(predictor.predict_property("hemolysis", "wt", seq))
1068
- print(predictor.predict_property("hemolysis", "smiles", smiles, uncertainty=True))
1069
- print(predictor.predict_property("nf", "wt", seq, uncertainty=True))
1070
- print(predictor.predict_property("nf", "smiles", smiles, uncertainty=True))
1071
  print(predictor.predict_binding_affinity("wt", target_seq=seq, binder_str="GIGAVLKVLT"))
1072
- print(predictor.predict_binding_affinity("wt", target_seq=seq, binder_str="GIGAVLKVLT", uncertainty=True))
1073
  seq1 = "GIGAVLKVLTTGLPALISWIKRKRQQ"
1074
  seq2 = "ACDEFGHIKLMNPQRSTVWY"
1075
 
1076
- r1 = predictor.predict_binding_affinity("wt", target_seq=seq2, binder_str="GIGAVLKVLT", uncertainty=True)
1077
- r2 = predictor.predict_property("nf", "wt", seq1, uncertainty=True)
1078
- r3 = predictor.predict_property("nf", "wt", seq2, uncertainty=True)
 
 
1079
  print(r1)
1080
  print(r2)
1081
  print(r3)
 
 
 
19
 
20
  EMB_TAG_TO_FOLDER_SUFFIX = {
21
  "wt": "wt",
22
+ "peptideclm": "peptideclm",
 
 
 
 
 
 
23
  "chemberta": "chemberta",
24
  }
25
 
 
772
 
773
  # infer emb_tag
774
  if emb_tag is None:
775
+ emb_tag = "wt"
776
 
777
  model_dir = self._resolve_dir(prop_key, model_name, emb_tag)
778
  kind, obj, art = load_artifact(model_dir, self.device)
 
1048
  root = Path(__file__).resolve().parent # current script folder
1049
 
1050
  predictor = PeptiVersePredictor(
1051
+ manifest_path=root / "basic_models.txt",
1052
  classifier_weight_root=root
1053
  )
1054
  print(predictor.training_root)
 
1059
  smiles = "C(C)C[C@@H]1NC(=O)[C@@H]2CCCN2C(=O)[C@@H](CC(C)C)NC(=O)[C@@H](CC(C)C)N(C)C(=O)[C@H](C)NC(=O)[C@H](Cc2ccccc2)NC1=O"
1060
 
1061
  print(predictor.predict_property("hemolysis", "wt", seq))
1062
+ print(predictor.predict_property("hemolysis", "smiles", smiles, uncertainty=False))
1063
+ print(predictor.predict_property("nf", "wt", seq, uncertainty=False))
1064
+ print(predictor.predict_property("nf", "smiles", smiles, uncertainty=False))
1065
  print(predictor.predict_binding_affinity("wt", target_seq=seq, binder_str="GIGAVLKVLT"))
1066
+ print(predictor.predict_binding_affinity("wt", target_seq=seq, binder_str="GIGAVLKVLT", uncertainty=False))
1067
  seq1 = "GIGAVLKVLTTGLPALISWIKRKRQQ"
1068
  seq2 = "ACDEFGHIKLMNPQRSTVWY"
1069
 
1070
+ r1 = predictor.predict_binding_affinity("wt", target_seq=seq2, binder_str="GIGAVLKVLT", uncertainty=False)
1071
+ r2 = predictor.predict_property("nf", "wt", seq1, uncertainty=False)
1072
+ r3 = predictor.predict_property("nf", "wt", seq2, uncertainty=False)
1073
+ r4 = predictor.predict_binding_affinity("wt", target_seq=seq2, binder_str=smiles, uncertainty=False)
1074
+ r5 = predictor.predict_property("halflife", "smiles", smiles)
1075
  print(r1)
1076
  print(r2)
1077
  print(r3)
1078
+ print(r4)
1079
+ print(r5)