PaddlePaddle/PaddleOCR · error · NotImplementedError

Sliding window is currently only implemented for causal mask

Error message

Sliding window is currently only implemented for causal masking

What it means

Sliding-window masking in the PP-FormulaNet head is only implemented inside the causal-mask code path. If the converter was built with a sliding_window but is_causal=False, the causal branch is skipped and the elif raises NotImplementedError.

Source

Thrown at ppocr/modeling/heads/rec_ppformulanet_head.py:219

                causal_4d_mask = self._make_causal_mask_parallel(
                    input_shape,
                    dtype,
                    past_key_values_length=past_key_values_length,
                    sliding_window=self.sliding_window,
                    parallel_step=parallel_step,
                    is_export=is_export,
                )
            else:
                causal_4d_mask = self._make_causal_mask(
                    input_shape,
                    dtype,
                    past_key_values_length=past_key_values_length,
                    sliding_window=self.sliding_window,
                    is_export=is_export,
                )

        elif self.sliding_window is not None:
            raise NotImplementedError(
                "Sliding window is currently only implemented for causal masking"
            )

        expanded_attn_mask = self._expand_mask(
            attention_mask_2d, dtype, tgt_len=input_shape[-1]
        )

        if causal_4d_mask is not None:
            expanded_attn_mask = causal_4d_mask.masked_fill_(
                expanded_attn_mask.cast(paddle.bool), paddle.finfo(dtype).min
            )

        expanded_4d_mask = expanded_attn_mask
        return expanded_4d_mask

    def to_4d_export(
        self,
        attention_mask_2d,

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Remove sliding_window (set to null) if you want non-causal attention
  2. Keep sliding_window but set is_causal: true so the causal masking path (which implements windowing) runs
  3. If bidirectional windowed attention is truly needed, implement a non-causal windowed mask in _make_causal_mask-style helper and extend the elif branch

Example fix

# before (config yml)
Head:
  is_causal: false
  sliding_window: 512
# after
Head:
  is_causal: false
  sliding_window: null
Defensive patterns

Strategy: validation

Validate before calling

def check_mask_config(is_causal, sliding_window):
    if sliding_window is not None and not is_causal:
        raise ValueError('sliding_window requires is_causal=True in this head; set sliding_window to null for non-causal attention')
    return is_causal, sliding_window

Type guard

def window_compatible(cfg) -> bool:
    sw = cfg.get('sliding_window')
    return sw is None or bool(cfg.get('is_causal'))

Try / catch

null  # configuration error; fail fast rather than catching

Prevention

When it happens

Trigger: Building the model with a positive sliding_window value while the mask converter is configured with is_causal=False (bidirectional/full attention), then running any forward pass that converts the 2D mask to 4D.

Common situations: Copying an encoder config (non-causal) but keeping the decoder's sliding_window key; experimenting with bidirectional attention for a formula model and leaving sliding_window set; merging configs from PP-FormulaNet variants where only the decoder is causal.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/8b1df58613a50e9d. Report an issue: GitHub.