PaddlePaddle/PaddleOCR · error · ValueError
Expected float between 0 and 1 pct_start, but got {}
Error message
Expected float between 0 and 1 pct_start, but got {} What it means
Thrown by OneCycleDecay.__init__ in PaddleOCR's LR scheduler when the pct_start argument fails validation. The guard requires pct_start to be a Python float AND strictly within [0, 1]. Because the isinstance(pct_start, float) check is part of the same condition, even an in-range int (0 or 1) is rejected, as are strings like '0.2' that some config loaders deliver.
Source
Thrown at ppocr/optimizer/lr_scheduler.py:119
},
]
else:
self._schedule_phases = [
{
"end_step": float(pct_start * self.total_steps) - 1,
"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):View on GitHub (pinned to 2661c7c0ef)
Solutions
- Pass pct_start as an explicit float literal, e.g. pct_start=0.1 or pct_start=1.0 for the boundary values.
- If the value comes from a config file, unquote it (pct_start: 0.1, not pct_start: '0.1') so YAML parses it as a float.
- If it may be computed dynamically, coerce before constructing: pct_start = float(pct_start).
Example fix
# before OneCycleDecay(max_lr=0.001, total_steps=10000, pct_start=1) # int -> ValueError # after OneCycleDecay(max_lr=0.001, total_steps=10000, pct_start=1.0) # float literal
Defensive patterns
Strategy: type-guard
Validate before calling
def valid_pct_start(v) -> float:
v = float(v) # raises early with a clear message if non-numeric
if not (0.0 <= v <= 1.0):
raise ValueError(f"pct_start must be within [0,1], got {v}")
return v
pct = valid_pct_start(cfg['Optimizer']['scheduler'].get('pct_start', 0.1)) Type guard
def is_valid_pct_start(v) -> bool:
return isinstance(v, float) and 0.0 <= v <= 1.0 Prevention
- Normalize numeric config values with float() before passing them to scheduler constructors.
- Keep a config schema check at startup that validates scheduler kwargs before training begins.
- Write pct_start as an unquoted decimal literal in YAML so it parses as float.
When it happens
Trigger: Constructing OneCycleDecay (directly or via a training config with scheduler.name: OneCycleDecay) with pct_start that is out of range, an int (e.g. pct_start=1), or a non-numeric type such as a string loaded from a config file.
Common situations: YAML/JSON config where pct_start is quoted ('0.3') so it arrives as a string; passing whole-number boundaries 0 or 1 as int; hand-written training scripts passing div results or ints from argparse (argparse type=int).
Related errors
- 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
- 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/3b0e4a420cc9936e.
Report an issue: GitHub.