{"record":{"id":"20b7850f3309e0f5","repo":"PaddlePaddle/PaddleOCR","slug":"the-norm-layer-must-be-str-or-paddle-nn-layer-laye-20b785","errorCode":null,"errorMessage":"The norm_layer must be str or paddle.nn.layer.LayerNorm class","messagePattern":"The norm_layer must be str or paddle\\.nn\\.layer\\.LayerNorm class","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ppocr/modeling/heads/rec_cppd_head.py","lineNumber":176,"sourceCode":"        mlp_ratio=4.0,\n        qkv_bias=False,\n        qk_scale=None,\n        drop=0.0,\n        attn_drop=0.0,\n        drop_path=0.0,\n        act_layer=nn.GELU,\n        norm_layer=\"nn.LayerNorm\",\n        epsilon=1e-6,\n    ):\n        super().__init__()\n        if isinstance(norm_layer, str):\n            self.norm1 = eval(norm_layer)(dim, epsilon=epsilon)\n            self.normkv = eval(norm_layer)(dim, epsilon=epsilon)\n        elif isinstance(norm_layer, Callable):\n            self.norm1 = norm_layer(dim)\n            self.normkv = norm_layer(dim)\n        else:\n            raise TypeError(\"The norm_layer must be str or paddle.nn.LayerNorm class\")\n        self.mixer = Attention(\n            dim,\n            num_heads=num_heads,\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop=attn_drop,\n            proj_drop=drop,\n        )\n\n        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here\n        self.drop_path = DropPath(drop_path) if drop_path > 0.0 else Identity()\n        if isinstance(norm_layer, str):\n            self.norm2 = eval(norm_layer)(dim, epsilon=epsilon)\n        elif isinstance(norm_layer, Callable):\n            self.norm2 = norm_layer(dim)\n        else:\n            raise TypeError(\"The norm_layer must be str or paddle.nn.layer.Layer class\")\n        mlp_hidden_dim = int(dim * mlp_ratio)","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/modeling/heads/rec_cppd_head.py#L158-L194","documentation":"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.","triggerScenarios":"Constructing the CPPD decoder Block with norm_layer=nn.LayerNorm(dim) (instance), norm_layer=None, or a non-class object from a config.","commonSituations":"Adapting CPPD head code and instantiating norms eagerly, or wiring a config system that yields None for unset norm keys.","solutions":["Pass the class or string: norm_layer=nn.LayerNorm or norm_layer='nn.LayerNorm' (default)","Do not pass an instance or None"],"exampleFix":"# before\nBlock(dim, ..., norm_layer=nn.LayerNorm(dim))  # instance -> TypeError\n\n# after\nBlock(dim, ..., norm_layer='nn.LayerNorm')","handlingStrategy":"type-guard","validationCode":"assert isinstance(norm_layer, (str, Callable)), 'norm_layer must be a str or Callable class, not an instance'","typeGuard":"from collections.abc import Callable\n\ndef is_valid_norm_layer(n) -> bool:\n    return isinstance(n, (str, Callable)) and not isinstance(n, nn.Layer)","tryCatchPattern":null,"preventionTips":["Pass 'nn.LayerNorm' (default) or nn.LayerNorm the class","Instances and None are rejected — validate before constructing the CPPD head"],"tags":["api-usage","cppd","transformer","type-error"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}