ESM Cambrian (ESMC)
Pre-trained model on protein sequences using a masked language modeling (MLM) objective.
Disclaimer
This is an UNOFFICIAL implementation of the Language Modeling Materializes a World Model of Protein Biology by Salvatore Candido, Thomas Hayes, Alexander Derry, Roshan Rao, Zeming Lin, Alexander Rives, et al.
The OFFICIAL repository of ESMC is at Biohub/esm.
Tip
The MultiMolecule team has confirmed that the provided model and checkpoints are producing the same intermediate representations as the original implementation.
The team releasing ESMC did not write this model card for this model so this model card has been written by the MultiMolecule team.
Model Details
ESM Cambrian is an encoder-only protein language model trained on billions of protein sequences in a self-supervised fashion. The model learns protein representations by predicting masked amino-acid tokens from sequence context. Please refer to the Training Details section for more information on the training process.
Variants
Model Specification
| Variants |
Num Layers |
Hidden Size |
Num Heads |
Intermediate Size |
Num Parameters (M) |
FLOPs (G) |
MACs (G) |
Max Num Tokens |
| ESMC-6B |
80 |
2560 |
40 |
6912 |
6351.87 |
6716.35 |
3355.44 |
2048 |
| ESMC-600M |
36 |
1152 |
18 |
3072 |
574.97 |
631.66 |
315.28 |
| ESMC-300M |
30 |
960 |
15 |
2560 |
332.95 |
370.71 |
184.97 |
Links
- Code: multimolecule.esmc
- Data: UniRef, MGnify, and Joint Genome Institute
- Paper: Language Modeling Materializes a World Model of Protein Biology
- Developed by: Salvatore Candido, Thomas Hayes, Alexander Derry, Roshan Rao, Zeming Lin, Robert Verkuil, Bryan Wu, Jin Sub Lee, Elise S. Bruguera, Jehan A. Keval, Mykhailo Kopylov, John E. Pak, Wesley Wu, Neil Thomas, Samson Mataraso, Alvin Hsu, Ashton C. Trotman-Grant, Kilian Fatras, Allan dos Santos Costa, Rohil Badkundri, Halil Akin, Deniz Oktay, Jonathan Deaton, Elizabeth Montabana, Hrishita Sitwala, Yue Yu, Marius Wiggert, Dylan Alexander Carlin, Anthony W. Goering, Tomasz Blazejewski, McCullen Sandora, Michael Hla, Tina Z. Jia, Leon H. Kloker, Nicholas J. Sofroniew, Masatoshi Uehara, Jassi Pannu, Sharrol Bachas, Daniel S. Liu, Tom Sercu, Alexander Rives
- Model type: Encoder-only Transformer with rotary position embeddings, QK layer normalization, and SwiGLU feed-forward blocks
- Original Repository: Biohub/esm
Usage
The model file depends on the multimolecule library. You can install it using pip:
| Bash |
|---|
| pip install multimolecule
|
Direct Use
Masked Language Modeling
You can use this model directly with a pipeline for masked language modeling:
| Python |
|---|
| import multimolecule # you must import multimolecule to register models
from transformers import pipeline
predictor = pipeline("fill-mask", model="multimolecule/esmc-300m")
output = predictor("MSK<mask>EELFTGVVPILVELDGDVNGHK")
|
Downstream Use
Here is how to use this model to get the features of a given sequence in PyTorch:
| Python |
|---|
| from multimolecule import EsmCModel, ProteinTokenizer
tokenizer = ProteinTokenizer.from_pretrained("multimolecule/esmc-300m")
model = EsmCModel.from_pretrained("multimolecule/esmc-300m")
text = "MSKGEELFTGVVPILVELDGDVNGHK"
input = tokenizer(text, return_tensors="pt")
output = model(**input)
|
Sequence Classification / Regression
Note
This model is not fine-tuned for any specific task. You will need to fine-tune the model on a downstream task to use it for sequence classification or regression.
Here is how to use this model as backbone to fine-tune for a sequence-level task in PyTorch:
| Python |
|---|
| import torch
from multimolecule import EsmCForSequencePrediction, ProteinTokenizer
tokenizer = ProteinTokenizer.from_pretrained("multimolecule/esmc-300m")
model = EsmCForSequencePrediction.from_pretrained("multimolecule/esmc-300m")
text = "MSKGEELFTGVVPILVELDGDVNGHK"
input = tokenizer(text, return_tensors="pt")
label = torch.tensor([1])
output = model(**input, labels=label)
|
Token Classification / Regression
Note
This model is not fine-tuned for any specific task. You will need to fine-tune the model on a downstream task to use it for token classification or regression.
Here is how to use this model as backbone to fine-tune for a residue-level task in PyTorch:
| Python |
|---|
| import torch
from multimolecule import EsmCForTokenPrediction, ProteinTokenizer
tokenizer = ProteinTokenizer.from_pretrained("multimolecule/esmc-300m")
model = EsmCForTokenPrediction.from_pretrained("multimolecule/esmc-300m")
text = "MSKGEELFTGVVPILVELDGDVNGHK"
input = tokenizer(text, return_tensors="pt")
label = torch.randint(2, (len(text), ))
output = model(**input, labels=label)
|
Note
This model is not fine-tuned for any specific task. You will need to fine-tune the model on a downstream task to use it for contact classification or regression.
Here is how to use this model as backbone to fine-tune for a contact-level task in PyTorch:
| Python |
|---|
| import torch
from multimolecule import EsmCForContactPrediction, ProteinTokenizer
tokenizer = ProteinTokenizer.from_pretrained("multimolecule/esmc-300m")
model = EsmCForContactPrediction.from_pretrained("multimolecule/esmc-300m")
text = "MSKGEELFTGVVPILVELDGDVNGHK"
input = tokenizer(text, return_tensors="pt")
label = torch.randint(2, (len(text), len(text)))
output = model(**input, labels=label)
|
Training Details
ESMC used Masked Language Modeling (MLM) as the pre-training objective: taking a protein sequence, the model predicts amino-acid tokens that have been masked from the input sequence.
Training Data
ESMC was trained on protein sequences from UniRef, MGnify, and the Joint Genome Institute. The released materials describe ESMC as trained on approximately 2.8 billion protein sequences drawn from across life.
The upstream model card reports that sequence data was clustered at 70% sequence identity, resulting in 83 million UniRef clusters, 372 million MGnify clusters, and 2 billion JGI clusters.
Note that ProteinTokenizer will tokenize protein sequences using the MultiMolecule protein vocabulary for you.
Training Procedure
Preprocessing
ESMC tokenizes protein chains as amino-acid sequences and uses masked amino-acid prediction from surrounding sequence context. The released models use rotary position embeddings and were trained with context length up to 2048 tokens.
Pre-training
The upstream model card describes a two-stage training schedule.
- Stage 1: 1,000,000 steps with context length 512 and 64% metagenomic data.
- Stage 2: 500,000 steps with context length 2048 and 37.5% metagenomic data.
- Training FLOPs: 1.26e22 for ESMC-300M, 2.17e22 for ESMC-600M, and 2.37e23 for ESMC-6B.
Citation
| BibTeX |
|---|
| @UNPUBLISHED{Candido2026-wk,
title = "Language modeling materializes a world model of protein
biology",
author = "Candido, Salvatore and Hayes, Thomas and Derry, Alexander and
Rao, Roshan and Lin, Zeming and Verkuil, Robert and Wu, Bryan
Z and Lee, Jin Sub and Bruguera, Elise S and Keval, Jehan A
and Kopylov, Mykhailo and Pak, John E and Wu, Wesley and
Thomas, Neil and Mataraso, Samson and Hsu, Alvin and
Trotman-Grant, Ashton C and Fatras, Kilian and dos Santos
Costa, Allan and Badkundri, Rohil and Ak{\i}n, Halil and
Oktay, Deniz and Deaton, Jonathan and Montabana, Elizabeth and
Sitwala, Hrishita and Yu, Yue and Wiggert, Marius and Carlin,
Dylan Alexander and Goering, Anthony W and Blazejewski, Tomasz
and Sandora, Mccullen and Hla, Michael and Jia, Tina Z and
Kloker, Leon H and Sofroniew, Nicholas J and Uehara, Masatoshi
and Pannu, Jassi and Bachas, Sharrol and Liu, Daniel S and
Sercu, Tom and Rives, Alexander",
abstract = "Abstract Proteins are fundamental to life. The full extent of
their biology is beyond our ability to characterize with
experimental approaches in the physical laboratory. Accurate
digital representations could accelerate the discovery of
protein biology through virtual experiments. We propose
language modeling to learn unified and general representations
that can be scaled to all of protein biology. Building on
these representations, we develop a structure prediction model
that exceeds the performance of established methods for
biomolecular complex prediction across benchmarks, including
for the interactions of antibodies with their targets. A
simple search procedure yields high experimental success rates
for the discovery of proteins with nanomolar binding
affinities for both miniproteins and single-chain antibodies,
a modality critical for therapeutic design. Study of the
concepts in the language model's representation space reveals
a systematic organization aligned with the reductionist
understanding of proteins developed through empirical science.
Leveraging this organization, we generate a comprehensive map
of protein biology encompassing over 6.8 billion sequences and
1.1 billion predicted structures, identifying connections
across known and unknown biology. As a whole, this shows
language modeling as a powerful substrate for representing the
biology of proteins, operating across scales from the
prediction and design of protein interactions at the atomic
level, to identifying properties of proteins at different
levels of granularity and abstraction, to the scale of mapping
connections between proteins across billions of years of
evolution.",
journal = "bioRxiv",
institution = "bioRxiv",
month = jun,
year = 2026,
copyright = "http://creativecommons.org/licenses/by/4.0/"
}
|
Note
The artifacts distributed in this repository are part of the MultiMolecule project.
If MultiMolecule supports your research, please cite the MultiMolecule project as follows:
| BibTeX |
|---|
| @software{chen_2024_12638419,
author = {Chen, Zhiyuan and Zhu, Sophia Y.},
title = {MultiMolecule},
doi = {10.5281/zenodo.12638419},
publisher = {Zenodo},
url = {https://doi.org/10.5281/zenodo.12638419},
year = 2024,
month = may,
day = 4
}
|
Please use GitHub issues of MultiMolecule for any questions or comments on the model card.
Please contact the authors of the ESMC paper for questions or comments on the paper/model.
License
This model implementation is licensed under the GNU Affero General Public License.
For additional terms and clarifications, please refer to our License FAQ.
| Text Only |
|---|
| SPDX-License-Identifier: AGPL-3.0-or-later
|
API Reference
EsmCConfig
Bases: PreTrainedConfig
This is the configuration class to store the configuration of an
EsmCModel. It is used to instantiate an ESMC model according to the specified
arguments, defining the model architecture. Instantiating a configuration with the defaults will yield a similar
configuration to Biohub’s biohub/ESMC-300M architecture after conversion
to the MultiMolecule protein vocabulary.
Parameters:
| Name |
Type |
Description |
Default |
vocab_size
|
int
|
Vocabulary size of the ESMC model. MultiMolecule checkpoints use the standard
ProteinTokenizer vocabulary.
|
37
|
hidden_size
|
int | None
|
Dimensionality of the encoder layers.
|
None
|
num_hidden_layers
|
int | None
|
Number of hidden layers in the Transformer encoder.
|
None
|
num_attention_heads
|
int | None
|
Number of attention heads for each attention layer.
|
None
|
|
|
int | None
|
Dimensionality of the SwiGLU hidden projection after splitting the packed upstream projection. If None,
it is computed from hidden_size using ESMC’s 8 / 3 expansion rounded up to a multiple of 256.
|
None
|
hidden_act
|
str
|
The non-linear activation function used in the feed-forward layer. ESMC uses "swiglu".
|
'swiglu'
|
hidden_dropout
|
float
|
Dropout probability applied to residual branches.
|
0.0
|
attention_dropout
|
float
|
Dropout probability applied to attention probabilities.
|
0.0
|
max_position_embeddings
|
int
|
Maximum sequence length used for documentation and tokenizer compatibility. ESMC uses rotary embeddings,
so this does not allocate learned position embeddings.
|
2048
|
initializer_range
|
float
|
Standard deviation of the initializer for weight matrices.
|
0.02
|
layer_norm_eps
|
float
|
Epsilon used by layer normalization.
|
1e-05
|
attention_bias
|
bool
|
Whether to use bias terms in attention projection layers.
|
False
|
feedforward_bias
|
bool
|
Whether to use bias terms in feed-forward projection layers.
|
False
|
attention_layer_norm_bias
|
bool
|
Whether to use a bias in the pre-attention layer normalization.
|
True
|
qk_layer_norm
|
bool
|
Whether to apply layer normalization to query and key projections before rotary embeddings.
|
True
|
qk_layer_norm_bias
|
bool
|
Whether to use a bias in query/key layer normalization.
|
False
|
final_layer_norm_bias
|
bool
|
Whether to use a bias in the final encoder layer normalization.
|
False
|
residue_scaling_factor
|
float | None
|
Residual branch divisor used by ESMC. If None, defaults to sqrt(num_hidden_layers / 36).
|
None
|
head
|
HeadConfig | None
|
The configuration of the downstream prediction heads.
|
None
|
lm_head
|
MaskedLMHeadConfig | None
|
The configuration of the masked language model head.
|
None
|
Source code in multimolecule/models/esmc/configuration_esmc.py
| Python |
|---|
| class EsmCConfig(PreTrainedConfig):
r"""
This is the configuration class to store the configuration of an
[`EsmCModel`][multimolecule.models.EsmCModel]. It is used to instantiate an ESMC model according to the specified
arguments, defining the model architecture. Instantiating a configuration with the defaults will yield a similar
configuration to Biohub's [biohub/ESMC-300M](https://huggingface.co/biohub/ESMC-300M) architecture after conversion
to the MultiMolecule protein vocabulary.
Args:
vocab_size:
Vocabulary size of the ESMC model. MultiMolecule checkpoints use the standard
[`ProteinTokenizer`][multimolecule.ProteinTokenizer] vocabulary.
hidden_size:
Dimensionality of the encoder layers.
num_hidden_layers:
Number of hidden layers in the Transformer encoder.
num_attention_heads:
Number of attention heads for each attention layer.
intermediate_size:
Dimensionality of the SwiGLU hidden projection after splitting the packed upstream projection. If `None`,
it is computed from `hidden_size` using ESMC's `8 / 3` expansion rounded up to a multiple of 256.
hidden_act:
The non-linear activation function used in the feed-forward layer. ESMC uses `"swiglu"`.
hidden_dropout:
Dropout probability applied to residual branches.
attention_dropout:
Dropout probability applied to attention probabilities.
max_position_embeddings:
Maximum sequence length used for documentation and tokenizer compatibility. ESMC uses rotary embeddings,
so this does not allocate learned position embeddings.
initializer_range:
Standard deviation of the initializer for weight matrices.
layer_norm_eps:
Epsilon used by layer normalization.
attention_bias:
Whether to use bias terms in attention projection layers.
feedforward_bias:
Whether to use bias terms in feed-forward projection layers.
attention_layer_norm_bias:
Whether to use a bias in the pre-attention layer normalization.
qk_layer_norm:
Whether to apply layer normalization to query and key projections before rotary embeddings.
qk_layer_norm_bias:
Whether to use a bias in query/key layer normalization.
final_layer_norm_bias:
Whether to use a bias in the final encoder layer normalization.
residue_scaling_factor:
Residual branch divisor used by ESMC. If `None`, defaults to `sqrt(num_hidden_layers / 36)`.
head:
The configuration of the downstream prediction heads.
lm_head:
The configuration of the masked language model head.
"""
model_type = "esmc"
def __init__(
self,
vocab_size: int = 37,
hidden_size: int | None = None,
num_hidden_layers: int | None = None,
num_attention_heads: int | None = None,
intermediate_size: int | None = None,
hidden_act: str = "swiglu",
hidden_dropout: float = 0.0,
attention_dropout: float = 0.0,
max_position_embeddings: int = 2048,
initializer_range: float = 0.02,
layer_norm_eps: float = 1.0e-5,
attention_bias: bool = False,
feedforward_bias: bool = False,
attention_layer_norm_bias: bool = True,
qk_layer_norm: bool = True,
qk_layer_norm_bias: bool = False,
final_layer_norm_bias: bool = False,
residue_scaling_factor: float | None = None,
pad_token_id: int = 0,
bos_token_id: int = 1,
eos_token_id: int = 2,
unk_token_id: int = 3,
mask_token_id: int = 4,
null_token_id: int = 5,
head: HeadConfig | None = None,
lm_head: MaskedLMHeadConfig | None = None,
**kwargs,
):
hidden_size = int(kwargs.pop("d_model", 960) if hidden_size is None else hidden_size)
num_hidden_layers = int(kwargs.pop("n_layers", 30) if num_hidden_layers is None else num_hidden_layers)
num_attention_heads = int(kwargs.pop("n_heads", 15) if num_attention_heads is None else num_attention_heads)
intermediate_size = (
_swiglu_intermediate_size(hidden_size) if intermediate_size is None else int(intermediate_size)
)
residue_scaling_factor = (
math.sqrt(num_hidden_layers / 36) if residue_scaling_factor is None else residue_scaling_factor
)
# ESMC stores the token embedding and MLM decoder as independent parameters.
kwargs.setdefault("tie_word_embeddings", False)
super().__init__(
pad_token_id=pad_token_id,
bos_token_id=bos_token_id,
eos_token_id=eos_token_id,
unk_token_id=unk_token_id,
mask_token_id=mask_token_id,
null_token_id=null_token_id,
**kwargs,
)
validate_attention_dimensions(hidden_size, num_attention_heads)
if (hidden_size // num_attention_heads) % 2 != 0:
raise ValueError(
"Rotary embeddings require an even head dimension; got "
f"hidden_size={hidden_size}, num_attention_heads={num_attention_heads}."
)
hidden_act = hidden_act.lower()
if hidden_act != "swiglu":
raise ValueError(f"ESMC only supports hidden_act='swiglu'; got {hidden_act!r}.")
self.vocab_size = vocab_size
self.hidden_size = hidden_size
self.num_hidden_layers = num_hidden_layers
self.num_attention_heads = num_attention_heads
self.intermediate_size = intermediate_size
self.hidden_act = hidden_act
self.hidden_dropout = hidden_dropout
self.attention_dropout = attention_dropout
self.max_position_embeddings = max_position_embeddings
self.initializer_range = initializer_range
self.layer_norm_eps = layer_norm_eps
self.attention_bias = attention_bias
self.feedforward_bias = feedforward_bias
self.attention_layer_norm_bias = attention_layer_norm_bias
self.qk_layer_norm = qk_layer_norm
self.qk_layer_norm_bias = qk_layer_norm_bias
self.final_layer_norm_bias = final_layer_norm_bias
self.residue_scaling_factor = residue_scaling_factor
self.head = HeadConfig(**head) if head is not None else None
self.lm_head = (
MaskedLMHeadConfig(**lm_head)
if lm_head is not None
else MaskedLMHeadConfig(
transform="nonlinear",
transform_act="gelu",
bias=True,
layer_norm_eps=layer_norm_eps,
)
)
|
Bases: EsmCPreTrainedModel
Examples:
| Python Console Session |
|---|
| >>> import torch
>>> from multimolecule import EsmCConfig, EsmCForContactPrediction, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCForContactPrediction(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input, labels=torch.randint(2, (1, 9, 9)))
>>> output["logits"].shape
torch.Size([1, 9, 9, 1])
>>> output["loss"]
tensor(..., grad_fn=<BinaryCrossEntropyWithLogitsBackward0>)
|
Source code in multimolecule/models/esmc/modeling_esmc.py
| Python |
|---|
| class EsmCForContactPrediction(EsmCPreTrainedModel):
"""
Examples:
>>> import torch
>>> from multimolecule import EsmCConfig, EsmCForContactPrediction, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCForContactPrediction(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input, labels=torch.randint(2, (1, 9, 9)))
>>> output["logits"].shape
torch.Size([1, 9, 9, 1])
>>> output["loss"] # doctest:+ELLIPSIS
tensor(..., grad_fn=<BinaryCrossEntropyWithLogitsBackward0>)
"""
def __init__(self, config: EsmCConfig):
super().__init__(config)
self.model = EsmCModel(config, add_pooling_layer=False)
self.contact_head = ContactPredictionHead(config)
self.head_config = self.contact_head.config
self.require_attentions = self.contact_head.require_attentions
# Initialize weights and apply final processing
self.post_init()
@can_return_tuple
def forward(
self,
input_ids: Tensor | NestedTensor | None = None,
attention_mask: Tensor | None = None,
inputs_embeds: Tensor | NestedTensor | None = None,
labels: Tensor | None = None,
**kwargs: Unpack[TransformersKwargs],
) -> tuple[Tensor, ...] | ContactPredictorOutput:
if self.require_attentions:
output_attentions = kwargs.get("output_attentions", self.config.output_attentions)
if output_attentions is False:
warn("output_attentions must be True since prediction head requires attentions.")
kwargs["output_attentions"] = True
outputs = self.model(
input_ids,
attention_mask=attention_mask,
inputs_embeds=inputs_embeds,
return_dict=True,
**kwargs,
)
output = self.contact_head(outputs, attention_mask, input_ids, labels)
logits, loss = output.logits, output.loss
return ContactPredictorOutput(
loss=loss,
logits=logits,
hidden_states=outputs.hidden_states,
attentions=outputs.attentions,
)
|
Bases: EsmCPreTrainedModel
Examples:
| Python Console Session |
|---|
| >>> import torch
>>> from multimolecule import EsmCConfig, EsmCForMaskedLM, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCForMaskedLM(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input, labels=input["input_ids"])
>>> output["logits"].shape
torch.Size([1, 11, 37])
>>> output["loss"]
tensor(..., grad_fn=<NllLossBackward0>)
|
Source code in multimolecule/models/esmc/modeling_esmc.py
| Python |
|---|
| class EsmCForMaskedLM(EsmCPreTrainedModel):
"""
Examples:
>>> import torch
>>> from multimolecule import EsmCConfig, EsmCForMaskedLM, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCForMaskedLM(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input, labels=input["input_ids"])
>>> output["logits"].shape
torch.Size([1, 11, 37])
>>> output["loss"] # doctest:+ELLIPSIS
tensor(..., grad_fn=<NllLossBackward0>)
"""
# ESMC does not tie input and output embeddings. Only the decoder bias alias
# follows the Transformers convention used by ``MaskedLMHead``.
_tied_weights_keys = {
"lm_head.decoder.bias": "lm_head.bias",
}
def __init__(self, config: EsmCConfig):
super().__init__(config)
self.model = EsmCModel(config, add_pooling_layer=False)
self.lm_head = MaskedLMHead(config)
# Initialize weights and apply final processing
self.post_init()
def get_expanded_tied_weights_keys(self, all_submodels: bool = False) -> dict:
tied_weights = super().get_expanded_tied_weights_keys(all_submodels=all_submodels)
if all_submodels:
return tied_weights
return tied_weights | self._tied_weights_keys
def get_output_embeddings(self):
return self.lm_head.decoder
def set_output_embeddings(self, embeddings):
self.lm_head.decoder = embeddings
if hasattr(self.lm_head, "bias"):
self.lm_head.bias = embeddings.bias
@can_return_tuple
def forward(
self,
input_ids: Tensor | NestedTensor | None = None,
attention_mask: Tensor | None = None,
inputs_embeds: Tensor | NestedTensor | None = None,
labels: Tensor | None = None,
**kwargs: Unpack[TransformersKwargs],
) -> tuple[Tensor, ...] | MaskedLMOutput:
outputs = self.model(
input_ids,
attention_mask=attention_mask,
inputs_embeds=inputs_embeds,
return_dict=True,
**kwargs,
)
output = self.lm_head(outputs, labels)
logits, loss = output.logits, output.loss
return MaskedLMOutput(
loss=loss,
logits=logits,
hidden_states=outputs.hidden_states,
attentions=outputs.attentions,
)
|
EsmCForSequencePrediction
Bases: EsmCPreTrainedModel
Examples:
| Python Console Session |
|---|
| >>> import torch
>>> from multimolecule import EsmCConfig, EsmCForSequencePrediction, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCForSequencePrediction(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input, labels=torch.tensor([[1]]))
>>> output["logits"].shape
torch.Size([1, 1])
>>> output["loss"]
tensor(..., grad_fn=<BinaryCrossEntropyWithLogitsBackward0>)
|
Source code in multimolecule/models/esmc/modeling_esmc.py
| Python |
|---|
| class EsmCForSequencePrediction(EsmCPreTrainedModel):
"""
Examples:
>>> import torch
>>> from multimolecule import EsmCConfig, EsmCForSequencePrediction, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCForSequencePrediction(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input, labels=torch.tensor([[1]]))
>>> output["logits"].shape
torch.Size([1, 1])
>>> output["loss"] # doctest:+ELLIPSIS
tensor(..., grad_fn=<BinaryCrossEntropyWithLogitsBackward0>)
"""
def __init__(self, config: EsmCConfig):
super().__init__(config)
self.model = EsmCModel(config)
self.sequence_head = SequencePredictionHead(config)
self.head_config = self.sequence_head.config
# Initialize weights and apply final processing
self.post_init()
@can_return_tuple
def forward(
self,
input_ids: Tensor | NestedTensor | None = None,
attention_mask: Tensor | None = None,
inputs_embeds: Tensor | NestedTensor | None = None,
labels: Tensor | None = None,
**kwargs: Unpack[TransformersKwargs],
) -> tuple[Tensor, ...] | SequencePredictorOutput:
outputs = self.model(
input_ids,
attention_mask=attention_mask,
inputs_embeds=inputs_embeds,
return_dict=True,
**kwargs,
)
output = self.sequence_head(outputs, labels)
logits, loss = output.logits, output.loss
return SequencePredictorOutput(
loss=loss,
logits=logits,
hidden_states=outputs.hidden_states,
attentions=outputs.attentions,
)
|
EsmCForTokenPrediction
Bases: EsmCPreTrainedModel
Examples:
| Python Console Session |
|---|
| >>> import torch
>>> from multimolecule import EsmCConfig, EsmCForTokenPrediction, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCForTokenPrediction(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input, labels=torch.randint(2, (1, 9)))
>>> output["logits"].shape
torch.Size([1, 9, 1])
>>> output["loss"]
tensor(..., grad_fn=<BinaryCrossEntropyWithLogitsBackward0>)
|
Source code in multimolecule/models/esmc/modeling_esmc.py
| Python |
|---|
| class EsmCForTokenPrediction(EsmCPreTrainedModel):
"""
Examples:
>>> import torch
>>> from multimolecule import EsmCConfig, EsmCForTokenPrediction, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCForTokenPrediction(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input, labels=torch.randint(2, (1, 9)))
>>> output["logits"].shape
torch.Size([1, 9, 1])
>>> output["loss"] # doctest:+ELLIPSIS
tensor(..., grad_fn=<BinaryCrossEntropyWithLogitsBackward0>)
"""
def __init__(self, config: EsmCConfig):
super().__init__(config)
self.model = EsmCModel(config, add_pooling_layer=False)
self.token_head = TokenPredictionHead(config)
self.head_config = self.token_head.config
# Initialize weights and apply final processing
self.post_init()
@can_return_tuple
def forward(
self,
input_ids: Tensor | NestedTensor | None = None,
attention_mask: Tensor | None = None,
inputs_embeds: Tensor | NestedTensor | None = None,
labels: Tensor | None = None,
**kwargs: Unpack[TransformersKwargs],
) -> tuple[Tensor, ...] | TokenPredictorOutput:
outputs = self.model(
input_ids,
attention_mask=attention_mask,
inputs_embeds=inputs_embeds,
return_dict=True,
**kwargs,
)
output = self.token_head(outputs, attention_mask, input_ids, labels)
logits, loss = output.logits, output.loss
return TokenPredictorOutput(
loss=loss,
logits=logits,
hidden_states=outputs.hidden_states,
attentions=outputs.attentions,
)
|
EsmCModel
Bases: EsmCPreTrainedModel
Examples:
| Python Console Session |
|---|
| >>> import torch
>>> from multimolecule import EsmCConfig, EsmCModel, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCModel(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input)
>>> output["last_hidden_state"].shape
torch.Size([1, 11, 60])
>>> output["pooler_output"].shape
torch.Size([1, 60])
|
Source code in multimolecule/models/esmc/modeling_esmc.py
| Python |
|---|
| class EsmCModel(EsmCPreTrainedModel):
"""
Examples:
>>> import torch
>>> from multimolecule import EsmCConfig, EsmCModel, ProteinTokenizer
>>> config = EsmCConfig(hidden_size=60, num_hidden_layers=2, num_attention_heads=3, intermediate_size=128)
>>> model = EsmCModel(config)
>>> tokenizer = ProteinTokenizer.from_pretrained("multimolecule/protein")
>>> input = tokenizer("MVLSPADKT", return_tensors="pt")
>>> output = model(**input)
>>> output["last_hidden_state"].shape
torch.Size([1, 11, 60])
>>> output["pooler_output"].shape
torch.Size([1, 60])
"""
def __init__(self, config: EsmCConfig, add_pooling_layer: bool = True):
super().__init__(config)
self.pad_token_id = config.pad_token_id
self.gradient_checkpointing = False
self.embeddings = EsmCEmbeddings(config)
self.encoder = EsmCEncoder(config)
self.pooler = EsmCPooler(config) if add_pooling_layer else None
# Initialize weights and apply final processing
self.post_init()
def get_input_embeddings(self):
return self.embeddings.word_embeddings
def set_input_embeddings(self, value):
self.embeddings.word_embeddings = value
@merge_with_config_defaults
@capture_outputs(tie_last_hidden_states=False)
def forward(
self,
input_ids: Tensor | NestedTensor | None = None,
attention_mask: Tensor | None = None,
sequence_id: Tensor | None = None,
inputs_embeds: Tensor | NestedTensor | None = None,
**kwargs: Unpack[TransformersKwargs],
) -> tuple[Tensor, ...] | BaseModelOutputWithPoolingAndCrossAttentions:
if (input_ids is None) ^ (inputs_embeds is not None):
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
if (
attention_mask is None
and input_ids is not None
and not isinstance(input_ids, NestedTensor)
and self.pad_token_id is not None
):
attention_mask = input_ids.ne(self.pad_token_id)
embedding_output = self.embeddings(input_ids=input_ids, inputs_embeds=inputs_embeds)
if sequence_id is not None:
attn_mask = (sequence_id.unsqueeze(-1) == sequence_id.unsqueeze(-2)).unsqueeze(1)
elif isinstance(embedding_output, NestedTensor) and attention_mask is None:
attn_mask = None
else:
attn_mask = create_bidirectional_mask(
config=self.config,
inputs_embeds=embedding_output,
attention_mask=attention_mask,
)
encoder_outputs = self.encoder(embedding_output, attention_mask=attn_mask, **kwargs)
sequence_output = encoder_outputs.last_hidden_state
pooled_output = self.pooler(sequence_output) if self.pooler is not None else None
return BaseModelOutputWithPoolingAndCrossAttentions(
last_hidden_state=sequence_output,
pooler_output=pooled_output,
hidden_states=encoder_outputs.hidden_states,
attentions=encoder_outputs.attentions,
)
|
EsmCPreTrainedModel
Bases: PreTrainedModel
An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
models.
Source code in multimolecule/models/esmc/modeling_esmc.py
| Python |
|---|
| class EsmCPreTrainedModel(PreTrainedModel):
"""
An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
models.
"""
config_class = EsmCConfig
base_model_prefix = "model"
supports_gradient_checkpointing = True
_supports_flash_attn = True
_supports_sdpa = True
_supports_flex_attn = True
_supports_attention_backend = True
_can_record_outputs: dict[str, Any] | None = None
_no_split_modules = ["EsmCLayer"]
|