Views
No views yet
facebook/esm2_t6_8M_UR50D
with its last 4 transformer layers unfrozen plus an MLP head.binding-esm2-20260705-2355-7396. This repo contains the
best checkpoint only.facebook/esm2_t6_8M_UR50D.Linear(320 → 256) → GELU → Dropout(0.1) → Linear(256 → 10).ProteinBindingModel (see How to use — this is not
an AutoModelForSequenceClassification).human_new, mouse, rat, dog, cat, cattle, horse, ihbat, monkey, mink.theoschiff-biie/ace2_binding
— a validated mirror of the task's referenced (non-existent) BIIE-AI/ace2_binding.
Yeast-display sequencing of a SARS-CoV-2 Omicron BA.1 RBD mutagenesis library
screened against 10 ACE2 orthologs. The dataset's own train/test split was used;
sparse multi-label rows are handled with a masked BCE loss (only observed
(sequence, species) pairs contribute).| Setting | Value |
|---|---|
| Epochs | 5 |
| Optimizer | AdamW (weight_decay 0.01, max_grad_norm 1.0) |
| Learning rate | head 3e-4 · encoder 5e-5 |
| Effective batch size | 128 (per-device 128, grad-accum 1) |
| Precision | bf16 |
| Sequence length | 201 aa (fixed) |
| Loss | masked multi-label BCE |
| Hardware | 1× A100-SXM4-40GB (Lambda) |
| Model | Macro-MCC (tuned) | Macro-MCC (@0.5) |
|---|---|---|
| This model (last-4 unfrozen) | 0.8229 | 0.8261 |
| Frozen-encoder baseline | 0.4557 | — |
| Δ vs baseline | +0.3672 | — |
| Species | Tuned thr. | MCC | AUROC | Support |
|---|---|---|---|---|
| human_new | 0.84 | 0.807 | 0.950 | 26,079 |
| mouse | 0.70 | 0.762 | 0.909 | 45,932 |
| rat | 0.54 | 0.967 | 0.997 | 15,370 |
| dog | 0.77 | 0.755 | 0.919 | 31,088 |
| cat | 0.65 | 0.920 | 0.972 | 75,548 |
| cattle | 0.76 | 0.759 | 0.932 | 53,255 |
| horse | 0.72 | 0.858 | 0.927 | 28,083 |
| ihbat | 0.68 | 0.845 | 0.927 | 36,475 |
| monkey | 0.85 | 0.624 | 0.941 | 16,637 |
| mink | 0.49 | 0.931 | 0.985 | 113,398 |
monkey is the hardest species, consistent with its low prevalence of 8.9%.)model.safetensors — encoder + head weights (~31 MB).config.json — {model_id, num_labels: 10, hidden: 320, proj: 256, head_dropout: 0.1, architecture: "ProteinBindingModel"}.ProteinBindingModel (ESM-2 encoder + pooled MLP head),
not a stock transformers class. Rebuild the module, then load the weights:1import json, torch, torch.nn as nn
2from huggingface_hub import hf_hub_download
3from safetensors.torch import load_file
4from transformers import AutoTokenizer, EsmModel
5
6REPO = "theoschiff-biie/capo-binding-esm2-20260705-2355-7396-best"
7SPECIES = ["human_new","mouse","rat","dog","cat","cattle","horse","ihbat","monkey","mink"]
8cfg = json.load(open(hf_hub_download(REPO, "config.json")))
9
10tok = AutoTokenizer.from_pretrained(cfg["model_id"])
11SPECIAL = {tok.cls_token_id, tok.eos_token_id, tok.pad_token_id} # excluded from the mean
12
13class ProteinBindingModel(nn.Module):
14 def __init__(self, model_id, num_labels=10, head_dropout=0.1, proj=256):
15 super().__init__()
16 self.encoder = EsmModel.from_pretrained(model_id, add_pooling_layer=False)
17 h = self.encoder.config.hidden_size
18 self.head = nn.Sequential(
19 nn.Linear(h, proj), nn.GELU(), nn.Dropout(head_dropout),
20 nn.Linear(proj, num_labels),
21 )
22
23 def _pool(self, hs, ids, mask):
24 sp = torch.ones_like(ids, dtype=torch.bool)
25 for t in SPECIAL:
26 sp &= ids != t
27 m = (mask.bool() & sp).unsqueeze(-1).to(hs.dtype)
28 return (hs * m).sum(1) / m.sum(1).clamp(min=1.0)
29
30 def forward(self, input_ids, attention_mask):
31 out = self.encoder(input_ids=input_ids, attention_mask=attention_mask)
32 return self.head(self._pool(out.last_hidden_state, input_ids, attention_mask))
33
34model = ProteinBindingModel(cfg["model_id"], cfg["num_labels"], cfg["head_dropout"], cfg["proj"])
35model.load_state_dict(load_file(hf_hub_download(REPO, "model.safetensors")), strict=False)
36model.eval()
37
38enc = tok("SEQ...RBD...SEQ", return_tensors="pt", truncation=True, max_length=203)
39with torch.no_grad():
40 probs = torch.sigmoid(model(enc["input_ids"], enc["attention_mask"]))[0]
41print({s: float(p) for s, p in zip(SPECIES, probs)}) # apply per-species tuned thresholds_poolmasks the ESM special tokens (CLS/EOS/PAD) exactly as training did. For bit-identical pooling, usesrc/models/model.pyfrom the CAPO run directory.
binding-esm2-20260705-2355-7396 (RUN_REPORT.md in the run dir).checkpoints/best/ only (private). checkpoints/last/ is retained
locally and intentionally not pushed.