PaddlePaddle/PaddleOCR · error · TypeError

The norm_layer must be str or paddle.nn.layer.LayerNorm clas

Error message

The norm_layer must be str or paddle.nn.layer.LayerNorm class

What it means

CPPD head's attention Block requires norm_layer as a str (eval'd into self.norm1 and self.normkv) or a Callable (called as norm_layer(dim)); anything else raises TypeError('The norm_layer must be str or paddle.nn.layer.LayerNorm class'). This first guard covers norm1/normkv; the default is the string 'nn.LayerNorm' with epsilon=1e-6.

Source

Thrown at ppocr/modeling/heads/rec_cppd_head.py:176

        mlp_ratio=4.0,
        qkv_bias=False,
        qk_scale=None,
        drop=0.0,
        attn_drop=0.0,
        drop_path=0.0,
        act_layer=nn.GELU,
        norm_layer="nn.LayerNorm",
        epsilon=1e-6,
    ):
        super().__init__()
        if isinstance(norm_layer, str):
            self.norm1 = eval(norm_layer)(dim, epsilon=epsilon)
            self.normkv = eval(norm_layer)(dim, epsilon=epsilon)
        elif isinstance(norm_layer, Callable):
            self.norm1 = norm_layer(dim)
            self.normkv = norm_layer(dim)
        else:
            raise TypeError("The norm_layer must be str or paddle.nn.LayerNorm class")
        self.mixer = Attention(
            dim,
            num_heads=num_heads,
            qkv_bias=qkv_bias,
            qk_scale=qk_scale,
            attn_drop=attn_drop,
            proj_drop=drop,
        )

        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
        self.drop_path = DropPath(drop_path) if drop_path > 0.0 else Identity()
        if isinstance(norm_layer, str):
            self.norm2 = eval(norm_layer)(dim, epsilon=epsilon)
        elif isinstance(norm_layer, Callable):
            self.norm2 = norm_layer(dim)
        else:
            raise TypeError("The norm_layer must be str or paddle.nn.layer.Layer class")
        mlp_hidden_dim = int(dim * mlp_ratio)

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Pass the class or string: norm_layer=nn.LayerNorm or norm_layer='nn.LayerNorm' (default)
  2. Do not pass an instance or None

Example fix

# before
Block(dim, ..., norm_layer=nn.LayerNorm(dim))  # instance -> TypeError

# after
Block(dim, ..., norm_layer='nn.LayerNorm')
Defensive patterns

Strategy: type-guard

Validate before calling

assert isinstance(norm_layer, (str, Callable)), 'norm_layer must be a str or Callable class, not an instance'

Type guard

from collections.abc import Callable

def is_valid_norm_layer(n) -> bool:
    return isinstance(n, (str, Callable)) and not isinstance(n, nn.Layer)

Prevention

When it happens

Trigger: Constructing the CPPD decoder Block with norm_layer=nn.LayerNorm(dim) (instance), norm_layer=None, or a non-class object from a config.

Common situations: Adapting CPPD head code and instantiating norms eagerly, or wiring a config system that yields None for unset norm keys.

Related errors


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