Skip to content

Make ModernBERT consume the validated shared attention layout and mask path #142

Description

@forkwright

Finding

The transformer crate implements head transposition, head merging, and attention-mask validation twice. The general Qwen/GQA path owns checked, Result-returning helpers and rejects a mask whose length differs from the sequence. The ModernBERT path carries a comment that its private helpers are “same as in attention.rs,” but its copies silently leave zero-filled output when a source range is missing and treat missing mask entries as padding.

One transformer representation therefore has two implementations with different failure semantics.

Verified against main e43777cd7f86674197d94e33533147dddfac4c82.

Evidence

Why this matters

Shape and mask disagreements are model-integrity failures. Silent zero filling or implicit padding produces numerically valid tensors over the wrong inputs, which is more difficult to detect than a load/shape error. It can make the ModernBERT CPU path disagree with the shared transformer path while both appear successful, undermining its role as a correctness reference for later GPU work.

The copies also make every safety repair non-transitive. Tightening the checked helper or mask contract in attention.rs does not protect ModernBERT, as the current divergence already demonstrates.

Desired correction

Give the transformer crate one internal owner for:

  • [seq, heads, d] ↔ [heads, seq, d] materialization;
  • exact input/output length validation; and
  • sequence-mask length validation.

Have both Qwen/GQA and ModernBERT consume that owner. Keep ModernBERT-specific local-window/global-attention masking as the legitimate delta, but require a validated [seq] mask before applying it.

Replace unwrap_or_default and optional-copy fallthrough in the forward path with typed Error::Shape propagation.

Done when:

  • only one production implementation transposes and merges transformer heads;
  • both attention families reject malformed tensor and mask lengths through the same error contract;
  • ModernBERT cannot return Ok with zero-filled rows caused by missing slices;
  • local/global-window policy remains explicit and separately tested; and
  • adversarial fixtures prove a short mask and a malformed QKV/layout buffer fail loudly in both paths.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions