Skip to content

Commit c4dcce4

Browse files
authored
Merge pull request #395 from bigict/amp
refactor: disable autocast for headers
2 parents 39efa1c + 639ce5c commit c4dcce4

4 files changed

Lines changed: 70 additions & 49 deletions

File tree

profold2/model/alphafold2.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from einops import rearrange
1414

1515
from profold2.common import residue_constants
16-
from profold2.model import commons, folding, functional
16+
from profold2.model import accelerator, commons, folding, functional
1717
from profold2.model.evoformer import Evoformer
1818
from profold2.model.head import HeaderBuilder
1919
from profold2.utils import env, exists, status
@@ -282,27 +282,29 @@ def forward(
282282
representations.update(msa=m, pair=x, single=s, frames=t, single_init=s)
283283

284284
ret.headers = {}
285-
for name, module, options in self.headers:
286-
value = module(ret.headers, representations, batch)
287-
if not exists(value):
288-
continue
289-
ret.headers[name] = value
290-
if 'representations' in value:
291-
representations.update(value['representations'])
292-
if 'folding' in ret.headers:
293-
batch = folding.multi_chain_permutation_alignment(ret.headers['folding'], batch)
294-
if self.training and compute_loss:
285+
with accelerator.autocast(enabled=False):
286+
representations = functional.to(representations, dtype=torch.float)
295287
for name, module, options in self.headers:
296-
if not hasattr(module, 'loss') or name not in ret.headers:
288+
value = module(ret.headers, representations, batch)
289+
if not exists(value):
297290
continue
298-
loss = module.loss(ret.headers[name], batch)
299-
if exists(loss):
300-
ret.headers[name].update(loss)
301-
lossw = loss['loss'] * options.get('weight', 1.0)
302-
if exists(ret.loss):
303-
ret.loss = commons.tensor_add(ret.loss, lossw)
304-
else:
305-
ret.loss = lossw
291+
ret.headers[name] = value
292+
if 'representations' in value:
293+
representations.update(value['representations'])
294+
if 'folding' in ret.headers:
295+
batch = folding.multi_chain_permutation_alignment(ret.headers['folding'], batch)
296+
if self.training and compute_loss:
297+
for name, module, options in self.headers:
298+
if not hasattr(module, 'loss') or name not in ret.headers:
299+
continue
300+
loss = module.loss(ret.headers[name], batch)
301+
if exists(loss):
302+
ret.headers[name].update(loss)
303+
lossw = loss['loss'] * options.get('weight', 1.0)
304+
if exists(ret.loss):
305+
ret.loss = commons.tensor_add(ret.loss, lossw)
306+
else:
307+
ret.loss = lossw
306308

307309
if return_recyclables:
308310
msa_first_row_repr, pairwise_repr = m[..., 0, :, :], representations['pair']

profold2/model/folding.py

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -142,36 +142,39 @@ def forward(self, representations, batch):
142142
single_repr_init = single_repr
143143
single_repr = self.single_repr_dim(single_repr)
144144

145-
# prepare float32 precision for equivariance
146-
original_dtype = single_repr.dtype
147-
single_repr, pairwise_repr = map(lambda t: t.float(), (single_repr, pairwise_repr))
145+
# initial frames
146+
if 'frames' in representations and exists(representations['frames']):
147+
quaternions, translations = representations['frames']
148+
else:
149+
quaternions = torch.tensor([1., 0., 0., 0.], device=device)
150+
quaternions = torch.tile(quaternions, b + (n, 1))
151+
translations = torch.zeros(b + (n, 3), device=device)
148152

149153
outputs = []
150154

151155
# iterative refinement with equivariant transformer in high precision
152-
with commons.torch_default_dtype(torch.float32):
153-
# initial frames
154-
if 'frames' in representations and exists(representations['frames']):
155-
quaternions, translations = representations['frames']
156-
else:
157-
quaternions = torch.tensor([1., 0., 0., 0.], device=device)
158-
quaternions = torch.tile(quaternions, b + (n, 1))
159-
translations = torch.zeros(b + (n, 3), device=device)
156+
with accelerator.autocast(enabled=False):
157+
# prepare float32 precision for equivariance
158+
single_repr, pairwise_repr = functional.to(
159+
(single_repr, pairwise_repr), dtype=torch.float
160+
)
161+
quaternions, translations = functional.to(
162+
(quaternions, translations), dtype=torch.float
163+
)
160164
rotations = functional.quaternion_to_matrix(quaternions).detach()
161165

162166
# go through the layers and apply invariant point attention and
163167
# feedforward
164168
for i in range(self.structure_module_depth):
165169
is_last = i == (self.structure_module_depth - 1)
166170

167-
with accelerator.autocast(enabled=False):
168-
single_repr = self.ipa_block(
169-
single_repr.float(),
170-
mask=batch['mask'].bool(),
171-
pairwise_repr=pairwise_repr.float(),
172-
rotations=rotations.float(),
173-
translations=translations.float()
174-
)
171+
single_repr = self.ipa_block(
172+
single_repr,
173+
mask=batch['mask'].bool(),
174+
pairwise_repr=pairwise_repr,
175+
rotations=rotations,
176+
translations=translations
177+
)
175178

176179
# update quaternion and translation
177180
quaternion_update, translation_update = self.to_affine_update(single_repr
@@ -197,7 +200,6 @@ def forward(self, representations, batch):
197200
functional.l2_norm(angles)
198201
)
199202
coords = functional.rigids_to_positions(frames, batch['seq'])
200-
coords.type(original_dtype)
201203
outputs.append(
202204
dict(
203205
frames=functional.rigids_scale(
@@ -212,4 +214,5 @@ def forward(self, representations, batch):
212214

213215

214216
def multi_chain_permutation_alignment(value, batch):
215-
return functional.multi_chain_permutation_alignment(value, batch)
217+
with accelerator.autocast(enabled=False):
218+
return functional.multi_chain_permutation_alignment(value, batch)

profold2/model/functional.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from einops import rearrange, repeat
99

1010
from profold2.common import residue_constants
11-
from profold2.model import accelerator
1211
from profold2.utils import default, exists
1312

1413

@@ -23,6 +22,23 @@ def apc(x, dim=None, epsilon=1e-8):
2322
return x - avg
2423

2524

25+
def to(x, *args, **kwargs):
26+
"""Performs Tensor dtype and/or device conversion. A torch.dtype and torch.device
27+
are inferred from the arguments of to(*args, **kwargs).
28+
See ```torch.Tensor.to```"""
29+
if isinstance(x, dict):
30+
for k, v in x.items():
31+
x[k] = to(v, *args, **kwargs)
32+
elif isinstance(x, list):
33+
for i, v in enumerate(x):
34+
x[i] = to(v, *args, **kwargs)
35+
elif isinstance(x, tuple):
36+
x = tuple(to(v, *args, **kwargs) for v in x)
37+
elif isinstance(x, torch.Tensor):
38+
x = x.to(*args, **kwargs)
39+
return x
40+
41+
2642
def l2_norm(v, dim=-1, epsilon=1e-12):
2743
return v / torch.clamp(
2844
torch.linalg.norm(v, dim=dim, keepdim=True), # pylint: disable=not-callable
@@ -1503,8 +1519,7 @@ def optimal_transform_create(pred_points, true_points, points_mask):
15031519
with torch.no_grad():
15041520
pred_ca = true_ca
15051521

1506-
with accelerator.autocast(enabled=False):
1507-
return kabsch_transform(pred_ca.float(), true_ca.float())
1522+
return kabsch_transform(pred_ca.float(), true_ca.float())
15081523

15091524

15101525
def seq_crop_mask(fgt_seq_index, fgt_seq_color, seq_index, seq_color, seq_anchor):

profold2/model/head.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ def forward(self, headers, representations, batch):
282282
'... m j d,b i j q,q c d,d -> ... m i c', msa, eij, states, self.mask
283283
)
284284
ret.update(wab=states)
285-
# eij = torch.einsum('b i j q,q c d -> b i j c d', eij, states)
285+
# eij = torch.einsum('... i j q,q c d -> ... i j c d', eij, states)
286286
else: # native potts model
287287
eij = rearrange(eij, '... i j (c d) -> ... i j c d', c=num_class, d=num_class)
288288
hi = torch.einsum('... m j d,b i j c d,d -> ... m i c', msa, eij, self.mask)
@@ -687,7 +687,7 @@ def yield_pred_angle_loss(pred_angles_list, true_angles):
687687

688688
assert 'traj' in value
689689
# loss
690-
loss = (fape_loss(value['traj'], batch) + torsion_angle_loss(value['traj'], batch))
690+
loss = fape_loss(value['traj'], batch) + torsion_angle_loss(value['traj'], batch)
691691

692692
return dict(loss=loss)
693693

@@ -1591,9 +1591,10 @@ def forward(self, headers, representations, batch):
15911591
)
15921592
with torch.no_grad():
15931593
# rotate / align
1594-
pred_points, true_points = functional.kabsch_align(
1595-
pred_points, true_points, mask=coord_mask
1596-
)
1594+
with accelerator.autocast(enabled=False):
1595+
pred_points, true_points = functional.kabsch_align(
1596+
pred_points.float(), true_points.float(), mask=coord_mask
1597+
)
15971598
n = torch.sum(batch['mask'], dim=-1, keepdim=True)
15981599
tms = functional.tmscore(pred_points, true_points, n=n)
15991600
tms = torch.where(torch.any(coord_mask, dim=-1), tms, 0)

0 commit comments

Comments
 (0)