This is the official repository for NanobodyBenchmark, designed to evaluate and compare various pre-trained language models for single-domain antibodies on downstream tasks.
Key dependencies: torch==1.13.1+cu117, transformers==4.38.1
git clone https://github.com/ZHymLumine/NbBench.git
cd NbBench
conda create -n nbbench python=3.8 -y
pip install -r requirements.txtWe evaluate multiple open-source pre-trained models. Download these model weights to the corresponding checkpoint/opensource/{model_name} directory.
Supported models and their Hugging Face repository URLs: ZYMScott/NbBench
| Model Name | Hugging Face Repository |
|---|---|
| ESM2-150M | facebook/esm2_t30_150M_UR50D |
| ESM2-650M | facebook/esm2_t33_650M_UR50D |
| ProtBERT | Rostlab/prot_bert |
| AblangL | qilowoq/AbLang_heavy |
| AblangH | qilowoq/AbLang_light |
| AnTiberty | ZYMScott/antiberty or from PyPI weights |
| AntiBERTa2 | alchemab/antiberta2 |
| AntiBERTa2-cssp | alchemab/antiberta2-cssp |
| IgBERT | Exscientia/IgBert |
| NanoBERT | NaturalAntibody/nanoBERT |
| VHHBert | COGNANO/VHHBERT |
NanobodyBenchmark
├── checkpoint
│ └── opensource
│ ├── esm2
│ ├── protbert
│ ├── ablang_l
│ ├── ablang_h
│ ├── antiberta2
│ ├── vhhbert
│ ├── igbert
│ ├── iglm
│ ├── antiberty
│ └── nanobert
├── data_utils
│ ├── Data processing tools
│ └── Clustering results
├── downstream
│ ├── train_cdr_classification.py
│ ├── train_interaction.py
│ ├── train_sdab_type.py
│ ├── train_cdr_infilling.py
│ ├── train_paratope.py
│ ├── train_vhh_affinity.py
│ ├── train_thermo.py
│ └── train_polyreaction.py
├── model
│ ├── esm2
│ ├── protbert
│ ├── ablang_l
│ ├── ablang_h
│ ├── antiberta2
│ ├── vhhbert
│ ├── igbert
│ ├── antiberty
│ └── nanobert
├── tokenizer
└── scripts
└── opensource
Current supported downstream tasks:
Nanobody (single-domain antibody) type classification(VHH, VNAR, etc.)Variable region classificationCDR region infillingParatope predictionAffinity predictionThermostability predictionPolyreactivity predictionAntigen-antibody interaction prediction
NanobodyBenchmark now supports loading datasets directly from Hugging Face Dataset Hub or downloading them to local storage. This provides flexibility and easier access to benchmark datasets.
The following datasets are available on Hugging Face collection:
- Binding Prediction:
- VR Classification
- CDR Infilling
- Thermostability:
- Affinity:
- Polyreactivity
- Nanobody type
You can load datasets from Hugging Face in three ways:
-
Direct Loading - Use the dataset from Hugging Face without downloading:
-
Download to Local Path - Download the dataset to your local
data/downstreamdirectory.
For the interaction prediction task, the model requires antigen embeddings. These embeddings are automatically downloaded from the Hugging Face dataset repository. No additional steps are needed.
Currently supported pre-trained models:
ESM2ProtBERTAblangLAblangHAntiBERTa2VHHBertIgBERTAnTibertyNanoBERT
To evaluate models on all nanobody tasks, run the bash scripts in the scripts folder:
cd NbBench
bash ./scripts/opensource/{model_name}/all_tasks.shHere's how to get embeddings from a sample single-domain antibody sequence:
import torch
from transformers import EsmModel, EsmTokenizer
from tqdm import tqdm
import pandas as pd
model_name = "facebook/esm2_t33_650M_UR50D"
tokenizer = EsmTokenizer.from_pretrained(model_name)
model = EsmModel.from_pretrained(model_name)
model.eval().cuda()
def get_unique_sequences(csv_files):
sequences = set()
for file in csv_files:
df = pd.read_csv(file)
sequences.update(df["seq"].dropna().unique())
return list(sequences)
def get_embedding(sequence, max_seq_length):
inputs = tokenizer(sequence, padding="max_length", return_tensors="pt", truncation=True, max_length=max_seq_length)
with torch.no_grad():
outputs = model(**{k: v.cuda() for k, v in inputs.items()})
last_hidden_state = outputs.last_hidden_state.cpu()
return last_hidden_state # shape: [hidden_size]
def save_embeddings_pt(sequences, output_path):
max_seq_length = max(len(seq) for seq in sequences)
emb_dict = {}
for seq in sequences:
emb = get_embedding(seq, max_seq_length)
emb_dict[seq] = emb
torch.save(emb_dict, output_path)
print(f"Saved {len(emb_dict)} embeddings to {output_path}")
csv_files = ["train.csv", "val.csv", "test.csv"]
sequences = get_unique_sequences(csv_files)
save_embeddings_pt(sequences, "antigen_embeddings.pt")or you can download the precomputed antigen_embeddings.pt file from huggingface
This repository is released under the Apache License 2.0, as detailed in the LICENSE file.
If you use this repository in your research, please consider citing our paper:
@misc{zhang2025nbbenchbenchmarkinglanguagemodels,
title={NbBench: Benchmarking Language Models for Comprehensive Nanobody Tasks},
author={Yiming Zhang and Koji Tsuda},
year={2025},
eprint={2505.02022},
archivePrefix={arXiv},
primaryClass={cs.LG},
url={https://arxiv.org/abs/2505.02022},
}

