PaddlePaddle/PaddleOCR · error · TypeError

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

Error message

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

What it means

Block in rec_vit_parseq accepts norm_layer either as a string (evaluated into a Paddle class, e.g. the default 'nn.LayerNorm') or a Callable (a layer class/lambda taking dim). The first check builds self.norm1; anything that is neither str nor Callable raises TypeError('The norm_layer must be str or paddle.nn.layer.Layer class').

Source

Thrown at ppocr/modeling/backbones/rec_vit_parseq.py:159

        dim,
        num_heads,
        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-5,
    ):
        super().__init__()
        if isinstance(norm_layer, str):
            self.norm1 = eval(norm_layer)(dim, epsilon=epsilon)
        elif isinstance(norm_layer, Callable):
            self.norm1 = norm_layer(dim)
        else:
            raise TypeError("The norm_layer must be str or paddle.nn.layer.Layer class")
        self.attn = 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)
        self.mlp = Mlp(

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Pass the class or its string: norm_layer=nn.LayerNorm or keep the default norm_layer='nn.LayerNorm'
  2. Do not pass an instance (no parentheses) and do not pass None

Example fix

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

# after
Block(dim, ..., norm_layer=nn.LayerNorm)        # class
Block(dim, ..., norm_layer='nn.LayerNorm')      # default string form
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: Passing norm_layer as an instance instead of a class (nn.LayerNorm(dim) rather than nn.LayerNorm), as None, or as some other object when constructing PARSeq ViT blocks.

Common situations: Config-driven construction where norm_layer is loaded as None for 'no norm'; passing a partial/instance because a different API expected an instantiated layer; typo like norm_layer='nn.Layernorm'.

Related errors


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