I recently stumbled on this issue… I don’t know if this is “best practice”, but my solution was to subtract the current epoch / starting_epoch (which is saved along with the model and optimizer, or 0 when starting from scratch) to the milestones (if the milestones are expressed in epochs), e.g:
milestones = [epoch - starting_epoch for epoch in milestones]
scheduler = lr_scheduler.MultiStepLR(optim, milestones, gamma=0.1)

I guess the scheduler goes through all the milestones, even negative ones, and in the case that the current_epoch is larger than the milestone, the learning rate is multiplied by gamma. (I was a bit surprised by this!)
This should also work (untested), but is probably less efficient:
for _ in range(current_epoch):
    scheduler.step()

This might save a bit of space in the checkpoint file…