PaddlePaddle/PaddleOCR · error · TypeError
The type of 'T_max1' in 'CosineAnnealingDecay' must be 'int'
Error message
The type of 'T_max1' in 'CosineAnnealingDecay' must be 'int', but received %s.
What it means
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.
Source
Thrown at ppocr/optimizer/lr_scheduler.py:173
)
start_step = 0
for i, phase in enumerate(self._schedule_phases):
end_step = phase["end_step"]
if step_num <= end_step or i == len(self._schedule_phases) - 1:
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, intView on GitHub (pinned to 2661c7c0ef)
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.
Example fix
# before TwoStepCosineDecay(learning_rate=lr, T_max1=epochs * 0.9, T_max2=30) # float -> TypeError # after TwoStepCosineDecay(learning_rate=lr, T_max1=int(epochs * 0.9), T_max2=30)
Defensive patterns
Strategy: type-guard
Validate before calling
t_max1 = int(t_max1) # coerce before construction; raises a clear TypeError here if non-numeric
Type guard
def is_int_period(v) -> bool:
return isinstance(v, int) and not isinstance(v, bool) Prevention
- Wrap scheduler config values with int()/float() coercion in one place before building the optimizer.
- Prefer integer literals for epoch counts in YAML configs.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Expected float between 0 and 1 pct_start, but got {}
- The type of 'T_max2' 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/ac7cbffc5df00164.
Report an issue: GitHub.