OneScience's picture
Upload folder using huggingface_hub
35cdf53 verified
Raw
History Blame Contribute Delete
1.99 kB
"""Utility functions for training AlphaFold and similar models."""
from collections import abc
import contextlib
import numbers
from flax_model.alphafold3.model import features
import haiku as hk
import jax.numpy as jnp
import numpy as np
VALID_DTYPES = [np.float32, np.float64, np.int8, np.int32, np.int64, bool]
def remove_invalidly_typed_feats(
batch: features.BatchDict,
) -> features.BatchDict:
"""Remove features of types we don't want to send to the TPU e.g. strings."""
return {
k: v
for k, v in batch.items()
if hasattr(v, 'dtype') and v.dtype in VALID_DTYPES
}
def bfloat16_getter(next_getter, value, context):
"""Ensures that a bfloat16 parameter is provided by casting if necessary."""
if context.original_dtype == jnp.bfloat16:
if value.dtype != jnp.bfloat16:
value = value.astype(jnp.bfloat16)
return next_getter(value)
@contextlib.contextmanager
def bfloat16_context():
with hk.custom_getter(bfloat16_getter):
yield
def mask_mean(mask, value, axis=None, keepdims=False, eps=1e-10):
"""Masked mean."""
mask_shape = mask.shape
value_shape = value.shape
assert len(mask_shape) == len(
value_shape
), 'Shapes are not compatible, shapes: {}, {}'.format(mask_shape, value_shape)
if isinstance(axis, numbers.Integral):
axis = [axis]
elif axis is None:
axis = list(range(len(mask_shape)))
assert isinstance(
axis, abc.Iterable
), 'axis needs to be either an iterable, integer or "None"'
broadcast_factor = 1.0
for axis_ in axis:
value_size = value_shape[axis_]
mask_size = mask_shape[axis_]
if mask_size == 1:
broadcast_factor *= value_size
else:
error = f'Shapes are not compatible, shapes: {mask_shape}, {value_shape}'
assert mask_size == value_size, error
return jnp.sum(mask * value, keepdims=keepdims, axis=axis) / (
jnp.maximum(
jnp.sum(mask, keepdims=keepdims, axis=axis) * broadcast_factor, eps
)
)