File size: 28,683 Bytes
e27a303 08ef0a2 e27a303 f0859a9 e27a303 ce2a6a8 e27a303 ce2a6a8 e27a303 90ade67 e27a303 a0ea787 e27a303 a0ea787 e27a303 90ade67 e27a303 a0ea787 e27a303 90ade67 4074358 5a6a979 4074358 e27a303 4074358 9ad7e6e e27a303 9ad7e6e 90ade67 ce2a6a8 e27a303 ce2a6a8 e27a303 8cf0b21 e27a303 8cf0b21 e27a303 90ade67 e27a303 9ad7e6e e27a303 8cf0b21 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 9ad7e6e 90ade67 9ad7e6e 90ade67 e27a303 90ade67 9ad7e6e 90ade67 9ad7e6e 90ade67 e27a303 90ade67 e27a303 8cf0b21 e27a303 9ad7e6e e27a303 9ad7e6e e27a303 9ad7e6e e27a303 9ad7e6e e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 69ae81c 90ade67 69ae81c 90ade67 432a257 07fc6ea 432a257 07fc6ea 432a257 90ade67 e27a303 432a257 e27a303 07fc6ea 432a257 07fc6ea 432a257 90ade67 69ae81c e27a303 07fc6ea 432a257 07fc6ea 432a257 90ade67 432a257 e27a303 07fc6ea 432a257 07fc6ea 432a257 90ade67 432a257 e27a303 07fc6ea e27a303 07fc6ea e27a303 07fc6ea e27a303 07fc6ea e27a303 432a257 c315d26 90ade67 07fc6ea 90ade67 c315d26 90ade67 07fc6ea 90ade67 c315d26 432a257 c315d26 90ade67 07fc6ea 90ade67 07fc6ea 90ade67 c315d26 90ade67 c315d26 90ade67 c315d26 90ade67 07fc6ea c315d26 07fc6ea c315d26 07fc6ea 90ade67 07fc6ea 90ade67 07fc6ea 90ade67 07fc6ea 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 90ade67 e27a303 8cf0b21 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 | ---
license: apache-2.0
---

# PeptiVerse: A Unified Platform for Therapeutic Peptide Property Prediction π§¬π
This is the repository for [PeptiVerse: A Unified Platform for Therapeutic Peptide Property Prediction](https://www.biorxiv.org/content/10.64898/2025.12.31.697180), a collection of machine learning predictors for canonical and non-canonical peptide property prediction using sequence and SMILES representations. 𧬠PeptiVerse π enables evaluation of key biophysical and therapeutic properties of peptides for property-optimized generation.
## Table of Contents π
- [Quick start](#quick-start)
- [Installation](#installation)
- [Repository Structure](#repository-structure)
- [Training data collection](#training-data-collection)
- [Best model list](#best-model-list)
- [Full model set (cuML-enabled)](#full-model-set-gpu-enabled)
- [Minimal deployable model set (no cuML)](#minimal-deployable-set)
- [Usage](#usage)
- [Local Application Hosting](#local-application-hosting)
- [Dataset integration](#dataset-integration)
- [Training](#training)
- [Quick inference by property per model](#Quick-inference-by-property-per-model)
- [Property Interpretations](#property-interpretations)
- [Model Architecture](#model-architecture)
- [Troubleshooting](#troubleshooting)
- [Citation](#citation)
## Quick Start π
- Light-weighted start (basic models, no cuML, read below for details)
```bash
# Ignore all LFS files, you will see an empty folder first
git clone --no-checkout https://huggingface.co/ChatterjeeLab/PeptiVerse
cd PeptiVerse
# Enable sparse checkout
git sparse-checkout init --cone
# Choose only selective items to download
git sparse-checkout set \
inference.py \
download_light.py \
best_models.txt \
basic_models.txt \
requirements.txt \
tokenizer \
README.md
# Now checkout
GIT_LFS_SKIP_SMUDGE=1 git checkout
# Install basic pkgs
pip install -r requirements.txt
# Download basic model weights according to the basic_models.txt. Adjust which config you wanted as needed.
python download_light.py
# Test in inference
python inference.py
```
- Full model clone (will clone all best model weights)
```bash
# Clone repository
git clone https://huggingface.co/ChatterjeeLab/PeptiVerse
# Install dependencies
pip install -r requirements.txt
# Run inference
python inference.py
```
> **Note:** This clones best model weights only. For full access:
> - **All model weights** (best + seed ensembles for uncertainty quantification): [Zenodo](https://zenodo.org/records/19989009)
> - **Training datasets** (embeddings + splits): [HuggingFace Dataset](https://huggingface.co/datasets/ChatterjeeLab/PeptiVerse_data)
## Installation π
### Minimal Setup
- Easy start-up environment (using transformers, xgboost models)
```bash
pip install -r requirements.txt
```
### Full Setup
- Additional access to trained SVM and ElastNet models requires installation of `RAPIDS cuML`, with instructions available from their official [github page](https://github.com/rapidsai/cuml) (**CUDA-capable GPU required**).
- Optional: pre-compiled Singularity/Apptainer environment (5.68G) is available at [Google drive](https://drive.google.com/file/d/1ybLJNTC3BITIqBd8IO09nOOm4PKwD4iS/view?usp=sharing) with everything you need (still need CUDA/GPU to load cuML models). The SHA256 for checking is `48619796ef0adc81bc420021821e5ee3d9b2176bf1f564104e06dc1ce56b3498`, check via `shasum -a 256 peptiverse.sif`.
```
# test
apptainer exec peptiverse.sif python -c "import sys; print(sys.executable)"
# run inference (see below)
apptainer exec --nv peptiverse.sif python inference.py
```
## Repository Structure π
This repo contains important large files for [PeptiVerse](https://huggingface.co/spaces/ChatterjeeLab/PeptiVerse), an interactive app for peptide property prediction. [Paper link.](https://www.biorxiv.org/content/10.64898/2025.12.31.697180v1)
```
PeptiVerse/
βββ training_data_cleaned/ # Processed datasets with embeddings
β βββ <property>/ # Property-specific data
β βββ train/val splits
β βββ precomputed embeddings
βββ training_classifiers/ # Trained model weights
β βββ <property>/
β βββ cnn_wt/ # CNN architectures
β βββ mlp_wt/ # MLP architectures
β βββ xgb_wt/ # XGBoost models
βββ tokenizer/ # PeptideCLM tokenizer
βββ training_data/ # Raw training data
βββ inference.py # Main prediction interface
βββ best_models.txt # Model selection manifest
βββ requirements.txt # Python dependencies
```
For full data access, please download the corresponding `training_data_cleaned` and `training_classifiers` from [HuggingFace Dataset](https://huggingface.co/datasets/ChatterjeeLab/PeptiVerse_data) and [Zenodo](https://zenodo.org/records/19989009). The current Huggingface repo only hosts best model weights and meta data with splits labels.
```
1. Download and extract the Zenodo archive.
2. Download or clone this repository.
3. Copy/merge the repository `training_classifiers/` contents into the extracted Zenodo `training_classifiers/` directory, preserving the folder structure.
`rsync -av --ignore-existing training_classifiers/ /path/to/zenodo_extracted/training_classifiers/`
4. Do not replace the entire Zenodo folder blindly; merge files so that large training outputs from Zenodo and updated best-model weights from this repository coexist.
```
## Training Data Collection π
<table>
<caption><strong>Data distribution.</strong> Classification tasks report counts for class 0/1; regression tasks report total sample size (N).</caption>
<thead>
<tr>
<th rowspan="2"><strong>Properties</strong></th>
<th colspan="2"><strong>Amino Acid Sequences</strong></th>
<th colspan="2"><strong>SMILES Sequences</strong></th>
</tr>
<tr>
<th><strong>0</strong></th>
<th><strong>1</strong></th>
<th><strong>0</strong></th>
<th><strong>1</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="5"><strong>Classification</strong></td>
</tr>
<tr>
<td>Hemolysis</td>
<td>4765</td>
<td>1311</td>
<td>4765</td>
<td>1311</td>
</tr>
<tr>
<td>Non-Fouling</td>
<td>13580</td>
<td>3600</td>
<td>13580</td>
<td>3600</td>
</tr>
<tr>
<td>Solubility</td>
<td>9668</td>
<td>8785</td>
<td>9668</td>
<td>8785</td>
</tr>
<tr>
<td>Permeability (Penetrance)</td>
<td>1162</td>
<td>1162</td>
<td>1162</td>
<td>1162</td>
</tr>
<tr>
<td>Toxicity</td>
<td>-</td>
<td>-</td>
<td>5518</td>
<td>5518</td>
</tr>
<tr>
<td colspan="5"><strong>Regression (N)</strong></td>
</tr>
<tr>
<td>Permeability (PAMPA)</td>
<td colspan="2" align="center">-</td>
<td colspan="2" align="center">6869</td>
</tr>
<tr>
<td>Permeability (CACO2)</td>
<td colspan="2" align="center">-</td>
<td colspan="2" align="center">606</td>
</tr>
<tr>
<td>Half-Life</td>
<td colspan="2" align="center">130</td>
<td colspan="2" align="center">245</td>
</tr>
<tr>
<td>Binding Affinity</td>
<td colspan="2" align="center">1436</td>
<td colspan="2" align="center">1597</td>
</tr>
</tbody>
</table>
## Best Model List π
### Full model set (cuML-enabled)
| Property | Best Model (Sequence) | Best Model (SMILES) | Task Type | Threshold (Sequence) | Threshold (SMILES) |
|---|---|---|---|---|---|
| Hemolysis | SVM | CNN (chemberta) | Classifier | 0.2521 | 0.564 |
| Non-Fouling | Transformer | ENET (peptideclm) | Classifier | 0.712 | 0.6969 |
| Solubility | CNN | Transformer (peptideclm) | Classifier | 0.377 | 0.329 |
| Permeability (Penetrance) | SVM | SVM (chemberta) | Classifier | 0.5493 | 0.573 |
| Toxicity | β | CNN (chemberta) | Classifier | β | 0.49 |
| Binding Affinity | pooled | pooled (chemberta) | Regression | β | β |
| Permeability (PAMPA) | β | CNN (chemberta) | Regression | β | β |
| Permeability (Caco-2) | β | SVR (chemberta) | Regression | β | β |
| Half-life | Transformer | XGB (peptideclm) | Regression | β | β |
>Note: *unpooled* indicates models operating on token-level embeddings with cross-attention, rather than mean-pooled representations.
### Minimal deployable model set (no cuML)
| Property | Best Model (WT) | Best Model (SMILES) | Task Type | Threshold (WT) | Threshold (SMILES) |
|---|---|---|---|---|---|
| Hemolysis | XGB | CNN (chemberta) | Classifier | 0.2801 | 0.564 |
| Non-Fouling | Transformer | XGB (peptideclm) | Classifier | 0.712 | 0.3892 |
| Solubility | CNN | Transformer (peptideclm) | Classifier | 0.377 | 0.329 |
| Permeability (Penetrance) | XGB | XGB (chemberta) | Classifier | 0.4301 | 0.5028 |
| Toxicity | β | CNN (chemberta) | Classifier | β | 0.49 |
| Binding Affinity | pooled | pooled (chemberta) | Regression | β | β |
| Permeability (PAMPA) | β | CNN (chemberta) | Regression | β | β |
| Permeability (Caco-2) | β | SVR (chemberta) | Regression | β | β |
| Half-life | Transformer | XGB (peptideclm) | Regression | β | β |
>Note: Models marked as SVM or ENET are replaced with XGB as these models are not currently supported in the deployment environment without cuML setups.
## Usage π
### Local Application Hosting
- Host the [PeptiVerse UI](https://huggingface.co/spaces/ChatterjeeLab/PeptiVerse) locally with your own resources.
```bash
# Configure models in best_models.txt
git clone https://huggingface.co/spaces/ChatterjeeLab/PeptiVerse
python app.py
```
### Data pre-processing
Under the `training_data_cleaned`, we provided the generated embeddings in huggingface dataset format. The following scripts are the steps used to generate the data.
### Dataset integration
- All processed training datasets are available at [ChatterjeeLab/PeptiVerse\_data](https://huggingface.co/datasets/ChatterjeeLab/PeptiVerse_data).
- Selective download the data you need with `huggingface-cli`
```bash
huggingface-cli download ChatterjeeLab/PeptiVerse_data \
--include "training_data_cleaned/**" \ # only this folder
--exclude "**/*.pt" "**/*.joblib" \ # skip weights/artifacts
--local-dir PeptiVerse_data \
--local-dir-use-symlinks False # make real copies
```
- Or in python
```python
from huggingface_hub import snapshot_download
local_dir = snapshot_download(
repo_id="ChatterjeeLab/PeptiVerse_data",
allow_patterns=["training_data_cleaned/**"], # only this folder
ignore_patterns=["**/*.pt", "**/*.joblib"], # skip weights/artifacts
local_dir="PeptiVerse_data",
local_dir_use_symlinks=False, # make real copies
)
print("Downloaded to:", local_dir)
```
- Usage of the huggingface datasets (with pre-computed embeddings and splits)
- All embedding datasets are saved via `DatasetDict.save_to_disk` and loadable with:
``` python
from datasets import load_from_disk
ds = load_from_disk(PATH)
train_ds = ds["train"]
val_ds = ds["val"]
```
- A) Sequence Based ([ESM-2](https://huggingface.co/facebook/esm2_t33_650M_UR50D) embeddings)
- Pooled (fixed-length vector per sequence)
- Generated by mean-pooling token embeddings excluding special tokens (CLS/EOS) and padding.
- Each item:
sequence: `str`
label: `int` (classification) or `float` (regression)
embedding: `float32[H]` (H=1280 for ESM-2 650M)
- Unpooled (variable-length token matrix)
- Generated by keeping all valid token embeddings (excluding special tokens + padding) as a per-sequence matrix.
- Each item:
sequence: `str`
label: `int` (classification) or `float` (regression)
embedding: `float16[L, H]` (nested lists)
attention_mask: `int8[L]`
length: `int` (=L)
- B) SMILES-based ([PeptideCLM](https://github.com/AaronFeller/PeptideCLM) embeddings)
- Pooled (fixed-length vector per sequence)
- Generated by mean-pooling token embeddings excluding special tokens (CLS/EOS) and padding.
- Each item:
sequence: `str` (SMILES)
label: `int` (classification) or `float` (regression)
embedding: `float32[H]`
- Unpooled (variable-length token matrix)
- Generated by keeping all valid token embeddings (excluding special tokens + padding) as a per-sequence matrix.
- Each item:
sequence: `str` (SMILES)
label: `int` (classification) or `float` (regression)
embedding: `float16[L, H]` (nested lists)
attention_mask: `int8[L]`
length: `int` (=L)
- C) SMILES-based ([ChemBERTa](https://huggingface.co/DeepChem/ChemBERTa-77M-MLM) embeddings)
- Pooled (fixed-length vector per sequence)
- Generated by mean-pooling token embeddings excluding special tokens (CLS/EOS) and padding.
- Each item:
sequence: `str` (SMILES)
label: `int` (classification) or `float` (regression)
embedding: `float32[H]`
- Unpooled (variable-length token matrix)
- Generated by keeping all valid token embeddings (excluding special tokens + padding) as a per-sequence matrix.
- Each item:
sequence: `str` (SMILES)
label: `int` (classification) or `float` (regression)
embedding: `float16[L, H]` (nested lists)
attention_mask: `int8[L]`
length: `int` (=L)
### Training
Under the `training_classifiers` folder, we provide the python scripts used to train different models. The scripts will
1. Read the pre-processed Huggingface Dataset from `training_data_cleaned` folder;
2. Perform OPTUNA hyperparameter sweep once being called;
3. All training was conducted on HPC with SLURM script under `training_classifiers/src` folder;
4. Customize or isolate certain model training scripts as needed.
##### Example of training
###### ML models
```
HOME_LOC=/home
SCRIPT_LOC=$HOME_LOC/PeptiVerse/training_classifiers
EMB_LOC=$HOME_LOC/PeptiVerse/training_data_cleaned
OBJECTIVE='hemolysis' # nf/solubility/hemolysis/permeability_pampa/permeability_caco2
WT='smiles' # wt/smiles
DATA_FILE="hemo_${WT}_with_embeddings"
LOG_LOC=$SCRIPT_LOC/src/logs
DATE=$(date +%m_%d)
MODEL_TYPE='svm_gpu' # xgb/enet_gpu/svm_gpu
SPECIAL_PREFIX="${MODEL_TYPE}-${OBJECTIVE}-${WT}_new"
# Create log directory if it doesn't exist
mkdir -p $LOG_LOC
cd $SCRIPT_LOC
python -u train_ml.py \
--dataset_path "${DATA_LOC}/${OBJECTIVE}/${DATA_FILE}" \
--out_dir "${SCRIPT_LOC}/${OBJECTIVE}/${MODEL_TYPE}_${WT}" \
--model "${MODEL_TYPE}" \
--n_trials 200 > "${LOG_LOC}/${DATE}_${SPECIAL_PREFIX}.log" 2>&1
```
###### DNN models
```
HOME_LOC=/home
SCRIPT_LOC=$HOME_LOC/PeptiVerse/training_classifiers
EMB_LOC=$HOME_LOC/PeptiVerse/training_data_cleaned
OBJECTIVE='nf' # nf/solubility/hemolysis
WT='smiles' #wt/smiles
DATA_FILE="nf_${WT}_with_embeddings_unpooled"
LOG_LOC=$SCRIPT_LOC/src/logs
DATE=$(date +%m_%d)
MODEL_TYPE='cnn' #mlp/cnn/transformer
SPECIAL_PREFIX="${MODEL_TYPE}-${OBJECTIVE}-${WT}"
# Create log directory if it doesn't exist
mkdir -p $LOG_LOC
cd $SCRIPT_LOC
python -u train_nn.py \
--dataset_path "${DATA_LOC}/${OBJECTIVE}/${DATA_FILE}" \
--out_dir "${SCRIPT_LOC}/${OBJECTIVE}/${MODEL_TYPE}_${WT}" \
--model "${MODEL_TYPE}" \
--n_trials 200 > "${LOG_LOC}/${DATE}_${SPECIAL_PREFIX}.log" 2>&1
```
###### Binding Affinity
```
HOME_LOC=/home
SCRIPT_LOC=$HOME_LOC/PeptiVerse/training_classifiers
EMB_LOC=$HOME_LOC/PeptiVerse/training_data_cleaned
OBJECTIVE='binding_affinity'
BINDER_MODEL='chemberta' # peptideclm / chemberta
STATUS='unpooled' # pooled / unpooled
TYPE='smiles'
DATA_FILE='pair_wt_${TYPE}_${STATUS}'
LOG_LOC=$SCRIPT_LOC/src/logs
DATE=$(date +%m_%d)
SPECIAL_PREFIX="${OBJECTIVE}-${BINDER_MODEL}-${STATUS}"
python -u binding_training.py \
--dataset_path "${EMB_LOC}/${OBJECTIVE}/${BINDER_MODEL}/${DATA_FILE}" \
--mode "${STATUS}" \
--out_dir "${SCRIPT_LOC}/${OBJECTIVE}/${BINDER_MODEL}_${TYPE}_${STATUS}" \
--n_trials 200 > "${LOG_LOC}/${DATE}_${SPECIAL_PREFIX}.log" 2>&1
```
### Quick inference by property per model
```python
from inference import PeptiVersePredictor
from pathlib import Path
root = Path(__file__).resolve().parent # current script folder
predictor = PeptiVersePredictor(
manifest_path=root / "best_models.txt",
classifier_weight_root=root,
device="cuda", # or "cpu"
)
# mode: smiles (SMILES-based models) / wt (Sequence-based models)
# property keys (with some level of name normalization)
# hemolysis
# nf (Non-Fouling)
# solubility
# permeability_penetrance
# toxicity
# permeability_pampa
# permeability_caco2
# halflife
# binding_affinity
seq = "GIVEQCCTSICSLYQLENYCN"
smiles = "CC(C)C[C@@H]1NC(=O)[C@@H](CC(C)C)N(C)C(=O)[C@@H](C)N(C)C(=O)[C@H](Cc2ccccc2)NC(=O)[C@H](CC(C)C)N(C)C(=O)[C@H]2CCCN2C1=O"
# Hemolysis
out = pred.predict_property("hemolysis", mode="wt", input_str=seq)
print(out)
# {"property":"hemolysis","mode":"wt","score":prob,"label":0/1,"threshold":...}
out = pred.predict_property("hemolysis", mode="smiles", input_str=smiles)
print(out)
# Non-fouling (key is nf)
out = pred.predict_property("nf", mode="wt", input_str=seq)
print(out)
out = pred.predict_property("nf", mode="smiles", input_str=smiles)
print(out)
# Solubility (Sequence-only)
out = pred.predict_property("solubility", mode="wt", input_str=seq)
print(out)
# Permeability (Penetrance) (Sequence-only)
out = pred.predict_property("permeability_penetrance", mode="wt", input_str=seq)
print(out)
# Toxicity (SMILES-only)
out = pred.predict_property("toxicity", mode="smiles", input_str=smiles)
print(out)
# Permeability (PAMPA) (SMILES regression)
out = pred.predict_property("permeability_pampa", mode="smiles", input_str=smiles)
print(out)
# {"property":"permeability_pampa","mode":"smiles","score":value}
# Permeability (Caco-2) (SMILES regression)
out = pred.predict_property("permeability_caco2", mode="smiles", input_str=smiles)
print(out)
# Half-life (sequence-based + SMILES regression)
out = pred.predict_property("halflife", mode="wt", input_str=seq)
print(out)
out = pred.predict_property("halflife", mode="smiles", input_str=smiles)
print(out)
# Binding Affinity
protein = "MTEYKLVVVGAGGVGKSALTIQLIQNHFVDEYDPTIEDSYRKQV..." # target protein
peptide_seq = "GIVEQCCTSICSLYQLENYCN"
out = pred.predict_binding_affinity(
mode="wt",
target_seq=protein,
binder_str=peptide_seq,
)
print(out)
# {
# "property":"binding_affinity",
# "mode":"wt",
# "affinity": float,
# "class_by_threshold": "High (β₯9)" / "Moderate (7-9)" / "Low (<7)",
# "class_by_logits": same buckets,
# "binding_model": "pooled" or "unpooled",
# }
```
#### Advanced inference with uncertainty prediction
The uncertainty prediction is added as a parameter in the inference code. The full classifier folder from [zenodo]() is required to enable this functionality. The model uncertainty is reported via all the scripts listed under the `training_classifiers` folder starting with "**refit**". Detailed description can be found in the methodology part of the manuscript.
At inference time, PeptiVersePredictor returns an `uncertainty` field with every prediction when `uncertainty=True` is passed. The method and interpretation depend on the model class, determined automatically at inference time.
```python
seq = "GIGAVLKVLTTGLPALISWIKRKRQQ"
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"
print(predictor.predict_property("nf", "wt", seq, uncertainty=True))
print(predictor.predict_property("nf", "smiles", smiles, uncertainty=True))
{'property': 'nf', 'col': 'wt', 'score': 0.00014520535252195523, 'emb_tag': 'wt', 'label': 0, 'threshold': 0.57, 'uncertainty': 0.0017192508727321288, 'uncertainty_type': 'ensemble_predictive_entropy'}
{'property': 'nf', 'col': 'smiles', 'score': 0.025485480204224586, 'emb_tag': 'peptideclm', 'label': 0, 'threshold': 0.6969, 'uncertainty': 0.11868063130587676, 'uncertainty_type': 'binary_predictive_entropy_single_model'}
```
---
##### Method by Model Class
| Model Class | Task | Uncertainty Method | Output Type | Range |
|---|---|---|---|---|
| MLP, CNN, Transformer | Classifier | Deep ensemble predictive entropy (5 seeds) | `float` | [0, ln(2) β 0.693] |
| MLP, CNN, Transformer | Regression | Adaptive conformal interval; falls back to ensemble std if no MAPIE bundle | `(lo, hi)` or `float` | unbounded |
| SVM / SVC / XGBoost | Classifier | Binary predictive entropy (sigmoid of decision function) | `float` | [0, ln(2) β 0.693] |
| SVR / ElasticNet / XGBoost | Regression | Adaptive conformal interval | `(lo, hi)` | unbounded |
> **Uncertainty is `None`** when: a DNN classifier has no seed ensemble trained, or a regression model has no `mapie_calibration.joblib` in its model directory.
---
## Interpretation π
You can also find the same description in the paper or in the PeptiVerse app `Documentation` tab.
---
### π©Έ Hemolysis Prediction<br>
50% of read blood cells being lysed at x ug/ml concetration (HC50). If HC50 < 100uM, considered as hemolytic, otherwise non-hemolytic, resulting in a binary 0/1 dataset. The predicted probability should therefore be interpreted as a risk indicator, not an exact concentration estimate.<br>
**Output interpretation:**<br>
- Score close to 1.0 = high probability of red blood cell membrane disruption
- Score close to 0.0 = non-hemolytic
---
### π§ Solubility Prediction<br>
Outputs a probability (0β1) that a peptide remains soluble in aqueous conditions.<br>
**Output interpretation:**<br>
- Score close to 1.0 = highly soluble
- Score close to 0.0 = poorly soluble
---
### π― Non-Fouling Prediction<br>
Higher scores indicate stronger non-fouling behavior, desirable for circulation and surface-exposed applications.<br>
**Output interpretation:**<br>
- Score close to 1.0 = non-fouling
- Score close to 0.0 = fouling
---
### πͺ£ Permeability Prediction<br>
Predicts membrane permeability on a log P scale.<br>
**Output interpretation:**<br>
- Higher values = more permeable (>-6.0)
- For penetrance predictions, it is a classification prediction, so within the [0, 1] range, closer to 1 indicates more permeable.
---
### β±οΈ Half-Life Prediction<br>
**Interpretation:** Predicted values reflect relative peptide stability for the unit in hours. Higher scores indicate longer persistence in serum, while lower scores suggest faster degradation.<br>
---
### β οΈ Toxicity Prediction<br>
**Interpretation:** Outputs a probability (0β1) that a peptide exhibits toxic effects. Higher scores indicate increased toxicity risk.<br>
---
### π Binding Affinity Prediction <br>
Predicts peptide-protein binding affinity. Requires both peptide and target protein sequence.<br>
**Interpretation:**<br>
- Scores β₯ 9 correspond to tight binders (K β€ 10β»βΉ M, nanomolar to picomolar range)<br>
- Scores between 7 and 9 correspond to medium binders (10β»β·β10β»βΉ M, nanomolar to micromolar range)<br>
- Scores < 7 correspond to weak binders (K β₯ 10β»βΆ M, micromolar and weaker)<br>
- A difference of 1 unit in score corresponds to an approximately tenfold change in binding affinity.<br>
---
### Uncertainty Interpretation <br>
#### Entropy (classifiers)<br>
Binary predictive entropy of the output probability pΜ:<br>
$$\mathcal{H} = -\bar{p}\log\bar{p} - (1 - \bar{p})\log(1 - \bar{p})$$<br>
- For **DNN classifiers**: pΜ is the mean probability across 5 independently seeded models (deep ensemble). High entropy reflects both epistemic uncertainty (seed disagreement) and aleatoric uncertainty (collectively diffuse predictions).<br>
- For **XGBoost / SVM / ElasticNet classifiers**: pΜ is the single model's output probability (or sigmoid of decision function for ElasticNet). Entropy reflects output confidence of a single model only.<br>
| Range | Interpretation |
|---|---|
| < 0.1 | High confidence |
| 0.1 β 0.4 | Moderate uncertainty |
| 0.4 β 0.6 | Low confidence |
| > 0.6 | Very low confidence β model close to guessing |
| β 0.693 | Maximum uncertainty β predicted probability β 0.5 |
---
#### Adaptive Conformal Prediction Interval (regressors)<br>
Returned as a tuple `(lo, hi)` with 90% marginal coverage guarantee.<br>
We implement the **residual normalised conformity score** following [Lei et al. (2018)](https://doi.org/10.1080/01621459.2017.1307116) and [Cordier et al. (2023) / MAPIE](https://proceedings.mlr.press/v204/cordier23a.html). An auxiliary XGBoost model $\hat{\sigma}(\mathbf{x})$ is trained on held-out embeddings and absolute residuals |yα΅’ β Ε·α΅’|. At inference:<br>
$$[\hat{y}(\mathbf{x}) - q \cdot \hat{\sigma}(\mathbf{x}),\ \hat{y}(\mathbf{x}) + q \cdot \hat{\sigma}(\mathbf{x})]$$
where q is the β(n+1)(1βΞ±)β / n quantile of the normalized scores sα΅’ = |yα΅’ β Ε·α΅’| / ΟΜ(xα΅’).
- **Interval width varies per input** -- molecules more dissimilar to training data tend to receive wider intervals<br>
- **Coverage guarantee**: on exchangeable data, P(y β [Ε· β qΟΜ, Ε· + qΟΜ]) β₯ 0.90<br>
- **The guarantee is marginal**, not conditional, as an unusually narrow interval on an out-of-distribution molecule does not guarantee correctness<br>
- **Full access**: We already computed MAPIE for all regression models; users are allowed to directly use them for customized model lists.<br>
---
#### Generating a MAPIE Bundle for a New Model<br>
To enable conformal uncertainty for a newly trained regression model:<br>
```bash
# Fit adaptive conformal bundle from val_predictions.csv
python fit_mapie_adaptive.py --root training_classifiers --prop <property_name>
```
The script reads `sequence`/`smiles` and `y_pred`/`y_true` columns from the CSV, recomputes embeddings, fits the XGBoost $\hat{\sigma}$ model, and saves `mapie_calibration.joblib` into the model directory. The bundle is automatically detected and loaded by `PeptiVersePredictor` on the next initialization.<br>
## Model Architecture π
- **Sequence Embeddings:** [ESM-2 650M model](https://huggingface.co/facebook/esm2_t33_650M_UR50D) / [PeptideCLM model](https://huggingface.co/aaronfeller/PeptideCLM-23M-all) / [ChemBERTa](https://huggingface.co/DeepChem/ChemBERTa-77M-MLM). Foundational embeddings are frozen.
- **XGBoost Model:** Gradient boosting on pooled embedding features for efficient, high-performance prediction.
- **CNN/Transformer Model:** One-dimensional convolutional/self-attention transformer networks operating on unpooled embeddings to capture local sequence patterns.
- **Binding Model:** Transformer-based architecture with cross-attention between protein and peptide representations.
- **SVR Model:** Support Vector Regression applied to pooled embeddings, providing a kernel-based, nonparametric regression baseline that is robust on smaller or noisy datasets.
- **Others:** SVM and Elastic Nets were trained with [RAPIDS cuML](https://github.com/rapidsai/cuml), which requires a CUDA environment and is therefore not supported in the web app. Model checkpoints remain available in the Hugging Face repository.
## Troubleshooting π
### LFS Download Issues
If files appear as SHA pointers:
```bash
huggingface-cli download ChatterjeeLab/PeptiVerse \
training_data_cleaned/hemolysis/hemo_smiles_meta_with_split.csv \
--local-dir . \
--local-dir-use-symlinks False
```
## Citation π
If you find this repository helpful for your publications, please consider citing our paper:
```
@article {Zhang2025.12.31.697180,
author = {Zhang, Yinuo and Tang, Sophia and Chen, Tong and Mahood, Elizabeth and Vincoff, Sophia and Chatterjee, Pranam},
title = {PeptiVerse: A Unified Platform for Therapeutic Peptide Property Prediction},
elocation-id = {2025.12.31.697180},
year = {2026},
doi = {10.64898/2025.12.31.697180},
publisher = {Cold Spring Harbor Laboratory},
URL = {https://www.biorxiv.org/content/early/2026/01/03/2025.12.31.697180},
eprint = {https://www.biorxiv.org/content/early/2026/01/03/2025.12.31.697180.full.pdf},
journal = {bioRxiv}
}
```
To use this repository, you agree to abide by the MIT License.
|