| --- |
| license: other |
| license_name: om-lula-community-license-1.1 |
| license_link: LICENSE |
| pipeline_tag: other |
| tags: |
| - biology |
| - drug-discovery |
| - small-molecule-discovery |
| - protein-ligand |
| - binding-affinity |
| - open-weight |
| - lula-1 |
| --- |
| |
| > **License notice.** By downloading, accessing, or using LULA-1, you agree to |
| > the [Om LULA Community License 1.1](LICENSE). LULA-1 is licensed for research, |
| > evaluation, benchmarking, teaching, and other non-commercial research uses |
| > only. **Any commercial work requires a separate Om commercial license**, |
| > including internal commercial discovery, commercial drug discovery, screening, |
| > hit finding, lead optimization, portfolio decisions, production R&D, product |
| > candidate identification, patent or therapeutic program work, hosted |
| > inference, paid API/SaaS access, resale, support/deployment, product |
| > bundling, and competing model services. For commercial licensing, contact |
| > dmc@omtx.ai. |
|
|
| <style> |
| @font-face { |
| font-family: 'OmMontserrat'; |
| font-style: normal; |
| font-weight: 100 900; |
| font-display: swap; |
| src: url('https://huggingface.co/spaces/omtx/README/resolve/main/assets/Montserrat-Latin-Variable.woff2') format('woff2'); |
| } |
| .om-card { background:#0A0A0A; border:1px solid #2A2A2A; border-radius:14px; overflow:hidden; |
| font-family:'OmMontserrat','Montserrat','Helvetica Neue',Arial,sans-serif; color:#fff; |
| margin-bottom:26px; } |
| .om-card p, .om-card h1 { margin-top:0; margin-left:0; margin-right:0; } |
| .om-hero { position:relative; overflow:hidden; background:#0A0A0A; } |
| .om-hero-img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; |
| object-position:72% 50%; margin:0; } |
| .om-scrim { position:absolute; inset:0; |
| background:linear-gradient(90deg,rgba(10,10,10,0.97) 0%,rgba(10,10,10,0.90) 44%,rgba(10,10,10,0.30) 100%); } |
| .om-cmark { position:absolute; color:#3B3636; font-size:19px; line-height:1; font-weight:300; z-index:5; } |
| .om-copy { position:relative; z-index:2; padding:36px 34px 38px; max-width:660px; } |
| .om-mono { color:#71717A; font-size:11px; font-weight:500; letter-spacing:0.26em; |
| text-transform:uppercase; margin-bottom:14px; } |
| .om-eyebrow { color:#E2E756; font-size:12px; font-weight:600; letter-spacing:0.32em; |
| text-transform:uppercase; margin-bottom:18px; } |
| .om-h1 { font-size:40px; font-weight:700; letter-spacing:-0.03em; line-height:1.0; |
| margin-bottom:18px; color:#fff; } |
| .om-accent { color:#E2E756; } |
| .om-lede { color:#D4D4D8; font-size:16px; line-height:1.5; margin-bottom:22px; max-width:54ch; } |
| .om-pill { display:inline-block; border:1px solid #2A2A2A; color:#D4D4D8; font-size:11px; |
| font-weight:700; letter-spacing:0.08em; text-transform:uppercase; padding:8px 15px; |
| border-radius:100px; margin:0 7px 7px 0; } |
| .om-status { border-top:1px solid #2A2A2A; background:#0D0C0C; padding:26px 34px 28px; } |
| .om-chip { display:inline-block; border:1px solid #3B3636; color:#71717A; font-size:11px; |
| font-weight:700; letter-spacing:0.08em; text-transform:uppercase; padding:7px 13px; |
| border-radius:6px; margin:0 7px 7px 0; } |
| .om-chip-live { border-color:#E2E756; color:#E2E756; } |
| </style> |
| |
| <div class="om-card"> |
| <div class="om-hero"> |
| <img class="om-hero-img" src="assets/lula1-hero.jpg" alt="Protein scaffold with a ligand bound in a highlighted pocket" /> |
| <div class="om-scrim"></div> |
| <span class="om-cmark" style="top:15px; left:15px;">+</span> |
| <span class="om-cmark" style="top:15px; right:15px;">+</span> |
| <span class="om-cmark" style="bottom:15px; right:15px;">+</span> |
| <div class="om-copy"> |
| <p class="om-mono">omtx.ai</p> |
| <p class="om-eyebrow">Open-weight release track</p> |
| <h1 class="om-h1">LULA-1 — <span class="om-accent">sequence-only</span> protein–ligand scoring.</h1> |
| <p class="om-lede"> |
| Protein amino-acid sequence plus ligand SMILES in, binding score out. No structure input, |
| no docking, no folding step. |
| </p> |
| <p> |
| <span class="om-pill">Sequence-only</span> |
| <span class="om-pill">Local inference</span> |
| <span class="om-pill">Open weights</span> |
| </p> |
| </div> |
| </div> |
| <div class="om-status"> |
| <p class="om-eyebrow">Model at a glance</p> |
| <span class="om-chip om-chip-live">1.7M parameters</span> |
| <span class="om-chip om-chip-live">6.8 MB</span> |
| <span class="om-chip om-chip-live">Sequence-only</span> |
| <span class="om-chip om-chip-live">Local inference</span> |
| <span class="om-chip om-chip-live">Open weights</span> |
| <span class="om-chip">Public AUROC 0.7615</span> |
| <span class="om-chip">EF@1000 54.8×</span> |
| </div> |
| </div> |
| |
| # LULA-1 |
|
|
| LULA-1 is a lightweight, fast, sequence-only protein–ligand binding scorer, trained on ~500M data |
| points from Om and public sources. It takes a protein |
| amino-acid sequence and a ligand SMILES string and returns a binding score. There is no structure |
| input, no docking, and no folding step. |
|
|
| It is fast because of how it is built: the protein is embedded once, and every additional ligand |
| costs only a projection and a cosine similarity. That is what makes screening a million-molecule |
| library practical. |
|
|
| The intended public interface is deliberately small: |
|
|
| ```python |
| score(protein_sequence: str, smiles: str | list[str]) -> record | list[record] |
| ``` |
|
|
| ## What this release contains |
|
|
| LULA-1 ships as a compact scoring head that runs on top of two public pretrained encoders. The |
| checkpoint is **6.8 MB — 1,705,984 parameters**. This makes the released Om weights easy to verify, |
| cache, and move between local environments while using widely available protein and molecule |
| representations at inference time. |
|
|
| ### Parameters |
|
|
| | Component | Parameters | Source | |
| |---|---:|---| |
| | **LULA-1 scoring head** | **1,705,984** | this repository | |
| | ESM-2 650M — protein encoder (1280-dim) | 652,358,616 | `facebook/esm2_t33_650M_UR50D` | |
| | ChemBERTa-77M-MTR — ligand encoder (384-dim) | ~3,500,000 | `DeepChem/ChemBERTa-77M-MTR` | |
| | **Total at inference** | **~657.6M** | | |
|
|
| The scoring head is ~0.26% of the parameters in play at inference. Breakdown of the checkpoint: |
|
|
| | Tensor | Shape | Parameters | |
| |---|---|---:| |
| | `protein_projector.weight` | 1024 × 1280 | 1,310,720 | |
| | `protein_projector.bias` | 1024 | 1,024 | |
| | `ligand_projector.weight` | 1024 × 384 | 393,216 | |
| | `ligand_projector.bias` | 1024 | 1,024 | |
| | **Total** | | **1,705,984** | |
|
|
| The checkpoint also carries `score_logit_scale` (10.0), a scalar loaded as a Python float rather |
| than a tensor — it is a persisted hyperparameter, not a trainable parameter, and is excluded from |
| the count above. |
|
|
| Architecturally this is a ConPLex-style contrastive scorer: each encoder output is passed through a |
| single `Linear → GELU → Dropout` projection to a shared 1024-dim space, L2-normalized, compared by |
| cosine similarity, scaled by the logit scale persisted in the checkpoint, and passed through a |
| sigmoid. The output is a probability-like score in `[0, 1]`. |
|
|
| The `omtx lula download` command downloads the LULA-1 weights and the required public encoder assets |
| into the local cache for scoring. Om distributes the LULA-1 scoring head in this repository; the |
| third-party encoders remain governed by their own upstream terms. |
|
|
| ## Usage |
|
|
| **Quickstart notebook:** [`notebooks/lula1_quickstart.ipynb`](notebooks/lula1_quickstart.ipynb) — |
| install, download, verify, and score a real target end to end. CPU works; GPU is faster. |
|
|
| ```bash |
| pip install "omtx[lula]>=2.0.12" |
| |
| hf auth login # required for gated LULA-1 weights; say no to adding the token as a git credential |
| omtx lula download # LULA-1 weights + both required encoders |
| omtx lula verify # SHA256 against the release manifest |
| ``` |
|
|
| ```python |
| from omtx.lula import load_model |
| |
| CA2 = ( |
| "MSHHWGYGKHNGPEHWHKDFPIAKGERQSPVDIDTHTAKYDPSLKPLSVSYDQATSLRIL" |
| "NNGHAFNVEFDDSQDKAVLKGGPLDGTYRLIQFHFHWGSLDGQGSEHTVDKKKYAAELHL" |
| "VHWNTKYGDFGKAVQQPDGLAVLGIFLKVGSAKPGLQKVVDVLDSIKTKGKSADFTNFDP" |
| "RGLLPESLDYWTYPGSLTTPPLLECVTWIVLKEPISVSSEQVLKFRKLNFNGEGEPEELM" |
| "VDNWRPAQPLKNRQIKASFK" |
| ) |
| mols = [ |
| "CC(=O)Nc1nnc(s1)S(N)(=O)=O", |
| "Cc1ccc(cc1)S(=O)(=O)N", |
| "CC(C)Cc1ccc(cc1)C(C)C(=O)O", |
| "CCN(CC)CCNC(=O)c1ccc(N)cc1", |
| "c1ccc(cc1)C(=O)O", |
| "CCO", |
| ] |
| |
| model = load_model() |
| for row in sorted(model.score(protein_sequence=CA2, smiles=mols), key=lambda r: r["rank"]): |
| print(row["rank"], round(row["score"], 4), row["smiles"]) |
| ``` |
|
|
| Verified in Google Colab on 2026-07-29 with `omtx[lula]>=2.0.12`; LULA-1 is |
| now gated on Hugging Face, so run `hf auth login` or pass a Hugging Face token |
| before `omtx lula download`. Expected CA2 ranking: |
|
|
| ```text |
| 1 0.9995 CC(=O)Nc1nnc(s1)S(N)(=O)=O |
| 2 0.9991 Cc1ccc(cc1)S(=O)(=O)N |
| 3 0.2331 CCO |
| 4 0.1643 CCN(CC)CCNC(=O)c1ccc(N)cc1 |
| 5 0.1518 CC(C)Cc1ccc(cc1)C(C)C(=O)O |
| 6 0.0984 c1ccc(cc1)C(=O)O |
| ``` |
|
|
| Batch scoring returns, per molecule: `score`, `rank`, and `top_percentile_in_batch`. |
| `rank` and `top_percentile_in_batch` are computed within the batch you submit, making the output |
| directly useful for prioritizing a candidate set. |
|
|
| The same scoring is available hosted, with no local setup, via `client.lula1.score(...)`. |
|
|
| ## Intended use |
|
|
| Ranking and triage of compound sets against a protein target — particularly where no structure is |
| available, or where a structure-based method would be too slow across the full set. LULA-1 returns a |
| relative score for prioritization. |
|
|
| ## Your data stays local |
|
|
| Scoring and fine-tuning run entirely on your machine. Nothing about your targets or compounds is |
| transmitted to Om. |
|
|
| - `omtx lula score` and local fine-tuning make **no network calls**. Protein sequences, SMILES, |
| labels, scores, and checkpoints never leave your environment. |
| - There is **no telemetry** in the local path — no usage pings, no analytics, no phone-home. |
| - `omtx lula download` is the only command that uses the network. It fetches the weights and the two |
| public encoders, and sends nothing about your data. |
| - After that download, the whole path runs **offline**. Point `OMTX_LULA_HOME` at a shared cache and |
| scoring works on an air-gapped machine. |
|
|
| This is a property of the code, not a policy promise: the scoring module contains no HTTP client and |
| no network imports. It is verifiable by inspection of the published package. |
|
|
| For teams that cannot send proprietary targets or compound libraries to a third-party API, this is |
| the point of an open-weight release. |
|
|
| ## Hosted models and fulfillment |
|
|
| LULA-1's weights are open-weight so you can screen locally with no dependency on Om. Three things are |
| available from Om when you want more than that: |
|
|
| **Hosted LULA-1** — the same model, no local setup, no encoder downloads, no GPU. Useful for large |
| screens and for teams that want managed runs and tracking. |
| [omtx.ai/models](https://omtx.ai/models) |
|
|
| **LULA-2** — Om's private hosted successor for advanced target classes, including protein–protein |
| interfaces and flat or shallow pockets. It reads the protein and ligand together with |
| cross-attention rather than scoring from independent embeddings and is available through Om's hosted |
| API. |
| [omtx.ai/models](https://omtx.ai/models) |
|
|
| **Molecule Fulfillment** — once you have a ranked shortlist, order the physical compounds through |
| Om: search, quote, checkout, and order status in one flow. |
| [omtx.ai](https://omtx.ai) |
|
|
| Pricing for hosted scoring is at [omtx.ai/pricing](https://omtx.ai/pricing). |
|
|
| A practical pattern: screen wide and cheap with open-weight LULA-1, then use Om's hosted models and |
| fulfillment tools for managed runs, ordering, and final prioritization. |
|
|
| ## What ships |
|
|
| | Path | | |
| |---|---| |
| | `model/best.pt` | Scoring-head checkpoint | |
| | `model/model_config.json` | Model configuration | |
| | `release_manifest.json` | Machine-readable hashes used by `omtx lula verify` | |
| | `checksums.txt` | Human-readable SHA256 list | |
| | `examples/` | Runnable scoring examples | |
| | `LICENSE`, `NOTICE` | Terms and third-party components | |
|
|
| Use is governed by `LICENSE`. Third-party pretrained encoders are governed by their own terms. This |
| release package focuses on the LULA-1 scoring head, verification assets, examples, and |
| documentation. |
|
|
| ## Training data |
|
|
| LULA-1 was trained on **~500 million data points** from **Om and public sources**. |
|
|
| ## Evaluation |
|
|
| LULA-1 is evaluated as a ranking model for hit triage. Scores are optimized for prioritizing |
| candidate molecules within a target-specific screening set. |
|
|
| ### Public metrics |
|
|
| The LULA-1 release checkpoint is `lula1_v6`. |
|
|
| | Metric | LULA-1 v6 | |
| |---|---:| |
| | Public validation AUROC | **0.7615** | |
| | Proteome-scale macro AUROC | **0.633** | |
| | Proteome-scale aggregate EF@1000 | **54.8×** | |
|
|
| ### Proteome-scale sweep |
|
|
| LULA-1 was also evaluated in a large proteome-scale ranking sweep. |
|
|
| | | | |
| |---|---| |
| | Proteins scored | **10,569** | |
| | Protein–ligand pairs scored | **10,575,246,882** | |
| | Known binders | 5,025,463 | |
| | Macro AUROC | 0.633 | |
| | Median AUROC | 0.678 | |
| | Aggregate EF@1000 | **54.8×** | |
|
|
| EF@1000 measures top-of-list enrichment: across the sweep, LULA-1 found 267,324 known binders in |
| the top-1000 ranked molecules per target, versus 4,877.6 expected under random ranking. |
|
|
| ### Enrichment by target evidence |
|
|
| LULA-1 enrichment improves as more target evidence is available: |
|
|
| | Known binders | Proteins | Median AUROC | Mean P@1000 | Expected P@1000 | Implied EF | |
| |---|---:|---:|---:|---:|---:| |
| | 1-9 | 4,910 | 0.648 | 0.0092% | 0.0003% | ~31× | |
| | 10-49 | 2,230 | 0.610 | 0.1016% | 0.0024% | ~42× | |
| | 50-199 | 1,528 | 0.686 | 0.6811% | 0.0103% | ~66× | |
| | 200-999 | 1,102 | 0.738 | 3.8868% | 0.0470% | ~83× | |
| | >=1000 | 799 | 0.810 | 26.4541% | 0.5175% | ~51× | |
|
|
| ### Target-level results |
|
|
| Per-protein metrics from the proteome-scale sweep, for well-known drug targets. |
|
|
| EF is AUPR divided by the target's observed positive rate in the ranked sweep. |
|
|
| | Target | UniProt | Known binders | AUROC | AUPR | EF | |
| |---|---|---:|---:|---:|---:| |
| | KIT | P10721 | 5,354 | 0.891 | 0.1005 | 19× | |
| | PIM1 | P11309 | 9,127 | 0.887 | 0.3810 | 42× | |
| | PARP1 | P09874 | 6,982 | 0.878 | 0.3436 | 50× | |
| | ALK | Q9UM73 | 4,265 | 0.876 | 0.1802 | 42× | |
| | BACE1 | P56817 | 15,149 | 0.876 | 0.4582 | 31× | |
| | BTK | Q06187 | 14,504 | 0.873 | 0.1465 | 10× | |
| | CA2 | P00918 | 10,901 | 0.870 | 0.5495 | 51× | |
| | HDAC1 | Q13547 | 12,855 | 0.853 | 0.5510 | 43× | |
| | CDK2 | P24941 | 16,693 | 0.845 | 0.2298 | 14× | |
| | MTOR | P42345 | 10,258 | 0.824 | 0.1394 | 14× | |
| | ABL1 | P00519 | 5,808 | 0.808 | 0.0540 | 9× | |
| | EGFR | P00533 | 18,363 | 0.788 | 0.1895 | 11× | |
| | ESR1 | P03372 | 7,815 | 0.757 | 0.2192 | 28× | |
| | AR | P10275 | 5,551 | 0.724 | 0.0799 | 14× | |
|
|
| Kinases and well-characterized enzyme families rank strongly. Target-level metrics and batch |
| rankings help prioritize each campaign. |
|
|
| ## License |
|
|
| Weights are released under the **Om LULA Community License 1.1**. By downloading, accessing, or |
| using LULA-1, you agree to that license. See `LICENSE` for the full terms and `NOTICE` for |
| third-party components. |
|
|
| Summary (the `LICENSE` file governs): |
|
|
| - **Permitted without a commercial license** — non-commercial research, evaluation, |
| benchmarking, teaching, security testing, local inference, local fine-tuning for non-commercial |
| research, non-commercial demos, publishing non-commercial scientific results, and sharing derived |
| checkpoints where terms allow. |
| - **Requires a separate Om commercial license** — any commercial work or commercialization, |
| including internal commercial discovery, commercial drug discovery, screening, hit finding, lead |
| optimization, portfolio decisions, production R&D, product candidate identification, patent or |
| therapeutic program work, monetized hosting, paid API/SaaS access, reselling model access, |
| support/deployment, bundling LULA-1 into a paid product, or building a competing model API around |
| Om weights. |
| - **Commercial licensing contact** — email dmc@omtx.ai. |
| - **Publication attribution required** — public papers, preprints, benchmarks, reports, model cards, |
| or presentations using LULA-1 must cite Om Therapeutics Inc. LULA-1, version `lula1_v6`, and the |
| Hugging Face model page. |
|
|
| ## Attribution |
|
|
| LULA-1's architecture is derived from **ConPLex**, developed at MIT. |
|
|
| > Singh, R., Sledzieski, S., Bryson, B., Cowen, L., & Berger, B. (2023). |
| > *Contrastive learning in protein language space predicts interactions between drugs and protein |
| > targets.* **Proceedings of the National Academy of Sciences**, 120(24). |
| > [doi:10.1073/pnas.2220778120](https://doi.org/10.1073/pnas.2220778120) |
|
|
| Reference implementation: [github.com/samsledje/ConPLex](https://github.com/samsledje/ConPLex) |
| (MIT License). |
|
|
| If you use LULA-1 in published work, please cite the ConPLex paper alongside Om. |
|
|
| ## Links |
|
|
| - Om — <https://omtx.ai> |
| - Hosted models — <https://omtx.ai/models> |
| - Pricing — <https://omtx.ai/pricing> |
| - GitHub — <https://github.com/omtx-ai> |
|
|