DSM (Diffusion Sequence Model) is a novel Protein Language Model (pLM) developed in collaboration between the
Gleghorn Lab
and
Synthyra
. It was trained with masked diffusion to enable both high-quality representation learning and generative protein design. This repository contains the code for training, evaluating, and applying DSM and its variants.
DSM is capable of generating diverse, biomimetic sequences that align with expected amino acid compositions, secondary structures, and predicted functions. Furthermore, DSM's learned representations match or exceed those of comparably sized pLMs on various downstream tasks. DSM is detailed extensively in our
preprint
(which is currently in review). Beyond the base and PPI variants, we are currently training versions to jointly diffuse over sequence and foldseek tokens, as well as
Annotation Vocabulary
tokens. Since the preprint release, Synthyra has trained
Synthyra/DSM_ppi_full
which neglects the LoRA PPI training in favor for full finetuning. Additionally, the sequences SeqA and SeqB are jointly masked instead of just SeqB in the original version. We plan on adding the
many
new results to the second version of the preprint and eventual journal article.
This section outlines how to use a trained
DSM
model for common generation tasks. The core generation logic is provided by the
GenerateMixin
class, used by
DSM
models.
First, ensure you have a trained model (either one you trained or a pre-trained one from Hugging Face Hub) and the necessary environment set up.
import torch
from models.modeling_dsm import DSM # Or DSM_ppi for binder generation# Load a pre-trained model
model_name_or_path = "GleghornLab/DSM_650"# Replace with your model of choice
device = torch.device("cuda"if torch.cuda.is_available() else"cpu")
model = DSM.from_pretrained(model_name_or_path).to(device).eval()
tokenizer = model.tokenizer
You are using a model of type esm_diff to instantiate a model of type dsm. This is not supported for all configurations of models and can yield errors.
This warning is normal - all good!
1. Unconditional Sequence Generation
To generate a novel sequence of a specific length. DSM uses a progressive denoising approach.
### Unconditional generation
length = 100
mask_token = tokenizer.mask_token
# optionally, enforce starting with methionine
input_tokens = tokenizer.encode('M' + ''.join([mask_token] * (length - 1)), add_special_tokens=True, return_tensors='pt').to(device)
output = model.mask_diffusion_generate(
tokenizer=tokenizer,
input_tokens=input_tokens,
step_divisor=100, # lower is slower but better
temperature=1.0, # sampling temperature
remasking="random", # strategy for remasking tokens not kept
preview=False, # set this to True to watch the mask tokens get rilled in real time
slow=False, # adds a small delay to the real time filling (because it is usually very fast and watching carefully is hard!)
return_trajectory=False# set this to True to return the trajectory of the generation (what you watch in the preview)
) # Note: output will be a tuple if return_trajectory is True
generated_sequences = model.decode_output(output)
print(f"Generated sequence: {generated_sequences[0]}")
# Mask Filling / Inpainting
template_sequence = "MA<mask><mask><mask>KEG<mask><mask>STL"
input_tokens = tokenizer.encode(template_sequence, add_special_tokens=True, return_tensors='pt').to(device)
output = model.mask_diffusion_generate(
tokenizer=tokenizer,
input_tokens=input_tokens,
step_divisor=100, # lower is slower but better
temperature=1.0, # sampling temperature
remasking="random", # strategy for remasking tokens not kept
preview=False, # set this to True to watch the mask tokens get rilled in real time
slow=False, # adds a small delay to the real time filling (because it is usually very fast and watching carefully is hard!)
return_trajectory=False# set this to True to return the trajectory of the generation (what you watch in the preview)
) # Note: output will be a tuple if return_trajectory is True
generated_sequences = model.decode_output(output)
print(f"Generated sequence: {generated_sequences[0]}")
Generated sequence: MAVKFKEGGISTL
3. Conditional Generation (e.g., Binders - using DSM-ppi)
# from models.modeling_dsm import DSM_ppi# model_binder = DSM_ppi.from_pretrained("GleghornLab/DSM_650_ppi_lora").to(device).eval()# The lora version from the paper leads to unreliable outputs# Synthyra has generously trained a version through full fine tuning
model = DSM.from_pretrained("Synthyra/DSM_ppi_full").to(device).eval()
# BBF-14
target_seq = "MGTPLWALLGGPWRGTATYEDGTKVTLDYRYTRVSPDRLRADVTYTTPDGTTLEATVDLWKDANGVIRYHATYPDGTSADGTLTQLDADTLLATGTYDDGTKYTVTLTRVAPGSGWHHHHHH"# For binder generation, the 'interactor' (SeqB) part is what gets generated/filled.# Start with a fully masked interactor of desired length.
interactor_template_len = 256
interactor_template = ''.join([mask_token] * interactor_template_len)
combined_input_str = target_seq + '<eos>' + interactor_template
input_tokens = tokenizer.encode(combined_input_str, add_special_tokens=True, return_tensors='pt').to(device)
output = model.mask_diffusion_generate(
tokenizer=tokenizer,
input_tokens=input_tokens,
step_divisor=100, # lower is slower but better
temperature=1.0, # sampling temperature
remasking="random", # strategy for remasking tokens not kept
preview=False, # set this to True to watch the mask tokens get rilled in real time
slow=False, # adds a small delay to the real time filling (because it is usually very fast and watching carefully is hard!)
return_trajectory=False# set this to True to return the trajectory of the generation (what you watch in the preview)
) # Note: output will be a tuple if return_trajectory is True
target, binder = model.decode_dual_input(output, seperator='<eos>')
# Parse out the generated interactor part based on EOS tokens.# Example: generated_full_seq_str.split(model_binder.tokenizer.eos_token)[1]print(f"Generated binder {binder[0]}")
Synthyra/DSM_ppi_full
was actually trained to fill masks from any part of SeqA and SeqB. That means you can fully hallucinate plausibly interacting protein pairs.
seq_a_length = 128
seq_b_length = 128
seq_a_template = ''.join([mask_token] * seq_a_length)
seq_b_template = ''.join([mask_token] * seq_b_length)
combined_input_str = seq_a_template + '<eos>' + seq_b_template
input_tokens = tokenizer.encode(combined_input_str, add_special_tokens=True, return_tensors='pt').to(device)
output = model.mask_diffusion_generate(
tokenizer=tokenizer,
input_tokens=input_tokens,
step_divisor=10, # lower is slower but better
temperature=1.0, # sampling temperature
remasking="random", # strategy for remasking tokens not kept
preview=False, # set this to True to watch the mask tokens get rilled in real time
slow=False, # adds a small delay to the real time filling (because it is usually very fast and watching carefully is hard!)
return_trajectory=False# set this to True to return the trajectory of the generation (what you watch in the preview)
) # Note: output will be a tuple if return_trajectory is True
seqa, seqb = model.decode_dual_input(output, seperator='<eos>')
# Parse out the generated interactor part based on EOS tokens.# Example: generated_full_seq_str.split(model_binder.tokenizer.eos_token)[1]print(f"SeqA: {seqa[0][5:]}") # remove cls tokenprint(f"SeqB: {seqb[0]}")
There are various demos with many more to come. For example, in
demo_dsm_ppi_full.py
(run by
python -m demos.demo_dsm_ppi_full
) we perform a test on DSM-ppi.
We take 1000 protein pairs from BIOGRID (real protein-protein interactions) and 1000 from Negatome (non interacting protein pairs) and mask the second sequence (SeqB) by 50%.
This acts as a sanity check, as we expect the accuracy on reconstructing real positive PPIs to be higher than the accuracy on non-interacting proteins.
Indeed, this is the case:
Set up the Python virtual environment:
The
setup_bioenv.sh
script creates a virtual environment named
bioenv
in your home directory (
~/bioenv
), installs PyTorch with CUDA 12.6 support, and then installs all other dependencies from
requirements.txt
.
Make the script executable:
chmod +x setup_bioenv.sh
Run the script:
./setup_bioenv.sh
If you are not on a linux machine, you can install the requirements directly
python -m pip install -r requirements.txt
Activate the environment:
Each time you want to work on this project, activate the virtual environment:
source ~/bioenv/bin/activate
To deactivate the environment:
deactivate
Training
The primary script for training models is
training/train_dsm.py
. This script further pretrains an ESM2 checkpoint using the DSM objective (masked diffusion based on LLaDA) on a large protein sequence dataset like
OMG-prot50
.
Main Training Script:
train_dsm.py
Base Model
: DSM models are extended from pre-trained ESM2 checkpoints (e.g., ESM2-150M, ESM2-650M).
Training Objective
: Masked diffusion loss, where the model predicts masked tokens. The loss is scaled by
1/(t + epsilon)
where
t
is the corruption level, penalizing errors more at low mask rates.
Language Modeling Head
: Uses a modified head with a soft-logit cap (
tau=30
) and tied output projection weights to the token embeddings.
Data Handling
:
Training data can be streamed from datasets like
Synthyra/omg_prot50
(a version of Open MetaGenomic dataset clustered at 50% identity).
Uses
data.dataset_classes.SequenceDatasetFromList
for validation/test sets and
data.dataset_classes.IterableDatasetFromHF
for streaming training.
data.data_collators.SequenceCollator
is used for batching.
Training Process
:
Utilizes Hugging Face
TrainingArguments
.
A custom
IterableTrainer
(from
training.iterable_trainer.py
) handles iterable datasets.
Uses AdamW optimizer and a cosine learning rate scheduler with linear warmup.
Supports logging to Weights & Biases (wandb).
The trained model can be pushed to Hugging Face Hub.
Example checkpoints mentioned in the paper:
DSM-150
(from ESM2-150M, 100k steps, batch 32, seqlen 512, LR 1e-4) and
DSM-650
(from ESM2-650M, 100k steps, global batch 128, seqlen 2048, LR 1e-4).
Training involves conditioning on a target sequence (SeqA) to generate an interactor (SeqB) using the format
[CLS]--SeqA--[EOS]--[MASKED~SeqB]--[EOS]
.
LoRA (Low-Rank Adaptation) can be applied to attention layers for efficient fine-tuning.
And
training/iterable_trainer.py
provides the
get_iterable_trainer
function used by
train_dsm.py
to enable training with iterable datasets.
Evaluation
The repository includes a comprehensive suite for evaluating model performance, focusing on:
Sequence Reconstruction (Mask Filling):
Evaluated by masking validation/test sets at various corruption rates (5% to 90%) and measuring cross-entropy loss, weighted F1 score, and Alignment Score (ASc) for the masked positions.
The script
evaluation/mask_filling.py
is central to this.
Unconditional Generation Quality:
Generate a corpus of sequences based on lengths from a reference set (e.g., validation data).
Compare distributions (1-mers, 2-mers, 3-mers) of amino acids and predicted secondary structures between generated and natural sequences using χ² test and Jensen-Shannon (JS) divergence.
Compare distributions of predicted functional annotations (e.g., using Annotation Vocabulary - AV terms).
Scripts involved:
evaluation/unconditional_generation_tuning.py
(to find optimal generation parameters like temperature and step divisor
s
),
evaluation/unconditional_generation.py
,
evaluation/ss_pred.py
(using
production_ss4_model
or
production_ss9_model
),
evaluation/annotate_comparisons.py
,
evaluation/compare_distributions.py
,
evaluation/plot_distribution_comparisons.py
.
The
run_eval_pipeline.py
script automates this workflow.
Representation Quality (Model Probing):
Evaluate learned embeddings by training linear probes (or simple transformer blocks) on various downstream tasks (e.g., secondary structure prediction, localization prediction, etc.).
Performance is compared against random vectors, randomized transformers, and other established pLMs.
The assessment was done with
Protify
, an open-source framework that can be used for pLM training and evaluation.
Conditional Generation (Binder Design for DSM-ppi):
Evaluate DSM-ppi on benchmarks like BenchBB.
Generate binders for target proteins using template-based masking strategies.
Assess generated binders using
in-silico
tools like Synteract2 for predicted binding affinity (ppKd).
The
evaluation/
directory also contains a
readme.md
which provides further details on some evaluation workflows. Key metrics used include:
Alignment Score (ASc):
A normalized Needleman-Wunsch global alignment score (using BLOSUM62) to measure sequence similarity, robust to length variations. ASc(a, b) = l/(f(a, a) - f(a, b) + l).
Jensen-Shannon (JS) Divergence:
To compare distributions of k-mers and functional terms.
Running the Full Unconditional Evaluation Pipeline:
The
evaluation/
directory contains additional scripts for more specific analyses. These are typically run independently:
evaluation/all_targets_uncond.py
and
evaluation/all_targets_cond.py
: Likely for evaluating generation towards specific targets, unconditionally and conditionally.
evaluation/conditional_binder.py
and
evaluation/unconditional_binder.py
: Suggest evaluation focused on generating protein binders.
evaluation/unconditional_by_length.py
: May evaluate unconditional generation focusing on sequence length distributions.
evaluation/utils.py
: Utility functions for evaluation scripts.
Users should refer to individual scripts (e.g., using
python -m evaluation.<script_name> --help
) for their specific usage and arguments.
The
evaluation/
directory also contains a
readme.md
which provides further details on the unconditional generation evaluation workflow.
Results
DSM demonstrates strong performance in both protein sequence generation and representation learning, establishing masked diffusion as a powerful paradigm.
Biomimetic Sequence Generation
: Unconditionally generated DSM sequences closely mimic natural protein distributions in terms of amino acid k-mers, predicted secondary structures (JS divergence < 0.01 for AA k-mers), and predicted functional annotations (AV terms, JS divergence ~0.1). This suggests DSM captures underlying biological principles.
Superior Sequence Reconstruction
: DSM models significantly outperform MLM-based ESM2 models in reconstructing sequences from highly corrupted inputs (up to 90% masking).
At 90% masking, DSM achieves an Alignment Score (ASc) of ~0.27, considerably higher than random.
DSM models show higher F1 scores in reconstruction tasks compared to DPLM models, especially at high mask rates.
High-Quality Embeddings
: DSM embeddings match or exceed the quality of those from comparably sized pLMs (ESM2, DPLM) and even larger autoregressive models (ProtCLM 1B) on various downstream tasks evaluated by linear probing.
DSM-650
generally provides the best representations among tested models of similar size.
Effective Binder Design (DSM-ppi):
DSM-ppi fine-tuned on protein-protein interaction data, demonstrates the ability to generate protein binders conditioned on target sequences.
On the BenchBB benchmark, DSM-generated binders (both unconditional DSM and conditional DSM-ppi) show promising predicted binding affinities, in some cases superior to known binders. For example, designs for EGFR showed high predicted pKd and good structural metrics (ipTM, pTM with AlphaFold3).
Efficiency
: DSM can generate realistic protein sequences from a single forward pass during reconstruction tasks at high mask rates, offering potential efficiency advantages over iterative AR or some discrete diffusion models.
These results highlight DSM's capability to unify high-quality protein representation learning and biologically coherent generative modeling within a single framework.
Cite
@misc{hallee2025diffusionsequencemodelsenhanced,
title={Diffusion Sequence Models for Enhanced Protein Representation and Generation},
author={Logan Hallee and Nikolaos Rafailidis and David B. Bichara and Jason P. Gleghorn},
year={2025},
eprint={2506.08293},
archivePrefix={arXiv},
primaryClass={q-bio.BM},
url={https://arxiv.org/abs/2506.08293},
}
Runs of Synthyra DSM_ppi_full on huggingface.co
22
Total runs
0
24-hour runs
0
3-day runs
2
7-day runs
-82
30-day runs
More Information About DSM_ppi_full huggingface.co Model
DSM_ppi_full huggingface.co
DSM_ppi_full huggingface.co is an AI model on huggingface.co that provides DSM_ppi_full's model effect (), which can be used instantly with this Synthyra DSM_ppi_full model. huggingface.co supports a free trial of the DSM_ppi_full model, and also provides paid use of the DSM_ppi_full. Support call DSM_ppi_full model through api, including Node.js, Python, http.
DSM_ppi_full huggingface.co is an online trial and call api platform, which integrates DSM_ppi_full's modeling effects, including api services, and provides a free online trial of DSM_ppi_full, you can try DSM_ppi_full online for free by clicking the link below.
Synthyra DSM_ppi_full online free url in huggingface.co:
DSM_ppi_full is an open source model from GitHub that offers a free installation service, and any user can find DSM_ppi_full on GitHub to install. At the same time, huggingface.co provides the effect of DSM_ppi_full install, users can directly use DSM_ppi_full installed effect in huggingface.co for debugging and trial. It also supports api for free installation.