PaddlePaddle/PaddleOCR · error · TypeError
The type of 'T_max2' in 'CosineAnnealingDecay' must be 'int'
Error message
The type of 'T_max2' in 'CosineAnnealingDecay' must be 'int', but received %s.
What it means
TypeError from TwoStepCosineDecay.__init__ when T_max2 (the second cosine period) is not a Python int. Same strict isinstance check as T_max1: floats, strings, and non-int numerics are rejected before the scheduler stores the value.
Source
Thrown at ppocr/optimizer/lr_scheduler.py:178
pct = (step_num - start_step) / (end_step - start_step)
computed_lr = self.anneal_func(phase["start_lr"], phase["end_lr"], pct)
break
start_step = phase["end_step"]
return computed_lr
class TwoStepCosineDecay(LRScheduler):
def __init__(
self, learning_rate, T_max1, T_max2, eta_min=0, last_epoch=-1, verbose=False
):
if not isinstance(T_max1, int):
raise TypeError(
"The type of 'T_max1' in 'CosineAnnealingDecay' must be 'int', but received %s."
% type(T_max1)
)
if not isinstance(T_max2, int):
raise TypeError(
"The type of 'T_max2' in 'CosineAnnealingDecay' must be 'int', but received %s."
% type(T_max2)
)
if not isinstance(eta_min, (float, int)):
raise TypeError(
"The type of 'eta_min' in 'CosineAnnealingDecay' must be 'float, int', but received %s."
% type(eta_min)
)
assert T_max1 > 0 and isinstance(
T_max1, int
), " 'T_max1' must be a positive integer."
assert T_max2 > 0 and isinstance(
T_max2, int
), " 'T_max1' must be a positive integer."
self.T_max1 = T_max1
self.T_max2 = T_max2
self.eta_min = float(eta_min)
super(TwoStepCosineDecay, self).__init__(learning_rate, last_epoch, verbose)View on GitHub (pinned to 2661c7c0ef)
Solutions
- Set T_max2 as an integer literal in the config file.
- Coerce in code: T_max2=int(total_epochs - warm_epochs).
- Double-check both T_max1 and T_max2 together, since each is validated independently.
Example fix
# before TwoStepCosineDecay(learning_rate=lr, T_max1=270, T_max2=total_epochs - 270) # float result # after TwoStepCosineDecay(learning_rate=lr, T_max1=270, T_max2=int(total_epochs - 270))
Defensive patterns
Strategy: type-guard
Validate before calling
t_max2 = int(t_max2) # coerce computed second-period values before construction
Type guard
def is_int_period(v) -> bool:
return isinstance(v, int) and not isinstance(v, bool) Prevention
- Apply int() to any arithmetic result passed as T_max1/T_max2.
- Validate both periods together in a config pre-check helper.
When it happens
Trigger: Building TwoStepCosineDecay with T_max2: 50.0 from config, a float computed at runtime, or a string argument; T_max1 passes validation but T_max2 does not.
Common situations: Asymmetric decay configs where T_max2 is derived by subtraction/division of epoch counts; YAML values with decimals; mixed configs where one period was fixed to int and the other left as a computed float.
Related errors
- Expected float between 0 and 1 pct_start, but got {}
- The type of 'T_max1' in 'CosineAnnealingDecay' must be 'int'
- The type of 'eta_min' in 'CosineAnnealingDecay' must be 'flo
- anneal_strategy must by one of 'cos' or 'linear', instead go
- Tried to step {} times. The specified number of total steps
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/176430078ed9a5c8.
Report an issue: GitHub.