TRF049

Weight initialization belongs in _init_weights, never in __init__ (meta-device init discards it).

   
Default Enabled
Scope All models
Source mlinter/trf049.py
Show in terminal mlinter --rule TRF049

What it does

Checks __init__ methods in modeling_*.py and modular_*.py for init calls: nn.init.* / init.* primitives and in-place initializers on own parameters (self.weight.data.normal_()).

Why is this bad?

Models instantiate on the meta device, so tensor values written in __init__ are discarded before loading; a parameter initialized only there has random content when fine-tuning from scratch or after a meta-device reload. Allocate with torch.empty in __init__ and initialize in _init_weights.

Example

 class AcmeEmbeddings(nn.Module):
     def __init__(self, config):
         super().__init__()
         self.position_embedding = nn.Parameter(torch.empty(config.num_positions, config.hidden_size))
-        nn.init.trunc_normal_(self.position_embedding, std=config.initializer_range)

 class AcmePreTrainedModel(PreTrainedModel):
     def _init_weights(self, module):
         super()._init_weights(module)
+        if isinstance(module, AcmeEmbeddings):
+            init.trunc_normal_(module.position_embedding, std=self.config.initializer_range)

Suppressing this rule

Add a # trf-ignore: TRF049 comment on the flagged line or the line directly above it. See Suppressing rules for whole-file directives and when a suppression is the wrong answer.

Allowlisted models

5 models are exempt from TRF049 in mlinter/rules.toml, because they predate the convention and cannot be changed without breaking backward compatibility.

Show the 5 allowlisted models
  • convbert
  • emu3
  • esm
  • granite_speech
  • unispeech_sat