TRF053

No manual label shifting in modeling code; self.loss_function owns it.

   
Default Enabled
Scope All models
Source mlinter/trf053.py
Show in terminal mlinter --rule TRF053

What it does

Checks modeling_*.py and modular_*.py for assignments that build shift_logits/shift_labels (and shifted_ variants) by slicing, as in labels[…, 1:]. Receiving already-shifted labels (shift_labels = kwargs.pop(“shift_labels”, labels)) is the correct idiom and is not flagged.

Why is this bad?

self.loss_function shifts labels itself, so modeling code that pre-shifts trains on doubly-shifted targets or forces a bespoke loss path. Decoder-only models pass the raw labels and let the loss shift them. Encoder-decoder models are the mirror case: their labels are already shifted because the decoder input gets the decoder start token prepended, so they must pass shift_labels=labels to stop the loss from shifting again. Double-shift is the recurring training-loss bug (Git/Florence2/Moonshine family).

Example

 if labels is not None:
-    shift_logits = logits[..., :-1, :].contiguous()
-    shift_labels = labels[..., 1:].contiguous()
-    loss = nn.functional.cross_entropy(shift_logits.view(-1, self.config.vocab_size), shift_labels.view(-1))
+    # decoder-only: labels are unshifted, the loss shifts them
+    loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size)
+    # encoder-decoder: labels are already shifted, hand them over as shift_labels
+    loss = self.loss_function(logits=logits, labels=labels, shift_labels=labels, vocab_size=self.config.vocab_size)

Suppressing this rule

Add a # trf-ignore: TRF053 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

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

Show the 15 allowlisted models
  • blip_2
  • clvp
  • csm
  • gemma3
  • git
  • gpt2
  • granite_speech
  • imagegpt
  • llama4
  • mamba
  • modernbert_decoder
  • moshi
  • openai
  • qwen2_audio
  • xlstm