DiffDock / models /score_wrapper.py
OneScience's picture
Upload folder using huggingface_hub
c2767f4 verified
Raw
History Blame Contribute Delete
7.99 kB
from argparse import Namespace
from functools import partial
from pathlib import Path
import torch
import yaml
from torch_geometric.nn.data_parallel import DataParallel
from onescience.utils.diffdock.diffusion_utils import get_timestep_embedding, t_to_sigma as t_to_sigma_compl
from onescience.utils.diffdock.utils import ExponentialMovingAverage
from .aa_model import AAModel
from .cg_model import CGModel
from .old_aa_model import AAOldModel
_LM_EMBEDDING_KEYS = (
"moad_esm_embeddings_path",
"pdbbind_esm_embeddings_path",
"pdbsidechain_esm_embeddings_path",
"esm_embeddings_path",
"esm_embeddings_model",
)
def load_model_args(model_dir):
model_dir = Path(model_dir)
config_path = model_dir / "model_parameters.yml"
with config_path.open("r", encoding="utf-8") as handle:
config = yaml.full_load(handle) or {}
return Namespace(**config)
def model_uses_lm_embeddings(model_args):
return any(getattr(model_args, key, None) is not None for key in _LM_EMBEDDING_KEYS)
def _has_arg(args, name):
try:
return name in args
except TypeError:
return hasattr(args, name)
def _get_arg(args, name, default=None):
if isinstance(args, dict):
return args.get(name, default)
if _has_arg(args, name):
return getattr(args, name)
return default
def get_model(args, device, t_to_sigma, no_parallel=False, confidence_mode=False, old=False):
timestep_emb_func = get_timestep_embedding(
embedding_type=_get_arg(args, "embedding_type", "sinusoidal"),
embedding_dim=args.sigma_embed_dim,
embedding_scale=_get_arg(args, "embedding_scale", 10000),
)
all_atoms = _get_arg(args, "all_atoms", False)
if old and not all_atoms:
raise NotImplementedError(
"The old coarse-grained DiffDock model path is not migrated yet. "
"Use old=True only with all_atoms=True, or migrate old_cg_model.py first."
)
lm_embedding_type = None
if (
_get_arg(args, "moad_esm_embeddings_path") is not None
or _get_arg(args, "pdbbind_esm_embeddings_path") is not None
or _get_arg(args, "pdbsidechain_esm_embeddings_path") is not None
or _get_arg(args, "esm_embeddings_path") is not None
):
lm_embedding_type = "precomputed"
if _get_arg(args, "esm_embeddings_model") is not None:
lm_embedding_type = args.esm_embeddings_model
if old:
model_class = AAOldModel
elif all_atoms:
model_class = AAModel
else:
model_class = CGModel
model_kwargs = dict(
t_to_sigma=t_to_sigma,
device=device,
no_torsion=args.no_torsion,
timestep_emb_func=timestep_emb_func,
num_conv_layers=args.num_conv_layers,
lig_max_radius=args.max_radius,
scale_by_sigma=args.scale_by_sigma,
sigma_embed_dim=args.sigma_embed_dim,
norm_by_sigma=_get_arg(args, "norm_by_sigma", False),
ns=args.ns,
nv=args.nv,
distance_embed_dim=args.distance_embed_dim,
cross_distance_embed_dim=args.cross_distance_embed_dim,
batch_norm=not args.no_batch_norm,
dropout=args.dropout,
use_second_order_repr=args.use_second_order_repr,
cross_max_distance=args.cross_max_distance,
dynamic_max_cross=args.dynamic_max_cross,
smooth_edges=_get_arg(args, "smooth_edges", False),
odd_parity=_get_arg(args, "odd_parity", False),
lm_embedding_type=lm_embedding_type,
confidence_mode=confidence_mode,
confidence_dropout=_get_arg(args, "confidence_dropout", 0.0),
confidence_no_batchnorm=_get_arg(args, "confidence_no_batchnorm", False),
affinity_prediction=_get_arg(args, "affinity_prediction", False),
parallel=_get_arg(args, "parallel", 1),
num_confidence_outputs=(
len(args.rmsd_classification_cutoff) + 1
if isinstance(_get_arg(args, "rmsd_classification_cutoff"), list)
else 1
),
atom_num_confidence_outputs=(
len(args.atom_rmsd_classification_cutoff) + 1
if isinstance(_get_arg(args, "atom_rmsd_classification_cutoff"), list)
else 1
),
parallel_aggregators=_get_arg(args, "parallel_aggregators", ""),
fixed_center_conv=not _get_arg(args, "not_fixed_center_conv", False),
no_aminoacid_identities=_get_arg(args, "no_aminoacid_identities", False),
include_miscellaneous_atoms=_get_arg(args, "include_miscellaneous_atoms", False),
sh_lmax=_get_arg(args, "sh_lmax", 2),
differentiate_convolutions=not _get_arg(args, "no_differentiate_convolutions", False),
tp_weights_layers=_get_arg(args, "tp_weights_layers", 2),
num_prot_emb_layers=_get_arg(args, "num_prot_emb_layers", 0),
reduce_pseudoscalars=_get_arg(args, "reduce_pseudoscalars", False),
embed_also_ligand=_get_arg(args, "embed_also_ligand", False),
atom_confidence=_get_arg(args, "atom_confidence_loss_weight", 0.0) > 0.0,
sidechain_pred=(
(_has_arg(args, "sidechain_loss_weight") and args.sidechain_loss_weight > 0)
or (_has_arg(args, "backbone_loss_weight") and args.backbone_loss_weight > 0)
),
depthwise_convolution=_get_arg(args, "depthwise_convolution", False),
)
if model_class is AAModel:
model_kwargs["crop_beyond"] = _get_arg(args, "crop_beyond", None)
elif model_class is AAOldModel:
for key in (
"atom_num_confidence_outputs",
"differentiate_convolutions",
"tp_weights_layers",
"num_prot_emb_layers",
"reduce_pseudoscalars",
"embed_also_ligand",
"atom_confidence",
"sidechain_pred",
"depthwise_convolution",
):
model_kwargs.pop(key, None)
model_kwargs["lm_embedding_type"] = (
"esm" if _get_arg(args, "esm_embeddings_path") is not None else None
)
model_kwargs["use_old_atom_encoder"] = _get_arg(args, "use_old_atom_encoder", True)
model = model_class(**model_kwargs)
if device.type == "cuda" and not no_parallel and _get_arg(args, "dataset") != "torsional":
model = DataParallel(model)
model.to(device)
return model
def build_score_model(
model_args,
device,
no_parallel=False,
confidence_mode=False,
old=False,
):
t_to_sigma = partial(t_to_sigma_compl, args=model_args)
model = get_model(
model_args,
device,
t_to_sigma=t_to_sigma,
no_parallel=no_parallel,
confidence_mode=confidence_mode,
old=old,
)
return model, t_to_sigma
def load_score_model(
model_dir,
ckpt,
device=None,
no_parallel=True,
confidence_mode=False,
old=False,
strict=True,
):
if device is None:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model_args = load_model_args(model_dir)
model, t_to_sigma = build_score_model(
model_args=model_args,
device=device,
no_parallel=no_parallel,
confidence_mode=confidence_mode,
old=old,
)
checkpoint_path = Path(model_dir) / ckpt
state_dict = torch.load(checkpoint_path, map_location=torch.device("cpu"))
if isinstance(state_dict, dict) and "model" in state_dict and "optimizer" in state_dict:
model.load_state_dict(state_dict["model"], strict=strict)
if "ema_weights" in state_dict and getattr(model_args, "ema_rate", None) is not None:
ema_weights = ExponentialMovingAverage(model.parameters(), decay=model_args.ema_rate)
ema_weights.load_state_dict(state_dict["ema_weights"], device=device)
ema_weights.copy_to(model.parameters())
else:
model.load_state_dict(state_dict, strict=strict)
model = model.to(device)
model.eval()
return model, model_args, t_to_sigma