PaddlePaddle/PaddleOCR · error · ValueError
Tried to step {} times. The specified number of total steps
Error message
Tried to step {} times. The specified number of total steps is {} What it means
Raised from OneCycleDecay.get_lr() once last_epoch exceeds the total_steps the scheduler was built with. OneCycleDecay precomputes a fixed phase schedule (warmup then decay) over total_steps, so stepping past that budget has no defined LR and is rejected at runtime, typically deep inside a training loop.
Source
Thrown at ppocr/optimizer/lr_scheduler.py:151
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."
return (end - start) * pct + start
def get_lr(self):
computed_lr = 0.0
step_num = self.last_epoch
if step_num > self.total_steps:
raise ValueError(
"Tried to step {} times. The specified number of total steps is {}".format(
step_num + 1, self.total_steps
)
)
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__(View on GitHub (pinned to 2661c7c0ef)
Solutions
- Recompute total_steps from the actual dataloader: total_steps = epochs * len(train_dataloader) per process, and rebuild the scheduler.
- If resuming/extending training, rebuild OneCycleDecay with the new larger total_steps rather than reusing the pickled scheduler.
- Verify you call scheduler.step() once per optimizer step, not per batch sub-iteration or per log interval.
Example fix
# before total_steps = epochs * steps_per_epoch # stale estimate after batch size change # after steps_per_epoch = math.ceil(n_samples / (batch_size * world_size)) total_steps = epochs * steps_per_epoch OneCycleDecay(max_lr=0.001, total_steps=total_steps, pct_start=0.1)
Defensive patterns
Strategy: validation
Validate before calling
planned_steps = epochs * math.ceil(n_samples / (batch_size * world_size))
scheduler = OneCycleDecay(max_lr=lr, total_steps=planned_steps, pct_start=0.1)
# guard inside a thin training-loop wrapper:
if scheduler.last_epoch >= scheduler.total_steps:
raise RuntimeError(f"total_steps={scheduler.total_steps} exhausted; rebuild scheduler with the new epoch budget") Try / catch
try:
lr = scheduler.get_lr()
except ValueError:
# budget exhausted: rebuild the schedule for the new horizon and continue
scheduler = rebuild_one_cycle(total_steps=new_total_steps)
lr = scheduler.get_lr() Prevention
- Derive total_steps from len(train_dataloader) at runtime instead of hardcoding.
- When extending or resuming training, construct a fresh scheduler with the updated total_steps.
- Step the scheduler exactly once per optimizer step.
When it happens
Trigger: The scheduler's total_steps is smaller than the actual number of optimizer steps taken: epochs/steps_per_epoch miscounted in config, resuming a checkpoint and continuing to train past the planned budget, or stepping the LR scheduler more often than the optimizer.
Common situations: Config computes total_steps = epochs * steps_per_epoch but the dataloader length or world size changed (more GPUs, smaller batch), so real steps exceed the estimate; fine-tuning jobs extended beyond the original epoch count without regenerating total_steps.
Related errors
- Expected float between 0 and 1 pct_start, but got {}
- anneal_strategy must by one of 'cos' or 'linear', instead go
- 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/6dfdc272bc46518a.
Report an issue: GitHub.