Lolalb commited on
Commit
5680a3d
·
verified ·
1 Parent(s): c5029cc

Fix freqs_cis being left uninitialized when loaded via meta-device init

Browse files
Files changed (1) hide show
  1. amplify.py +17 -6
amplify.py CHANGED
@@ -206,14 +206,24 @@ class AMPLIFY(AMPLIFYPreTrainedModel):
206
 
207
  self.decoder = nn.Linear(config.hidden_size, config.vocab_size)
208
 
209
- freqs_cis = precompute_freqs_cis(config.hidden_size // config.num_attention_heads, config.max_protein_length * 2)
210
-
211
- # Ensures freqs_cis is moved to the same devices as the model. Non-persistent buffers are not saved in the state_dict.
212
- self.register_buffer("freqs_cis", freqs_cis, persistent=False)
 
213
 
214
  # Initialize weights and apply final processing
215
  self.post_init()
216
 
 
 
 
 
 
 
 
 
 
217
  @classmethod
218
  def load(cls, checkpoint_path: str, config_path: str, vocab_path: str = None, tag: str = None):
219
 
@@ -277,10 +287,11 @@ class AMPLIFY(AMPLIFYPreTrainedModel):
277
  assert input_ids.is_cuda, "Packing uses an implementation of flash-attention and is only supported on GPU."
278
 
279
  # RoPE
 
280
  if position_ids is not None:
281
- freqs_cis = self.freqs_cis[position_ids]
282
  else:
283
- freqs_cis = self.freqs_cis[: input_ids.shape[1]].unsqueeze(0).repeat(input_ids.shape[0], 1, 1)
284
 
285
  # Embedding
286
  x = self.encoder(input_ids)
 
206
 
207
  self.decoder = nn.Linear(config.hidden_size, config.vocab_size)
208
 
209
+ # freqs_cis is derived from the config, not learned, so it is not saved in the state_dict. It is built lazily on
210
+ # first use rather than here: `from_pretrained` may construct the model on the meta device and then materialize
211
+ # it with uninitialized memory, filling in only the tensors present in the checkpoint. A buffer populated in
212
+ # __init__ would be left as garbage by that path, so it is registered as None and computed in forward().
213
+ self.register_buffer("freqs_cis", None, persistent=False)
214
 
215
  # Initialize weights and apply final processing
216
  self.post_init()
217
 
218
+ def _ensure_freqs_cis(self, device: torch.device) -> torch.Tensor:
219
+ """Build the rotary embedding table on first use, then reuse it."""
220
+ if self.freqs_cis is None or self.freqs_cis.device != device:
221
+ self.freqs_cis = precompute_freqs_cis(
222
+ self.config.hidden_size // self.config.num_attention_heads,
223
+ self.config.max_protein_length * 2,
224
+ ).to(device)
225
+ return self.freqs_cis
226
+
227
  @classmethod
228
  def load(cls, checkpoint_path: str, config_path: str, vocab_path: str = None, tag: str = None):
229
 
 
287
  assert input_ids.is_cuda, "Packing uses an implementation of flash-attention and is only supported on GPU."
288
 
289
  # RoPE
290
+ freqs_cis_table = self._ensure_freqs_cis(input_ids.device)
291
  if position_ids is not None:
292
+ freqs_cis = freqs_cis_table[position_ids]
293
  else:
294
+ freqs_cis = freqs_cis_table[: input_ids.shape[1]].unsqueeze(0).repeat(input_ids.shape[0], 1, 1)
295
 
296
  # Embedding
297
  x = self.encoder(input_ids)