|
|
|
|
| """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 |
| ) |
| ) |
|
|