PaddlePaddle/PaddleOCR · error · ValueError
Expected positive integer steps_per_epoch, but got {}
Error message
Expected positive integer steps_per_epoch, but got {} What it means
Companion check to error 318: the scheduler needs steps_per_epoch (iterations per epoch) as a positive integer because total_steps = epochs * steps_per_epoch drives the LR curve. A zero, negative, non-int, or missing value raises this ValueError before any training step runs.
Source
Thrown at ppocr/optimizer/lr_scheduler.py:74
self,
max_lr,
epochs=None,
steps_per_epoch=None,
pct_start=0.3,
anneal_strategy="cos",
div_factor=25.0,
final_div_factor=1e4,
three_phase=False,
last_epoch=-1,
verbose=False,
):
# Validate total_steps
if epochs <= 0 or not isinstance(epochs, int):
raise ValueError(
"Expected positive integer epochs, but got {}".format(epochs)
)
if steps_per_epoch <= 0 or not isinstance(steps_per_epoch, int):
raise ValueError(
"Expected positive integer steps_per_epoch, but got {}".format(
steps_per_epoch
)
)
self.total_steps = epochs * steps_per_epoch
self.max_lr = max_lr
self.initial_lr = self.max_lr / div_factor
self.min_lr = self.initial_lr / final_div_factor
if three_phase:
self._schedule_phases = [
{
"end_step": float(pct_start * self.total_steps) - 1,
"start_lr": self.initial_lr,
"end_lr": self.max_lr,
},
{View on GitHub (pinned to 2661c7c0ef)
Solutions
- Pass a positive int steps_per_epoch, typically math.ceil(num_samples / batch_size)
- Guard: steps_per_epoch = max(1, math.ceil(num_samples / batch_size))
- Check the scheduler config key name expected by PaddleOCR's optimizer builder
Example fix
# before steps_per_epoch = num_samples / batch_size # 0.0 for tiny debug set # after import math steps_per_epoch = max(1, math.ceil(num_samples / batch_size))
Defensive patterns
Strategy: validation
Validate before calling
import math steps_per_epoch = max(1, math.ceil(num_samples / batch_size)) assert isinstance(steps_per_epoch, int) and steps_per_epoch > 0
Type guard
def valid_steps(s) -> bool:
return isinstance(s, int) and not isinstance(s, bool) and s > 0 Prevention
- Compute steps with ceil division, never plain /
- Clamp to >=1 for tiny debug datasets so smoke tests still run
When it happens
Trigger: Calling the scheduler with steps_per_epoch=0 (e.g. num_samples//batch_size with batch > num_samples), a float, or None passed positionally.
Common situations: Tiny debug datasets where batch size exceeds sample count; computing steps as float division; config keys named differently (iters_per_epoch) so the parameter never gets set.
Related errors
- Expected positive integer epochs, but got {}
- Asset "${assetName}" must be an object.
- Please set inference model dir in Global.inference_model or
- "out_size" must be an integer or tuple of integers
- Sliding window is currently only implemented for causal mask
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/c1c528ae33d45659.
Report an issue: GitHub.