PaddlePaddle/PaddleOCR · error · ValueError
anneal_strategy must by one of 'cos' or 'linear', instead go
Error message
anneal_strategy must by one of 'cos' or 'linear', instead got {} What it means
Thrown by OneCycleDecay.__init__ when anneal_strategy is not exactly 'cos' or 'linear'. The string comparison is case-sensitive with no normalization, so any other spelling, casing, or whitespace causes the ValueError before the scheduler is built.
Source
Thrown at ppocr/optimizer/lr_scheduler.py:125
"start_lr": self.initial_lr,
"end_lr": self.max_lr,
},
{
"end_step": self.total_steps - 1,
"start_lr": self.max_lr,
"end_lr": self.min_lr,
},
]
# Validate pct_start
if pct_start < 0 or pct_start > 1 or not isinstance(pct_start, float):
raise ValueError(
"Expected float between 0 and 1 pct_start, but got {}".format(pct_start)
)
# Validate anneal_strategy
if anneal_strategy not in ["cos", "linear"]:
raise ValueError(
"anneal_strategy must by one of 'cos' or 'linear', instead got {}".format(
anneal_strategy
)
)
elif anneal_strategy == "cos":
self.anneal_func = self._annealing_cos
elif anneal_strategy == "linear":
self.anneal_func = self._annealing_linear
super(OneCycleDecay, self).__init__(max_lr, last_epoch, verbose)
def _annealing_cos(self, start, end, pct):
"Cosine anneal from `start` to `end` as pct goes from 0.0 to 1.0."
cos_out = math.cos(math.pi * pct) + 1
return end + (start - end) / 2.0 * cos_out
def _annealing_linear(self, start, end, pct):
"Linearly anneal from `start` to `end` as pct goes from 0.0 to 1.0."View on GitHub (pinned to 2661c7c0ef)
Solutions
- Set anneal_strategy to the exact lowercase string 'cos' or 'linear' in the scheduler config block.
- Check for invisible whitespace/case issues if the value is generated programmatically: anneal_strategy.strip().lower().
- Consult the OneCycleDecay docstring/config template for the accepted values before editing.
Example fix
# before
Optimizer:
scheduler:
name: OneCycleDecay
anneal_strategy: cosine # rejected
# after
Optimizer:
scheduler:
name: OneCycleDecay
anneal_strategy: cos Defensive patterns
Strategy: validation
Validate before calling
ANNEAL_STRATEGIES = {"cos", "linear"}
strategy = cfg['Optimizer']['scheduler'].get('anneal_strategy', 'cos').strip().lower()
assert strategy in ANNEAL_STRATEGIES, f"anneal_strategy must be one of {ANNEAL_STRATEGIES}, got {strategy!r}" Type guard
def is_valid_anneal_strategy(v) -> bool:
return isinstance(v, str) and v.strip().lower() in {"cos", "linear"} Prevention
- Normalize enum-like config strings (strip + lower) before use.
- Copy scheduler blocks from the official PaddleOCR config templates rather than retyping.
When it happens
Trigger: Setting scheduler.anneal_strategy in the training config to anything other than the exact lowercase strings 'cos' or 'linear', e.g. 'Cos', 'cosine', 'lin', or a value with trailing whitespace.
Common situations: Copy-pasted configs from tutorials that use PyTorch/fastai vocabulary ('cosine'), typos, or uppercase values from templating. Paddle's own CosineAnnealingDecay configs often lead users to write 'cosine' here.
Related errors
- Expected float between 0 and 1 pct_start, but got {}
- Tried to step {} times. The specified number of total steps
- The type of 'T_max1' in 'CosineAnnealingDecay' must be 'int'
- The type of 'T_max2' in 'CosineAnnealingDecay' must be 'int'
- The type of 'eta_min' in 'CosineAnnealingDecay' must be 'flo
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/d51ee9ae7ce3907a.
Report an issue: GitHub.