Instructions to use Synthyra/ESMFold2-Fast with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Synthyra/ESMFold2-Fast with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="Synthyra/ESMFold2-Fast", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("Synthyra/ESMFold2-Fast", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
| """Predicted-aligned-error scores and training loss.""" | |
| from __future__ import annotations | |
| import torch | |
| import torch.nn.functional as F | |
| from torch import Tensor | |
| from .esmfold2_affine3d import Affine3D | |
| _CPU_DEVICE = torch.device("cpu") | |
| def _compute_pae_masks(mask: Tensor) -> Tensor: | |
| residue_mask = mask.bool() | |
| return residue_mask.unsqueeze(-1) & residue_mask.unsqueeze(-2) | |
| def _pae_bins( | |
| max_bin: float = 31, | |
| num_bins: int = 64, | |
| device: torch.device = _CPU_DEVICE, | |
| ) -> Tensor: | |
| """Return the representative distance for each PAE probability bin.""" | |
| boundaries = torch.linspace(0, max_bin, steps=num_bins - 1, device=device) | |
| width = max_bin / (num_bins - 2) | |
| centers = boundaries + width / 2 | |
| overflow_center = centers[-1:] + width | |
| return torch.cat((centers, overflow_center)) | |
| def _masked_probabilities(logits: Tensor, pair_mask: Tensor) -> Tensor: | |
| masked_logits = logits.masked_fill( | |
| ~pair_mask.unsqueeze(-1), | |
| torch.finfo(logits.dtype).min, | |
| ) | |
| return masked_logits.softmax(dim=-1) | |
| def masked_mean( | |
| mask: Tensor, | |
| value: Tensor, | |
| dim: int | tuple[int, ...] | None = None, | |
| eps: float = 1e-10, | |
| ) -> Tensor: | |
| """Average values over true entries of a broadcast-compatible mask.""" | |
| weights = mask.expand_as(value) | |
| weighted_sum = torch.sum(weights * value, dim=dim) | |
| weight_sum = torch.sum(weights, dim=dim) | |
| return weighted_sum / (weight_sum + eps) | |
| def compute_predicted_aligned_error( | |
| logits: Tensor, | |
| aa_mask: Tensor, | |
| sequence_id: Tensor | None = None, | |
| max_bin: float = 31, | |
| ) -> Tensor: | |
| """Convert PAE logits ``X`` with shape (..., l, l, n) to distances.""" | |
| del sequence_id | |
| pair_mask = _compute_pae_masks(aa_mask) | |
| probabilities = _masked_probabilities(logits, pair_mask) | |
| centers = _pae_bins(max_bin, logits.shape[-1], logits.device) | |
| return torch.sum(probabilities * centers, dim=-1) | |
| def compute_tm(logits: Tensor, aa_mask: Tensor, max_bin: float = 31.0) -> Tensor: | |
| """Estimate TM score from pairwise PAE logits.""" | |
| pair_mask = _compute_pae_masks(aa_mask) | |
| sequence_lengths = aa_mask.sum(dim=-1, keepdim=True) | |
| centers = _pae_bins(max_bin, logits.shape[-1], logits.device) | |
| distance_scale = 1.24 * (sequence_lengths.clamp_min(19) - 15) ** (1 / 3) - 1.8 | |
| tm_weights = 1.0 / (1 + (centers / distance_scale.unsqueeze(-1)) ** 2) | |
| probabilities = _masked_probabilities(logits, pair_mask) | |
| score_per_pair = torch.sum(probabilities * tm_weights.unsqueeze(-2), dim=-1) | |
| score_per_anchor = masked_mean(pair_mask, score_per_pair, dim=-1) | |
| return score_per_anchor.max(dim=-1).values | |
| def _local_coordinates(frames: Affine3D) -> Tensor: | |
| origins = frames.trans[..., None, :, :] | |
| return frames.invert()[..., None].apply(origins) | |
| def tm_loss( | |
| logits: Tensor, | |
| pred_affine: Tensor, | |
| targ_affine: Tensor, | |
| targ_mask: Tensor, | |
| tm_mask: Tensor | None = None, | |
| sequence_id: Tensor | None = None, | |
| max_bin: float = 31, | |
| ) -> Tensor: | |
| """Cross-entropy loss for discretized aligned-position errors.""" | |
| del sequence_id | |
| predicted_frames = Affine3D.from_tensor(pred_affine) | |
| target_frames = Affine3D.from_tensor(targ_affine) | |
| with torch.no_grad(): | |
| squared_error = ( | |
| (_local_coordinates(predicted_frames) - _local_coordinates(target_frames)) | |
| .square() | |
| .sum(dim=-1) | |
| ) | |
| boundaries = torch.linspace( | |
| 0, | |
| max_bin, | |
| logits.shape[-1] - 1, | |
| device=logits.device, | |
| ).square() | |
| target_bins = (squared_error[..., None] > boundaries).sum(dim=-1).long() | |
| cross_entropy = F.cross_entropy( | |
| logits.movedim(3, 1), | |
| target_bins, | |
| reduction="none", | |
| ) | |
| pair_mask = _compute_pae_masks(targ_mask) | |
| loss_per_sample = masked_mean(pair_mask, cross_entropy, dim=(-1, -2)) | |
| if tm_mask is None: | |
| return loss_per_sample.mean() | |
| return masked_mean(tm_mask, loss_per_sample) | |