{"record":{"id":"ac7cbffc5df00164","repo":"PaddlePaddle/PaddleOCR","slug":"the-type-of-t-max1-in-cosineannealingdecay-mus","errorCode":null,"errorMessage":"The type of 'T_max1' in 'CosineAnnealingDecay' must be 'int', but received %s.","messagePattern":"The type of 'T_max1' in 'CosineAnnealingDecay' must be 'int', but received (.+?)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ppocr/optimizer/lr_scheduler.py","lineNumber":173,"sourceCode":"            )\n        start_step = 0\n        for i, phase in enumerate(self._schedule_phases):\n            end_step = phase[\"end_step\"]\n            if step_num <= end_step or i == len(self._schedule_phases) - 1:\n                pct = (step_num - start_step) / (end_step - start_step)\n                computed_lr = self.anneal_func(phase[\"start_lr\"], phase[\"end_lr\"], pct)\n                break\n            start_step = phase[\"end_step\"]\n\n        return computed_lr\n\n\nclass TwoStepCosineDecay(LRScheduler):\n    def __init__(\n        self, learning_rate, T_max1, T_max2, eta_min=0, last_epoch=-1, verbose=False\n    ):\n        if not isinstance(T_max1, int):\n            raise TypeError(\n                \"The type of 'T_max1' in 'CosineAnnealingDecay' must be 'int', but received %s.\"\n                % type(T_max1)\n            )\n        if not isinstance(T_max2, int):\n            raise TypeError(\n                \"The type of 'T_max2' in 'CosineAnnealingDecay' must be 'int', but received %s.\"\n                % type(T_max2)\n            )\n        if not isinstance(eta_min, (float, int)):\n            raise TypeError(\n                \"The type of 'eta_min' in 'CosineAnnealingDecay' must be 'float, int', but received %s.\"\n                % type(eta_min)\n            )\n        assert T_max1 > 0 and isinstance(\n            T_max1, int\n        ), \" 'T_max1' must be a positive integer.\"\n        assert T_max2 > 0 and isinstance(\n            T_max2, int","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/optimizer/lr_scheduler.py#L155-L191","documentation":"TypeError from TwoStepCosineDecay.__init__ when T_max1 is not a Python int. The scheduler validates its period arguments strictly with isinstance(T_max1, int), so floats (even whole-valued like 300.0), strings, or numpy float scalars are rejected.","triggerScenarios":"Configuring a two-stage cosine decay schedule (e.g. for ViT/STR-style recognition training) with T_max1: 300.0 in YAML, or passing a computed float (epochs * something) or a string from a CLI into TwoStepCosineDecay.","commonSituations":"YAML configs where the value carries a decimal point; values computed with '/' in Python producing floats; JSON configs deserialized with float types; copying values from documentation that shows fractional epoch counts.","solutions":["Write T_max1 as a plain integer in the config (T_max1: 300, not 300.0).","Coerce computed values in code: TwoStepCosineDecay(lr, T_max1=int(t1), T_max2=int(t2)).","If a fractional period is genuinely needed, round to the nearest int first and document the approximation."],"exampleFix":"# before\nTwoStepCosineDecay(learning_rate=lr, T_max1=epochs * 0.9, T_max2=30)  # float -> TypeError\n\n# after\nTwoStepCosineDecay(learning_rate=lr, T_max1=int(epochs * 0.9), T_max2=30)","handlingStrategy":"type-guard","validationCode":"t_max1 = int(t_max1)  # coerce before construction; raises a clear TypeError here if non-numeric","typeGuard":"def is_int_period(v) -> bool:\n    return isinstance(v, int) and not isinstance(v, bool)","tryCatchPattern":null,"preventionTips":["Wrap scheduler config values with int()/float() coercion in one place before building the optimizer.","Prefer integer literals for epoch counts in YAML configs."],"tags":["lr-scheduler","type-validation","config","training"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}